summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/conf/NOTES5
-rw-r--r--sys/conf/files.i3866
-rw-r--r--sys/conf/options.i3864
-rw-r--r--sys/dev/kbd/kbdtables.h10
-rw-r--r--sys/dev/syscons/blank/blank_saver.c10
-rw-r--r--sys/dev/syscons/daemon/daemon_saver.c6
-rw-r--r--sys/dev/syscons/fade/fade_saver.c12
-rw-r--r--sys/dev/syscons/green/green_saver.c10
-rw-r--r--sys/dev/syscons/scvesactl.c150
-rw-r--r--sys/dev/syscons/scvidctl.c486
-rw-r--r--sys/dev/syscons/snake/snake_saver.c14
-rw-r--r--sys/dev/syscons/star/star_saver.c14
-rw-r--r--sys/dev/syscons/syscons.c1819
-rw-r--r--sys/dev/syscons/syscons.h92
-rw-r--r--sys/i386/conf/LINT5
-rw-r--r--sys/i386/conf/NOTES5
-rw-r--r--sys/i386/conf/files.i3866
-rw-r--r--sys/i386/conf/options.i3864
-rw-r--r--sys/i386/include/console.h127
-rw-r--r--sys/i386/include/pc/vesa.h127
-rw-r--r--sys/i386/isa/kbdtables.h10
-rw-r--r--sys/i386/isa/pcaudio.c10
-rw-r--r--sys/i386/isa/scvesactl.c150
-rw-r--r--sys/i386/isa/scvidctl.c486
-rw-r--r--sys/i386/isa/syscons.c1819
-rw-r--r--sys/i386/isa/syscons.h92
-rw-r--r--sys/i386/isa/vesa.c868
-rw-r--r--sys/i386/isa/videoio.c1612
-rw-r--r--sys/i386/isa/videoio.h107
-rw-r--r--sys/i386/isa/wst.c8
-rw-r--r--sys/modules/syscons/blank/blank_saver.c10
-rw-r--r--sys/modules/syscons/daemon/daemon_saver.c6
-rw-r--r--sys/modules/syscons/fade/fade_saver.c12
-rw-r--r--sys/modules/syscons/green/green_saver.c10
-rw-r--r--sys/modules/syscons/saver.h12
-rw-r--r--sys/modules/syscons/snake/snake_saver.c14
-rw-r--r--sys/modules/syscons/star/star_saver.c14
-rw-r--r--sys/pc98/pc98/wst.c8
38 files changed, 5339 insertions, 2821 deletions
diff --git a/sys/conf/NOTES b/sys/conf/NOTES
index 2d8c4a8..8b20f86 100644
--- a/sys/conf/NOTES
+++ b/sys/conf/NOTES
@@ -2,7 +2,7 @@
# LINT -- config file for checking all the sources, tries to pull in
# as much of the source tree as it can.
#
-# $Id: LINT,v 1.464 1998/09/15 10:01:13 gibbs Exp $
+# $Id: LINT,v 1.465 1998/09/15 11:44:43 phk Exp $
#
# NB: You probably don't want to try running a kernel built from this
# file. Instead, you should start from GENERIC, and add options from
@@ -803,6 +803,9 @@ options SC_HISTORY_SIZE=200 # number of history buffer lines
options SC_DISABLE_REBOOT # disable reboot key sequence
# If the screen flickers badly when the mouse pointer is moved, try this.
options SC_BAD_FLICKER
+# To include support for VESA video modes
+# Dont use together with SMP!!
+options VESA # needs VM86 defined too!!
#
# `flags' for sc0:
diff --git a/sys/conf/files.i386 b/sys/conf/files.i386
index 5302df4..6a08470 100644
--- a/sys/conf/files.i386
+++ b/sys/conf/files.i386
@@ -1,7 +1,7 @@
# This file tells config what files go into building a kernel,
# files marked standard are always included.
#
-# $Id: files.i386,v 1.202 1998/09/08 20:57:46 sos Exp $
+# $Id: files.i386,v 1.203 1998/09/15 10:01:13 gibbs Exp $
#
# The long compile-with and dependency lines are required because of
# limitations in config: backslash-newline doesn't work in strings, and
@@ -240,6 +240,10 @@ i386/isa/spigot.c optional spigot device-driver
i386/isa/spkr.c optional speaker device-driver
i386/isa/stallion.c optional stl device-driver
i386/isa/syscons.c optional sc device-driver
+i386/isa/scvidctl.c optional sc device-driver
+i386/isa/scvesactl.c optional sc device-driver
+i386/isa/videoio.c optional sc device-driver
+i386/isa/vesa.c optional sc device-driver
i386/isa/tw.c optional tw device-driver
#i386/isa/ultra14f.c optional uha device-driver
i386/isa/wd.c optional wdc device-driver
diff --git a/sys/conf/options.i386 b/sys/conf/options.i386
index c07d086..21c4598 100644
--- a/sys/conf/options.i386
+++ b/sys/conf/options.i386
@@ -1,4 +1,4 @@
-# $Id: options.i386,v 1.85 1998/09/08 18:09:50 brian Exp $
+# $Id: options.i386,v 1.86 1998/09/15 10:01:14 gibbs Exp $
BOUNCEPAGES opt_bounce.h
DISABLE_PSE
@@ -77,6 +77,8 @@ SC_DISABLE_REBOOT opt_syscons.h
SC_MOUSE_CHAR opt_syscons.h
SC_BAD_FLICKER opt_syscons.h
+VESA opt_vesa.h
+
PSM_HOOKAPM opt_psm.h
PSM_RESETAFTERSUSPEND opt_psm.h
PSM_DEBUG opt_psm.h
diff --git a/sys/dev/kbd/kbdtables.h b/sys/dev/kbd/kbdtables.h
index d36b39a..61376f4 100644
--- a/sys/dev/kbd/kbdtables.h
+++ b/sys/dev/kbd/kbdtables.h
@@ -1,18 +1,18 @@
/*-
- * Copyright (c) 1992-1995 Søren Schmidt
+ * Copyright (c) 1992-1998 Søren Schmidt
* 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
- * in this position and unchanged.
+ * notice, this list of conditions and the following disclaimer,
+ * without modification, immediately at the beginning of the file.
* 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. The name of the author may not be used to endorse or promote products
- * derived from this software withough specific prior written permission
+ * derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: kbdtables.h,v 1.39 1998/01/28 08:45:18 yokota Exp $
+ * $Id$
*/
#define SET8 0x80 /* set eight bit on */
diff --git a/sys/dev/syscons/blank/blank_saver.c b/sys/dev/syscons/blank/blank_saver.c
index 451dc9a..d5f4cf0 100644
--- a/sys/dev/syscons/blank/blank_saver.c
+++ b/sys/dev/syscons/blank/blank_saver.c
@@ -1,18 +1,18 @@
/*-
- * Copyright (c) 1995 Søren Schmidt
+ * Copyright (c) 1995-1998 Søren Schmidt
* 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
- * in this position and unchanged.
+ * notice, this list of conditions and the following disclaimer,
+ * without modification, immediately at the beginning of the file.
* 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. The name of the author may not be used to endorse or promote products
- * derived from this software withough specific prior written permission
+ * derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: blank_saver.c,v 1.10 1997/07/15 14:49:09 yokota Exp $
+ * $Id$
*/
#include <sys/param.h>
diff --git a/sys/dev/syscons/daemon/daemon_saver.c b/sys/dev/syscons/daemon/daemon_saver.c
index f3cf3dc..688df41 100644
--- a/sys/dev/syscons/daemon/daemon_saver.c
+++ b/sys/dev/syscons/daemon/daemon_saver.c
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: daemon_saver.c,v 1.8 1998/01/16 17:58:43 bde Exp $
+ * $Id: daemon_saver.c,v 1.9 1998/08/06 09:14:20 yokota Exp $
*/
#include <sys/param.h>
@@ -205,7 +205,7 @@ daemon_saver(int blank)
/* clear the screen and set the border color */
fillw(((FG_LIGHTGREY|BG_BLACK) << 8) | scr_map[0x20],
Crtat, scp->xsize * scp->ysize);
- set_border(0);
+ set_border(scp, 0);
xlen = ylen = tlen = 0;
}
if (scrn_blanked++ < 2)
@@ -322,7 +322,7 @@ daemon_saver(int blank)
draw_string(txpos, typos, toff, (char *)message, tlen);
} else {
if (scrn_blanked > 0) {
- set_border(scp->border);
+ set_border(scp, scp->border);
scrn_blanked = 0;
}
}
diff --git a/sys/dev/syscons/fade/fade_saver.c b/sys/dev/syscons/fade/fade_saver.c
index 341f7e8..41176e7 100644
--- a/sys/dev/syscons/fade/fade_saver.c
+++ b/sys/dev/syscons/fade/fade_saver.c
@@ -1,18 +1,18 @@
/*-
- * Copyright (c) 1995-1997 Søren Schmidt
+ * Copyright (c) 1995-1998 Søren Schmidt
* 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
- * in this position and unchanged.
+ * notice, this list of conditions and the following disclaimer,
+ * without modification, immediately at the beginning of the file.
* 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. The name of the author may not be used to endorse or promote products
- * derived from this software withough specific prior written permission
+ * derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: fade_saver.c,v 1.11 1997/07/15 14:49:25 yokota Exp $
+ * $Id$
*/
#include <sys/param.h>
@@ -84,7 +84,7 @@ fade_saver(int blank)
else {
switch (crtc_type) {
case KD_VGA:
- load_palette(palette);
+ load_palette(cur_console, palette);
count = 0;
break;
case KD_EGA:
diff --git a/sys/dev/syscons/green/green_saver.c b/sys/dev/syscons/green/green_saver.c
index b8c8295..6678662 100644
--- a/sys/dev/syscons/green/green_saver.c
+++ b/sys/dev/syscons/green/green_saver.c
@@ -1,18 +1,18 @@
/*-
- * Copyright (c) 1995 Søren Schmidt
+ * Copyright (c) 1995-1998 Søren Schmidt
* 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
- * in this position and unchanged.
+ * notice, this list of conditions and the following disclaimer,
+ * without modification, immediately at the beginning of the file.
* 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. The name of the author may not be used to endorse or promote products
- * derived from this software withough specific prior written permission
+ * derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: green_saver.c,v 1.10 1997/07/15 14:49:29 yokota Exp $
+ * $Id$
*/
#include <sys/param.h>
diff --git a/sys/dev/syscons/scvesactl.c b/sys/dev/syscons/scvesactl.c
new file mode 100644
index 0000000..9678177
--- /dev/null
+++ b/sys/dev/syscons/scvesactl.c
@@ -0,0 +1,150 @@
+/*-
+ * Copyright (c) 1998 Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp)
+ * 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. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#include "sc.h"
+#include "opt_vesa.h"
+#include "opt_vm86.h"
+
+#if (NSC > 0 && defined(VESA) && defined(VM86)) || defined(VESA_MODULE)
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/tty.h>
+#include <sys/kernel.h>
+
+#include <machine/apm_bios.h>
+#include <machine/console.h>
+#include <machine/pc/vesa.h>
+
+#include <i386/isa/videoio.h>
+#include <i386/isa/syscons.h>
+
+static int (*prev_user_ioctl)(dev_t dev, int cmd, caddr_t data, int flag,
+ struct proc *p);
+
+extern struct tty *scdevtotty(dev_t dev);
+
+int
+vesa_ioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
+{
+ scr_stat *scp;
+ struct tty *tp;
+ video_info_t info;
+ video_adapter_t *adp;
+ int mode;
+ int error;
+ int s;
+
+ tp = scdevtotty(dev);
+ if (!tp)
+ return ENXIO;
+ scp = sc_get_scr_stat(tp->t_dev);
+
+ switch (cmd) {
+ case SW_VESA_USER:
+
+ mode = (int)data;
+ if ((*biosvidsw.get_info)(scp->adp, mode, &info))
+ return ENODEV;
+ if (info.vi_flags & V_INFO_GRAPHICS)
+ goto vesa_graphics;
+ else
+ goto vesa_text;
+
+ /* text modes */
+ case SW_VESA_C80x60:
+ case SW_VESA_C132x25:
+ case SW_VESA_C132x43:
+ case SW_VESA_C132x50:
+ case SW_VESA_C132x60:
+ adp = get_adapter(scp);
+ if (!(adp->va_flags & V_ADP_MODECHANGE))
+ return ENODEV;
+ mode = (cmd & 0xff) + M_VESA_BASE;
+vesa_text:
+ return sc_set_text_mode(scp, tp, mode, 0, 0, 0);
+
+ /* graphics modes */
+ case SW_VESA_32K_320: case SW_VESA_64K_320:
+ case SW_VESA_FULL_320:
+
+ case SW_VESA_CG640x400:
+
+ case SW_VESA_CG640x480:
+ case SW_VESA_32K_640: case SW_VESA_64K_640:
+ case SW_VESA_FULL_640:
+
+ case SW_VESA_800x600: case SW_VESA_CG800x600:
+ case SW_VESA_32K_800: case SW_VESA_64K_800:
+ case SW_VESA_FULL_800:
+
+ case SW_VESA_1024x768: case SW_VESA_CG1024x768:
+ case SW_VESA_32K_1024: case SW_VESA_64K_1024:
+ case SW_VESA_FULL_1024:
+
+ case SW_VESA_1280x1024: case SW_VESA_CG1280x1024:
+ case SW_VESA_32K_1280: case SW_VESA_64K_1280:
+ case SW_VESA_FULL_1280:
+ adp = get_adapter(scp);
+ if (!(adp->va_flags & V_ADP_MODECHANGE))
+ return ENODEV;
+ mode = (cmd & 0xff) + M_VESA_BASE;
+vesa_graphics:
+ return sc_set_graphics_mode(scp, tp, mode);
+ }
+
+ if (prev_user_ioctl)
+ return (*prev_user_ioctl)(dev, cmd, data, flag, p);
+ else
+ return ENOIOCTL;
+}
+
+int
+vesa_load_ioctl(void)
+{
+ if (prev_user_ioctl)
+ return EBUSY;
+ prev_user_ioctl = sc_user_ioctl;
+ sc_user_ioctl = vesa_ioctl;
+ return 0;
+}
+
+int
+vesa_unload_ioctl(void)
+{
+ if (sc_user_ioctl != vesa_ioctl)
+ return EBUSY;
+ sc_user_ioctl = prev_user_ioctl;
+ prev_user_ioctl = NULL;
+ return 0;
+}
+
+#endif /* (NSC > 0 && VESA && VM86) || VESA_MODULE */
diff --git a/sys/dev/syscons/scvidctl.c b/sys/dev/syscons/scvidctl.c
new file mode 100644
index 0000000..464933e
--- /dev/null
+++ b/sys/dev/syscons/scvidctl.c
@@ -0,0 +1,486 @@
+/*-
+ * Copyright (c) 1998 Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp)
+ * 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. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#include "sc.h"
+#include "opt_syscons.h"
+
+#if NSC > 0
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/signalvar.h>
+#include <sys/tty.h>
+#include <sys/kernel.h>
+
+#include <machine/apm_bios.h>
+#include <machine/console.h>
+
+#include <i386/isa/videoio.h>
+#include <i386/isa/syscons.h>
+
+/* video ioctl */
+
+extern scr_stat *cur_console;
+extern u_short *Crtat;
+extern int fonts_loaded;
+extern int sc_history_size;
+extern u_char palette[];
+
+int
+sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, int xsize, int ysize,
+ int fontsize)
+{
+ video_adapter_t *adp;
+ video_info_t info;
+ int error;
+ int s;
+ int i;
+
+ if ((*biosvidsw.get_info)(scp->adp, mode, &info))
+ return ENODEV;
+ adp = get_adapter(scp);
+
+ /* adjust argument values */
+ if (fontsize <= 0)
+ fontsize = info.vi_cheight;
+ if (fontsize < 14) {
+ fontsize = 8;
+ if (!(fonts_loaded & FONT_8))
+ return EINVAL;
+ } else if (fontsize >= 16) {
+ fontsize = 16;
+ if (!(fonts_loaded & FONT_16))
+ return EINVAL;
+ } else {
+ fontsize = 14;
+ if (!(fonts_loaded & FONT_14))
+ return EINVAL;
+ }
+ if ((xsize <= 0) || (xsize > info.vi_width))
+ xsize = info.vi_width;
+ if ((ysize <= 0) || (ysize > info.vi_height))
+ ysize = info.vi_height;
+
+ /* stop screen saver, etc */
+ s = spltty();
+ if ((error = sc_clean_up(scp))) {
+ splx(s);
+ return error;
+ }
+
+ /* set up scp */
+ if (scp->history != NULL)
+ i = imax(scp->history_size / scp->xsize
+ - imax(sc_history_size, scp->ysize), 0);
+ else
+ i = 0;
+ /*
+ * This is a kludge to fend off scrn_update() while we
+ * muck around with scp. XXX
+ */
+ scp->status |= UNKNOWN_MODE;
+ scp->status &= ~(GRAPHICS_MODE | PIXEL_MODE);
+ scp->mode = mode;
+ scp->font_size = fontsize;
+ scp->xsize = xsize;
+ scp->ysize = ysize;
+ scp->xpixel = scp->xsize*8;
+ scp->ypixel = scp->ysize*fontsize;
+
+ /* allocate buffers */
+ sc_alloc_scr_buffer(scp, TRUE, TRUE);
+ if (ISMOUSEAVAIL(adp->va_flags))
+ sc_alloc_cut_buffer(scp, FALSE);
+ sc_alloc_history_buffer(scp, sc_history_size, i, FALSE);
+ splx(s);
+
+ if (scp == cur_console)
+ set_mode(scp);
+ scp->status &= ~UNKNOWN_MODE;
+
+ if (tp == NULL)
+ return 0;
+ if (tp->t_winsize.ws_col != scp->xsize
+ || tp->t_winsize.ws_row != scp->ysize) {
+ tp->t_winsize.ws_col = scp->xsize;
+ tp->t_winsize.ws_row = scp->ysize;
+ pgsignal(tp->t_pgrp, SIGWINCH, 1);
+ }
+
+ return 0;
+}
+
+int
+sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode)
+{
+ video_adapter_t *adp;
+ video_info_t info;
+ int error;
+ int s;
+
+ if ((*biosvidsw.get_info)(scp->adp, mode, &info))
+ return ENODEV;
+ adp = get_adapter(scp);
+
+ /* stop screen saver, etc */
+ s = spltty();
+ if ((error = sc_clean_up(scp))) {
+ splx(s);
+ return error;
+ }
+
+ /* set up scp */
+ scp->status |= (UNKNOWN_MODE | GRAPHICS_MODE);
+ scp->status &= ~PIXEL_MODE;
+ scp->mode = mode;
+ scp->xpixel = info.vi_width;
+ scp->ypixel = info.vi_height;
+ scp->xsize = info.vi_width/8;
+ scp->ysize = info.vi_height/info.vi_cheight;
+ scp->font_size = FONT_NONE;
+ /* move the mouse cursor at the center of the screen */
+ sc_move_mouse(scp, scp->xpixel / 2, scp->ypixel / 2);
+ splx(s);
+
+ if (scp == cur_console)
+ set_mode(scp);
+ /* clear_graphics();*/
+ scp->status &= ~UNKNOWN_MODE;
+
+ if (tp == NULL)
+ return 0;
+ if (tp->t_winsize.ws_xpixel != scp->xpixel
+ || tp->t_winsize.ws_ypixel != scp->ypixel) {
+ tp->t_winsize.ws_xpixel = scp->xpixel;
+ tp->t_winsize.ws_ypixel = scp->ypixel;
+ pgsignal(tp->t_pgrp, SIGWINCH, 1);
+ }
+
+ return 0;
+}
+
+int
+sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize,
+ int fontsize)
+{
+ video_adapter_t *adp;
+ video_info_t info;
+ int error;
+ int s;
+ int i;
+
+ if ((*biosvidsw.get_info)(scp->adp, scp->mode, &info))
+ return ENODEV; /* this shouldn't happen */
+ adp = get_adapter(scp);
+
+#ifdef SC_VIDEO_DEBUG
+ if (scp->scr_buf != NULL) {
+ printf("set_pixel_mode(): mode:%x, col:%d, row:%d, font:%d\n",
+ scp->mode, xsize, ysize, fontsize);
+ }
+#endif
+
+ /* adjust argument values */
+ if ((fontsize <= 0) || (fontsize == FONT_NONE))
+ fontsize = info.vi_cheight;
+ if (fontsize < 14) {
+ fontsize = 8;
+ if (!(fonts_loaded & FONT_8))
+ return EINVAL;
+ } else if (fontsize >= 16) {
+ fontsize = 16;
+ if (!(fonts_loaded & FONT_16))
+ return EINVAL;
+ } else {
+ fontsize = 14;
+ if (!(fonts_loaded & FONT_14))
+ return EINVAL;
+ }
+ if (xsize <= 0)
+ xsize = info.vi_width/8;
+ if (ysize <= 0)
+ ysize = info.vi_height/fontsize;
+
+#ifdef SC_VIDEO_DEBUG
+ if (scp->scr_buf != NULL) {
+ printf("set_pixel_mode(): mode:%x, col:%d, row:%d, font:%d\n",
+ scp->mode, xsize, ysize, fontsize);
+ printf("set_pixel_mode(): Crtat:%x, %dx%d, xoff:%d, yoff:%d\n",
+ Crtat, info.vi_width, info.vi_height,
+ (info.vi_width/8 - xsize)/2,
+ (info.vi_height/fontsize - ysize)/2);
+ }
+#endif
+
+ /* stop screen saver, etc */
+ s = spltty();
+ if ((error = sc_clean_up(scp))) {
+ splx(s);
+ return error;
+ }
+
+ /* set up scp */
+ if (scp->history != NULL)
+ i = imax(scp->history_size / scp->xsize
+ - imax(sc_history_size, scp->ysize), 0);
+ else
+ i = 0;
+ scp->status |= (UNKNOWN_MODE | PIXEL_MODE);
+ scp->status &= ~(GRAPHICS_MODE | MOUSE_ENABLED);
+ scp->xsize = xsize;
+ scp->ysize = ysize;
+ scp->font_size = fontsize;
+ scp->xoff = (scp->xpixel/8 - xsize)/2;
+ scp->yoff = (scp->ypixel/fontsize - ysize)/2;
+
+ /* allocate buffers */
+ sc_alloc_scr_buffer(scp, TRUE, TRUE);
+ if (ISMOUSEAVAIL(adp->va_flags))
+ sc_alloc_cut_buffer(scp, FALSE);
+ sc_alloc_history_buffer(scp, sc_history_size, i, FALSE);
+ splx(s);
+
+ /* FIXME */
+ if (scp == cur_console)
+ bzero(Crtat, scp->xpixel*scp->ypixel/8);
+
+ scp->status &= ~UNKNOWN_MODE;
+
+#ifdef SC_VIDEO_DEBUG
+ printf("set_pixel_mode(): status:%x\n", scp->status);
+#endif
+
+ if (tp == NULL)
+ return 0;
+ if (tp->t_winsize.ws_col != scp->xsize
+ || tp->t_winsize.ws_row != scp->ysize) {
+ tp->t_winsize.ws_col = scp->xsize;
+ tp->t_winsize.ws_row = scp->ysize;
+ pgsignal(tp->t_pgrp, SIGWINCH, 1);
+ }
+
+ return 0;
+}
+
+int
+sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p)
+{
+ scr_stat *scp;
+ video_adapter_t *adp;
+ int error;
+ int s;
+
+ scp = sc_get_scr_stat(tp->t_dev);
+
+ switch (cmd) {
+
+ case CONS_CURRENT: /* get current adapter type */
+ adp = get_adapter(scp);
+ *(int *)data = adp->va_type;
+ return 0;
+
+ case CONS_CURRENTADP: /* get current adapter index */
+ *(int *)data = scp->adp;
+ return 0;
+
+ case CONS_ADPINFO: /* adapter information */
+ adp = (*biosvidsw.adapter)(((video_adapter_t *)data)->va_index);
+ if (adp == NULL)
+ return ENODEV;
+ bcopy(adp, data, sizeof(*adp));
+ return 0;
+
+ case CONS_GET: /* get current video mode */
+ *(int *)data = scp->mode;
+ return 0;
+
+ case CONS_MODEINFO: /* get mode information */
+ return ((*biosvidsw.get_info)(scp->adp,
+ ((video_info_t *)data)->vi_mode, (video_info_t *)data)
+ ? ENODEV : 0);
+
+ case CONS_FINDMODE: /* find a matching video mode */
+ return ((*biosvidsw.query_mode)(scp->adp, (video_info_t *)data)
+ ? ENODEV : 0);
+
+ case CONS_SETWINORG:
+ return ((*biosvidsw.set_win_org)(scp->adp, *(u_int *)data)
+ ? ENODEV : 0);
+
+ /* VGA TEXT MODES */
+ case SW_VGA_C40x25:
+ case SW_VGA_C80x25: case SW_VGA_M80x25:
+ case SW_VGA_C80x30: case SW_VGA_M80x30:
+ case SW_VGA_C80x50: case SW_VGA_M80x50:
+ case SW_VGA_C80x60: case SW_VGA_M80x60:
+ case SW_B40x25: case SW_C40x25:
+ case SW_B80x25: case SW_C80x25:
+ case SW_ENH_B40x25: case SW_ENH_C40x25:
+ case SW_ENH_B80x25: case SW_ENH_C80x25:
+ case SW_ENH_B80x43: case SW_ENH_C80x43:
+ case SW_EGAMONO80x25:
+ adp = get_adapter(scp);
+ if (!(adp->va_flags & V_ADP_MODECHANGE))
+ return ENODEV;
+ return sc_set_text_mode(scp, tp, cmd & 0xff, 0, 0, 0);
+
+ /* GRAPHICS MODES */
+ case SW_BG320: case SW_BG640:
+ case SW_CG320: case SW_CG320_D: case SW_CG640_E:
+ case SW_CG640x350: case SW_ENH_CG640:
+ case SW_BG640x480: case SW_CG640x480: case SW_VGA_CG320:
+ case SW_VGA_MODEX:
+ adp = get_adapter(scp);
+ if (!(adp->va_flags & V_ADP_MODECHANGE))
+ return ENODEV;
+ return sc_set_graphics_mode(scp, tp, cmd & 0xff);
+
+ case KDSETMODE: /* set current mode of this (virtual) console */
+ switch (*data) {
+ case KD_TEXT: /* switch to TEXT (known) mode */
+ /*
+ * If scp->mode is of graphics modes, we don't know which
+ * text mode to switch back to...
+ */
+ if (scp->status & GRAPHICS_MODE)
+ return EINVAL;
+ /* restore fonts & palette ! */
+#if 0
+ adp = get_adapter(scp);
+ if (ISFONTAVAIL(adp->va_flags)
+ && !(scp->status & (GRAPHICS_MODE | PIXEL_MODE)))
+ /*
+ * FONT KLUDGE
+ * Don't load fonts for now... XXX
+ */
+ if (fonts_loaded & FONT_8)
+ copy_font(scp, LOAD, 8, font_8);
+ if (fonts_loaded & FONT_14)
+ copy_font(scp, LOAD, 14, font_14);
+ if (fonts_loaded & FONT_16)
+ copy_font(scp, LOAD, 16, font_16);
+ }
+#endif
+ load_palette(scp, palette);
+
+ /* move hardware cursor out of the way */
+ (*biosvidsw.set_hw_cursor)(scp->adp, -1, -1);
+
+ /* FALL THROUGH */
+
+ case KD_TEXT1: /* switch to TEXT (known) mode */
+ /*
+ * If scp->mode is of graphics modes, we don't know which
+ * text/pixel mode to switch back to...
+ */
+ if (scp->status & GRAPHICS_MODE)
+ return EINVAL;
+ s = spltty();
+ if ((error = sc_clean_up(scp))) {
+ splx(s);
+ return error;
+ }
+ scp->status |= UNKNOWN_MODE;
+ splx(s);
+ /* no restore fonts & palette */
+ if (scp == cur_console) {
+ set_mode(scp);
+ /* FIXME */
+ if (scp->status & PIXEL_MODE)
+ bzero(Crtat, scp->xpixel*scp->ypixel/8);
+ }
+ sc_clear_screen(scp);
+ scp->status &= ~UNKNOWN_MODE;
+ return 0;
+
+ case KD_PIXEL: /* pixel (raster) display */
+ if (!(scp->status & (GRAPHICS_MODE | PIXEL_MODE)))
+ return EINVAL;
+ if (!(scp->status & PIXEL_MODE))
+ return sc_set_pixel_mode(scp, tp, scp->xsize, scp->ysize,
+ scp->font_size);
+ s = spltty();
+ if ((error = sc_clean_up(scp))) {
+ splx(s);
+ return error;
+ }
+ scp->status |= (UNKNOWN_MODE | PIXEL_MODE);
+ splx(s);
+ if (scp == cur_console) {
+ set_mode(scp);
+ load_palette(scp, palette);
+ /* FIXME */
+ bzero(Crtat, scp->xpixel*scp->ypixel/8);
+ }
+ sc_clear_screen(scp);
+ scp->status &= ~UNKNOWN_MODE;
+ return 0;
+
+ case KD_GRAPHICS: /* switch to GRAPHICS (unknown) mode */
+ s = spltty();
+ if ((error = sc_clean_up(scp))) {
+ splx(s);
+ return error;
+ }
+ scp->status |= UNKNOWN_MODE;
+ splx(s);
+ return 0;
+
+ default:
+ return EINVAL;
+ }
+ /* NOT REACHED */
+
+ case KDRASTER: /* set pixel (raster) display mode */
+ if (ISUNKNOWNSC(scp) || ISTEXTSC(scp))
+ return ENODEV;
+ return sc_set_pixel_mode(scp, tp, ((int *)data)[0], ((int *)data)[1],
+ ((int *)data)[2]);
+
+ case KDGETMODE: /* get current mode of this (virtual) console */
+ /*
+ * From the user program's point of view, KD_PIXEL is the same
+ * as KD_TEXT...
+ */
+ *data = ISGRAPHSC(scp) ? KD_GRAPHICS : KD_TEXT;
+ return 0;
+
+ case KDSBORDER: /* set border color of this (virtual) console */
+ scp->border = *data;
+ if (scp == cur_console)
+ set_border(cur_console, scp->border);
+ return 0;
+ }
+
+ return ENOIOCTL;
+}
+
+#endif /* NSC > 0 */
diff --git a/sys/dev/syscons/snake/snake_saver.c b/sys/dev/syscons/snake/snake_saver.c
index c3fa1fe..c5011d0 100644
--- a/sys/dev/syscons/snake/snake_saver.c
+++ b/sys/dev/syscons/snake/snake_saver.c
@@ -1,18 +1,18 @@
/*-
- * Copyright (c) 1995 Søren Schmidt
+ * Copyright (c) 1995-1998 Søren Schmidt
* 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
- * in this position and unchanged.
+ * notice, this list of conditions and the following disclaimer,
+ * without modification, immediately at the beginning of the file.
* 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. The name of the author may not be used to endorse or promote products
- * derived from this software withough specific prior written permission
+ * derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: snake_saver.c,v 1.16 1998/01/16 17:58:50 bde Exp $
+ * $Id$
*/
#include <sys/param.h>
@@ -63,7 +63,7 @@ snake_saver(int blank)
if (scrn_blanked <= 0) {
fillw((FG_LIGHTGREY|BG_BLACK)<<8 | scr_map[0x20],
Crtat, scp->xsize * scp->ysize);
- set_border(0);
+ set_border(scp, 0);
dirx = (scp->xpos ? 1 : -1);
diry = (scp->ypos ?
scp->xsize : -scp->xsize);
@@ -99,7 +99,7 @@ snake_saver(int blank)
}
else {
if (scrn_blanked > 0) {
- set_border(scp->border);
+ set_border(scp, scp->border);
scrn_blanked = 0;
}
}
diff --git a/sys/dev/syscons/star/star_saver.c b/sys/dev/syscons/star/star_saver.c
index 517a557..8ac65bd 100644
--- a/sys/dev/syscons/star/star_saver.c
+++ b/sys/dev/syscons/star/star_saver.c
@@ -1,18 +1,18 @@
/*-
- * Copyright (c) 1995 Søren Schmidt
+ * Copyright (c) 1995-1998 Søren Schmidt
* 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
- * in this position and unchanged.
+ * notice, this list of conditions and the following disclaimer,
+ * without modification, immediately at the beginning of the file.
* 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. The name of the author may not be used to endorse or promote products
- * derived from this software withough specific prior written permission
+ * derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: star_saver.c,v 1.13 1998/01/16 17:58:55 bde Exp $
+ * $Id$
*/
#include <sys/param.h>
@@ -62,7 +62,7 @@ star_saver(int blank)
scrn_blanked = 1;
fillw((FG_LIGHTGREY|BG_BLACK)<<8|scr_map[0x20], Crtat,
scp->xsize * scp->ysize);
- set_border(0);
+ set_border(scp, 0);
for(i=0; i<NUM_STARS; i++) {
stars[i][0] =
random() % (scp->xsize*scp->ysize);
@@ -80,7 +80,7 @@ star_saver(int blank)
}
else {
if (scrn_blanked > 0) {
- set_border(scp->border);
+ set_border(scp, scp->border);
scrn_blanked = 0;
}
}
diff --git a/sys/dev/syscons/syscons.c b/sys/dev/syscons/syscons.c
index ebc243f..50e0f19 100644
--- a/sys/dev/syscons/syscons.c
+++ b/sys/dev/syscons/syscons.c
@@ -1,18 +1,18 @@
/*-
- * Copyright (c) 1992-1997 Søren Schmidt
+ * Copyright (c) 1992-1998 Søren Schmidt
* 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
- * in this position and unchanged.
+ * notice, this list of conditions and the following disclaimer,
+ * without modification, immediately at the beginning of the file.
* 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. The name of the author may not be used to endorse or promote products
- * derived from this software withough specific prior written permission
+ * derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@@ -25,13 +25,15 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: syscons.c,v 1.276 1998/08/23 08:26:41 bde Exp $
+ * $Id$
*/
#include "sc.h"
#include "apm.h"
#include "opt_ddb.h"
#include "opt_devfs.h"
+#include "opt_vesa.h"
+#include "opt_vm86.h"
#include "opt_syscons.h"
#if NSC > 0
@@ -57,9 +59,9 @@
#include <machine/psl.h>
#include <machine/frame.h>
#include <machine/pc/display.h>
+#include <machine/pc/vesa.h>
#include <machine/apm_bios.h>
#include <machine/random.h>
-#include <machine/bootinfo.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
@@ -70,6 +72,7 @@
#include <i386/isa/timerreg.h>
#include <i386/isa/kbdtables.h>
#include <i386/isa/kbdio.h>
+#include <i386/isa/videoio.h>
#include <i386/isa/syscons.h>
#if !defined(MAXCONS)
@@ -96,11 +99,6 @@
#define COLD 0
#define WARM 1
-#define VESA_MODE(x) ((x) >= M_VESA_BASE)
-
-#define MODE_MAP_SIZE (M_VGA_CG320 + 1)
-#define MODE_PARAM_SIZE 64
-
#define DEFAULT_BLANKTIME (5*60) /* 5 minutes */
#define MAX_BLANKTIME (7*24*60*60) /* 7 days!? */
@@ -159,6 +157,7 @@ static int blinkrate = 0;
u_int crtc_addr = MONO_BASE;
char crtc_type = KD_MONO;
char crtc_vga = FALSE;
+static int adp_flags = 0;
static u_char shfts = 0, ctls = 0, alts = 0, agrs = 0, metas = 0;
static u_char accents = 0;
static u_char nlkcnt = 0, clkcnt = 0, slkcnt = 0, alkcnt = 0;
@@ -172,7 +171,7 @@ static int run_scrn_saver = FALSE; /* should run the saver? */
static int scrn_idle = FALSE; /* about to run the saver */
u_char scr_map[256];
u_char scr_rmap[256];
- char *video_mode_ptr = NULL;
+static int initial_video_mode; /* initial video mode # */
static int bios_video_mode; /* video mode # set by BIOS */
int fonts_loaded = 0
#ifdef STD8X16FONT
@@ -180,19 +179,15 @@ static int bios_video_mode; /* video mode # set by BIOS */
#endif
;
- char font_8[256*8];
- char font_14[256*14];
+ u_char font_8[256*8];
+ u_char font_14[256*14];
#ifdef STD8X16FONT
extern
#endif
- unsigned char font_16[256*16];
- char palette[256*3];
-static char *mode_map[MODE_MAP_SIZE];
-static char vgaregs[MODE_PARAM_SIZE];
-static char vgaregs2[MODE_PARAM_SIZE];
-static int rows_offset = 1;
-static char *cut_buffer;
-static int cut_buffer_size;
+ u_char font_16[256*16];
+ u_char palette[256*3];
+static u_char *cut_buffer = NULL;
+static int cut_buffer_size = 0;
static int mouse_level = 0; /* sysmouse protocol level */
static mousestatus_t mouse_status = { 0, 0, 0, 0, 0, 0 };
static u_short mouse_and_mask[16] = {
@@ -208,13 +203,14 @@ static u_short mouse_or_mask[16] = {
0x0000, 0x0000, 0x0000, 0x0000
};
-static int extra_history_size =
+ int sc_history_size = SC_HISTORY_SIZE;
+static int extra_history_size =
SC_MAX_HISTORY_SIZE - SC_HISTORY_SIZE * MAXCONS;
static void none_saver(int blank) { }
static void (*current_saver)(int blank) = none_saver;
static void (*default_saver)(int blank) = none_saver;
-int (*sc_user_ioctl)(dev_t dev, int cmd, caddr_t data,
+ int (*sc_user_ioctl)(dev_t dev, int cmd, caddr_t data,
int flag, struct proc *p) = NULL;
static int sticky_splash = FALSE;
@@ -233,8 +229,6 @@ static struct tty sccons[MAXCONS+2];
#endif
#define SC_MOUSE 128
#define SC_CONSOLE 255
-#define MONO_BUF pa_to_va(0xB0000)
-#define CGA_BUF pa_to_va(0xB8000)
u_short *Crtat;
static const int nsccons = MAXCONS+2;
@@ -243,9 +237,6 @@ static const int nsccons = MAXCONS+2;
+ (offset)) % (scp->history_size)))
#define ISSIGVALID(sig) ((sig) > 0 && (sig) < NSIG)
-/* this should really be in `rtc.h' */
-#define RTC_EQUIPMENT 0x14
-
/* prototypes */
static int scattach(struct isa_device *dev);
static int scparam(struct tty *tp, struct termios *t);
@@ -256,30 +247,26 @@ static void scstart(struct tty *tp);
static void scmousestart(struct tty *tp);
static void scinit(void);
static void scshutdown(int howto, void *arg);
-static void map_mode_table(char *map[], char *table, int max);
-static int map_mode_num(int mode);
-static char *get_mode_param(scr_stat *scp, int mode);
static u_int scgetc(u_int flags);
#define SCGETC_CN 1
#define SCGETC_NONBLOCK 2
static void sccnupdate(scr_stat *scp);
-static scr_stat *get_scr_stat(dev_t dev);
static scr_stat *alloc_scp(void);
static void init_scp(scr_stat *scp);
static void sc_bcopy(scr_stat *scp, u_short *p, int from, int to, int mark);
static int get_scr_num(void);
static timeout_t scrn_timer;
static void scrn_update(scr_stat *scp, int show_cursor);
+static void scrn_saver(void (*saver)(int), int blank);
static void stop_scrn_saver(void (*saver)(int));
static int wait_scrn_saver_stop(void);
-static void clear_screen(scr_stat *scp);
static int switch_scr(scr_stat *scp, u_int next_scr);
static void exchange_scr(void);
-static void move_crsr(scr_stat *scp, int x, int y);
static void scan_esc(scr_stat *scp, u_char c);
+static void ansi_put(scr_stat *scp, u_char *buf, int len);
static void draw_cursor_image(scr_stat *scp);
static void remove_cursor_image(scr_stat *scp);
-static void ansi_put(scr_stat *scp, u_char *buf, int len);
+static void move_crsr(scr_stat *scp, int x, int y);
static u_char *get_fstr(u_int c, u_int *len);
static void history_to_screen(scr_stat *scp);
static int history_up_line(scr_stat *scp);
@@ -287,16 +274,6 @@ static int history_down_line(scr_stat *scp);
static int mask2attr(struct term_stat *term);
static void set_keyboard(int command, int data);
static void update_leds(int which);
-static void set_vgaregs(char *modetable);
-static void read_vgaregs(char *buf);
-#define COMP_IDENTICAL 0
-#define COMP_SIMILAR 1
-#define COMP_DIFFERENT 2
-static int comp_vgaregs(u_char *buf1, u_char *buf2);
-static void dump_vgaregs(u_char *buf);
-#define PARAM_BUFSIZE 6
-static void set_font_mode(u_char *buf);
-static void set_normal_mode(u_char *buf);
static void set_destructive_cursor(scr_stat *scp);
static void set_mouse_pos(scr_stat *scp);
static int skip_spc_right(scr_stat *scp, u_short *p);
@@ -312,12 +289,11 @@ static void draw_mouse_image(scr_stat *scp);
static void remove_mouse_image(scr_stat *scp);
static void draw_cutmarking(scr_stat *scp);
static void remove_cutmarking(scr_stat *scp);
-static void save_palette(void);
static void do_bell(scr_stat *scp, int pitch, int duration);
static timeout_t blink_screen;
#ifdef SC_SPLASH_SCREEN
-static void scsplash_init(void);
-static void scsplash(int show);
+static void scsplash_init(scr_stat *scp);
+static void scsplash_saver(int show);
#define scsplash_stick(stick) (sticky_splash = (stick))
#else
#define scsplash_stick(stick)
@@ -332,7 +308,7 @@ static d_close_t scclose;
static d_read_t scread;
static d_write_t scwrite;
static d_ioctl_t scioctl;
-static d_devtotty_t scdevtotty;
+ d_devtotty_t scdevtotty;
static d_mmap_t scmmap;
#define CDEV_MAJOR 12
@@ -353,7 +329,7 @@ draw_cursor_image(scr_stat *scp)
u_short cursor_image, *ptr = Crtat + (scp->cursor_pos - scp->scr_buf);
u_short prev_image;
- if (VESA_MODE(scp->mode)) {
+ if (ISPIXELSC(scp)) {
sc_bcopy(scp, scp->scr_buf, scp->cursor_pos - scp->scr_buf,
scp->cursor_pos - scp->scr_buf, 1);
return;
@@ -405,7 +381,7 @@ draw_cursor_image(scr_stat *scp)
static void
remove_cursor_image(scr_stat *scp)
{
- if (VESA_MODE(scp->mode))
+ if (ISPIXELSC(scp))
sc_bcopy(scp, scp->scr_buf, scp->cursor_oldpos - scp->scr_buf,
scp->cursor_oldpos - scp->scr_buf, 0);
else
@@ -436,6 +412,12 @@ scprobe(struct isa_device *dev)
printf("sc%d: no video adapter is found.\n", dev->id_unit);
return (0);
}
+ (*biosvidsw.diag)(bootverbose);
+#if defined(VESA) && defined(VM86)
+ if (vesa_load())
+ return FALSE;
+ (*biosvidsw.diag)(bootverbose);
+#endif
sc_port = dev->id_iobase;
if (sckbdprobe(dev->id_unit, dev->id_flags))
@@ -448,99 +430,24 @@ scprobe(struct isa_device *dev)
static int
scvidprobe(int unit, int flags)
{
- /*
- * XXX don't try to `printf' anything here, the console may not have
- * been configured yet.
- */
- u_short volatile *cp;
- u_short was;
- u_int pa;
- u_int segoff;
+ video_adapter_t *adp;
/* do this test only once */
if (init_done != COLD)
- return (Crtat != 0);
-
- /*
- * Finish defaulting crtc variables for a mono screen. Crtat is a
- * bogus common variable so that it can be shared with pcvt, so it
- * can't be statically initialized. XXX.
- */
- Crtat = (u_short *)MONO_BUF;
- crtc_type = KD_MONO;
- /* If CGA memory seems to work, switch to color. */
- cp = (u_short *)CGA_BUF;
- was = *cp;
- *cp = (u_short) 0xA55A;
- bios_video_mode = *(u_char *)pa_to_va(0x449);
- if (bootinfo.bi_vesa == 0x102) {
- bios_video_mode = bootinfo.bi_vesa;
- Crtat = (u_short *)pa_to_va(0xA0000);
- crtc_addr = COLOR_BASE;
- crtc_type = KD_VGA;
- bzero(Crtat, 800*600/8);
- } else if (*cp == 0xA55A) {
- Crtat = (u_short *)CGA_BUF;
- crtc_addr = COLOR_BASE;
- crtc_type = KD_CGA;
- } else {
- cp = Crtat;
- was = *cp;
- *cp = (u_short) 0xA55A;
- if (*cp != 0xA55A) {
- /* no screen at all, bail out */
- Crtat = 0;
- return FALSE;
- }
- }
- *cp = was;
+ return (crtc_type != -1);
- if (!VESA_MODE(bios_video_mode)) {
- /*
- * Check rtc and BIOS date area.
- * XXX: don't use BIOSDATA_EQUIPMENT, it is not a dead copy
- * of RTC_EQUIPMENT. The bit 4 and 5 of the ETC_EQUIPMENT are
- * zeros for EGA and VGA. However, the EGA/VGA BIOS will set
- * these bits in BIOSDATA_EQUIPMENT according to the monitor
- * type detected.
- */
- switch ((rtcin(RTC_EQUIPMENT) >> 4) & 3) { /* bit 4 and 5 */
- case 0: /* EGA/VGA, or nothing */
- crtc_type = KD_EGA;
- /* the color adapter may be in the 40x25 mode... XXX */
- break;
- case 1: /* CGA 40x25 */
- /* switch to the 80x25 mode? XXX */
- /* FALL THROUGH */
- case 2: /* CGA 80x25 */
- /* `crtc_type' has already been set... */
- /* crtc_type = KD_CGA; */
- break;
- case 3: /* MDA */
- /* `crtc_type' has already been set... */
- /* crtc_type = KD_MONO; */
- break;
- }
+ if ((*biosvidsw.init)() <= 0)
+ return FALSE;
+ if ((adp = (*biosvidsw.adapter)(V_ADP_PRIMARY)) == NULL)
+ return FALSE;
- /* is this a VGA or higher ? */
- outb(crtc_addr, 7);
- if (inb(crtc_addr) == 7) {
-
- crtc_type = KD_VGA;
- crtc_vga = TRUE;
- read_vgaregs(vgaregs);
-
- /* Get the BIOS video mode pointer */
- segoff = *(u_int *)pa_to_va(0x4a8);
- pa = ((segoff & 0xffff0000) >> 12) + (segoff & 0xffff);
- if (ISMAPPED(pa, sizeof(u_int))) {
- segoff = *(u_int *)pa_to_va(pa);
- pa = ((segoff & 0xffff0000) >> 12) + (segoff & 0xffff);
- if (ISMAPPED(pa, MODE_PARAM_SIZE))
- video_mode_ptr = (char *)pa_to_va(pa);
- }
- }
- }
+ crtc_type = adp->va_type;
+ crtc_vga = (crtc_type == KD_VGA);
+ crtc_addr = adp->va_crtc_addr;
+ Crtat = (u_short *)adp->va_window;
+ adp_flags = adp->va_flags;
+ initial_video_mode = adp->va_initial_mode;
+ bios_video_mode = adp->va_initial_bios_mode;
return TRUE;
}
@@ -728,48 +635,42 @@ static int
scattach(struct isa_device *dev)
{
scr_stat *scp;
+ video_info_t info;
dev_t cdev = makedev(CDEV_MAJOR, 0);
- char *p;
#ifdef DEVFS
int vc;
#endif
scinit();
flags = dev->id_flags;
- if (crtc_type != KD_VGA || VESA_MODE(bios_video_mode))
+ if (!ISFONTAVAIL(adp_flags))
flags &= ~CHAR_CURSOR;
scp = console[0];
- if (crtc_type == KD_VGA) {
- cut_buffer_size = scp->xsize * scp->ysize + 1;
- cut_buffer = (char *)malloc(cut_buffer_size, M_DEVBUF, M_NOWAIT);
- if (cut_buffer != NULL)
- cut_buffer[0] = '\0';
- }
-
- scp->scr_buf = (u_short *)malloc(scp->xsize*scp->ysize*sizeof(u_short),
- M_DEVBUF, M_NOWAIT);
-
/* copy temporary buffer to final buffer */
- bcopy(sc_buffer, scp->scr_buf, scp->xsize * scp->ysize * sizeof(u_short));
+ scp->scr_buf = NULL;
+ sc_alloc_scr_buffer(scp, FALSE, FALSE);
+ bcopy(sc_buffer, scp->scr_buf, scp->xsize*scp->ysize*sizeof(u_short));
- scp->cursor_pos = scp->cursor_oldpos =
- scp->scr_buf + scp->xpos + scp->ypos * scp->xsize;
- scp->mouse_pos = scp->mouse_oldpos =
- scp->scr_buf + ((scp->mouse_ypos/scp->font_size)*scp->xsize +
- scp->mouse_xpos/8);
+ /* cut buffer is available only when the mouse pointer is used */
+ if (ISMOUSEAVAIL(adp_flags))
+ sc_alloc_cut_buffer(scp, FALSE);
/* initialize history buffer & pointers */
- scp->history_head = scp->history_pos =
- (u_short *)malloc(scp->history_size*sizeof(u_short),
- M_DEVBUF, M_NOWAIT);
- if (scp->history_head != NULL)
- bzero(scp->history_head, scp->history_size*sizeof(u_short));
- scp->history = scp->history_head;
+ sc_alloc_history_buffer(scp, sc_history_size, 0, FALSE);
+
+#if defined(VESA) && defined(VM86)
+ if ((flags & VESA800X600)
+ && ((*biosvidsw.get_info)(scp->adp, M_VESA_800x600, &info) == 0)) {
+ sc_set_graphics_mode(scp, NULL, M_VESA_800x600);
+ sc_set_pixel_mode(scp, NULL, COL, ROW, 16);
+ initial_video_mode = M_VESA_800x600;
+ }
+#endif /* VESA && VM86 */
/* initialize cursor stuff */
- if (!(scp->status & UNKNOWN_MODE))
+ if (!ISGRAPHSC(scp))
draw_cursor_image(scp);
/* get screen update going */
@@ -777,42 +678,13 @@ scattach(struct isa_device *dev)
update_leds(scp->status);
- if ((crtc_type == KD_VGA) && bootverbose) {
- printf("sc%d: BIOS video mode:%d\n", dev->id_unit, bios_video_mode);
- printf("sc%d: VGA registers upon power-up\n", dev->id_unit);
- dump_vgaregs(vgaregs);
- printf("sc%d: video mode:%d\n", dev->id_unit, scp->mode);
- printf("sc%d: VGA registers in BIOS for mode:%d\n",
- dev->id_unit, scp->mode);
- dump_vgaregs(vgaregs2);
- p = get_mode_param(scp, scp->mode);
- if (p != NULL) {
- printf("sc%d: VGA registers to be used for mode:%d\n",
- dev->id_unit, scp->mode);
- dump_vgaregs(p);
- }
- printf("sc%d: rows_offset:%d\n", dev->id_unit, rows_offset);
- }
- if ((crtc_type == KD_VGA) && !VESA_MODE(bios_video_mode)
- && (video_mode_ptr == NULL))
- printf("sc%d: WARNING: video mode switching is only partially supported\n",
- dev->id_unit);
-
printf("sc%d: ", dev->id_unit);
switch(crtc_type) {
case KD_VGA:
- if (VESA_MODE(bios_video_mode))
- printf("Graphics display (VESA mode = 0x%x)", bios_video_mode);
- else if (crtc_addr == MONO_BASE)
- printf("VGA mono");
- else
- printf("VGA color");
+ printf("VGA %s", (adp_flags & V_ADP_COLOR) ? "color" : "mono");
break;
case KD_EGA:
- if (crtc_addr == MONO_BASE)
- printf("EGA mono");
- else
- printf("EGA color");
+ printf("EGA %s", (adp_flags & V_ADP_COLOR) ? "color" : "mono");
break;
case KD_CGA:
printf("CGA");
@@ -820,7 +692,7 @@ scattach(struct isa_device *dev)
case KD_MONO:
case KD_HERCULES:
default:
- printf("MDA/hercules");
+ printf("MDA/Hercules");
break;
}
printf(" <%d virtual consoles, flags=0x%x>\n", MAXCONS, flags);
@@ -896,6 +768,8 @@ scopen(dev_t dev, int flag, int mode, struct proc *p)
return(EBUSY);
if (minor(dev) < MAXCONS && !console[minor(dev)]) {
console[minor(dev)] = alloc_scp();
+ if (ISGRAPHSC(console[minor(dev)]))
+ sc_set_pixel_mode(console[minor(dev)], NULL, COL, ROW, 16);
}
if (minor(dev)<MAXCONS && !tp->t_winsize.ws_col && !tp->t_winsize.ws_row) {
tp->t_winsize.ws_col = console[minor(dev)]->xsize;
@@ -913,7 +787,7 @@ scclose(dev_t dev, int flag, int mode, struct proc *p)
if (!tp)
return(ENXIO);
if (minor(dev) < MAXCONS) {
- scp = get_scr_stat(tp->t_dev);
+ scp = sc_get_scr_stat(tp->t_dev);
if (scp->status & SWITCH_WAIT_ACQ)
wakeup((caddr_t)&scp->smode);
#if not_yet_done
@@ -927,9 +801,9 @@ scclose(dev_t dev, int flag, int mode, struct proc *p)
if (scp->history != NULL) {
free(scp->history, M_DEVBUF);
if (scp->history_size / scp->xsize
- > imax(SC_HISTORY_SIZE, scp->ysize))
+ > imax(sc_history_size, scp->ysize))
extra_history_size += scp->history_size / scp->xsize
- - imax(SC_HISTORY_SIZE, scp->ysize);
+ - imax(sc_history_size, scp->ysize);
}
free(scp, M_DEVBUF);
console[minor(dev)] = NULL;
@@ -1008,10 +882,17 @@ scintr(int unit)
}
}
+#if 0
if (cur_console->status & MOUSE_ENABLED) {
cur_console->status &= ~MOUSE_VISIBLE;
remove_mouse_image(cur_console);
}
+#else
+ if (cur_console->status & MOUSE_VISIBLE) {
+ remove_mouse_image(cur_console);
+ cur_console->status &= ~MOUSE_VISIBLE;
+ }
+#endif
}
static int
@@ -1030,21 +911,25 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
u_int i;
struct tty *tp;
scr_stat *scp;
- u_short *usp;
- char *mp;
+ video_adapter_t *adp;
int s;
tp = scdevtotty(dev);
if (!tp)
return ENXIO;
- scp = get_scr_stat(tp->t_dev);
+ scp = sc_get_scr_stat(tp->t_dev);
/* If there is a user_ioctl function call that first */
if (sc_user_ioctl) {
- if (error = (*sc_user_ioctl)(dev, cmd, data, flag, p))
+ error = (*sc_user_ioctl)(dev, cmd, data, flag, p);
+ if (error != ENOIOCTL)
return error;
}
+ error = sc_vid_ioctl(tp, cmd, data, flag, p);
+ if (error != ENOIOCTL)
+ return error;
+
switch (cmd) { /* process console hardware related ioctl's */
case GIO_ATTR: /* get current attributes */
@@ -1052,18 +937,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return 0;
case GIO_COLOR: /* is this a color console ? */
- if (crtc_addr == COLOR_BASE)
- *(int*)data = 1;
- else
- *(int*)data = 0;
- return 0;
-
- case CONS_CURRENT: /* get current adapter type */
- *(int *)data = crtc_type;
- return 0;
-
- case CONS_GET: /* get current video mode */
- *(int*)data = scp->mode;
+ *(int *)data = (adp_flags & V_ADP_COLOR) ? 1 : 0;
return 0;
case CONS_BLANKTIME: /* set screen saver timeout (0 = no saver) */
@@ -1081,7 +955,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
else
flags &= ~BLINK_CURSOR;
if ((*(int*)data) & 0x02) {
- if (crtc_type != KD_VGA || VESA_MODE(bios_video_mode))
+ if (!ISFONTAVAIL(get_adapter(scp)->va_flags))
return ENXIO;
flags |= CHAR_CURSOR;
} else
@@ -1090,7 +964,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
* The cursor shape is global property; all virtual consoles
* are affected. Update the cursor in the current console...
*/
- if (!(cur_console->status & UNKNOWN_MODE)) {
+ if (!ISGRAPHSC(cur_console)) {
remove_cursor_image(cur_console);
if (flags & CHAR_CURSOR)
set_destructive_cursor(cur_console);
@@ -1117,37 +991,22 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
lines = imax(*(int *)data, scp->ysize);
lines0 = (scp->history != NULL) ?
scp->history_size / scp->xsize : scp->ysize;
+ if (lines0 > imax(sc_history_size, scp->ysize))
+ i = lines0 - imax(sc_history_size, scp->ysize);
+ else
+ i = 0;
/*
* syscons unconditionally allocates buffers upto SC_HISTORY_SIZE
* lines or scp->ysize lines, whichever is larger. A value
* greater than that is allowed, subject to extra_history_size.
*/
- if (lines > imax(lines0, SC_HISTORY_SIZE) + extra_history_size)
- return EINVAL;
+ if (lines > imax(sc_history_size, scp->ysize))
+ if (lines - imax(sc_history_size, scp->ysize) >
+ extra_history_size + i)
+ return EINVAL;
if (cur_console->status & BUFFER_SAVED)
return EBUSY;
- usp = scp->history;
- scp->history = NULL;
- if (usp != NULL)
- free(usp, M_DEVBUF);
- scp->history_size = lines * scp->xsize;
- /*
- * extra_history_size +=
- * (lines0 > imax(SC_HISTORY_SIZE, scp->ysize)) ?
- * lines0 - imax(SC_HISTORY_SIZE, scp->ysize)) : 0;
- * extra_history_size -=
- * (lines > imax(SC_HISTORY_SIZE, scp->ysize)) ?
- * lines - imax(SC_HISTORY_SIZE, scp->ysize)) : 0;
- * lines0 >= ysize && lines >= ysize... Hey, the above can be
- * reduced to the following...
- */
- extra_history_size +=
- imax(lines0, SC_HISTORY_SIZE) - imax(lines, SC_HISTORY_SIZE);
- usp = (u_short *)malloc(scp->history_size * sizeof(u_short),
- M_DEVBUF, M_WAITOK);
- bzero(usp, scp->history_size * sizeof(u_short));
- scp->history_head = scp->history_pos = usp;
- scp->history = usp;
+ sc_alloc_history_buffer(scp, lines, i, TRUE);
return 0;
}
else
@@ -1171,7 +1030,8 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
mouse_info_t *mouse = (mouse_info_t*)data;
mouse_info_t buf;
- if (crtc_type != KD_VGA || VESA_MODE(bios_video_mode))
+ /* FIXME: */
+ if (!ISMOUSEAVAIL(get_adapter(scp)->va_flags))
return ENODEV;
if (cmd == OLD_CONS_MOUSECTL) {
@@ -1220,7 +1080,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return 0;
case MOUSE_SHOW:
- if (!(scp->status & MOUSE_ENABLED)) {
+ if (ISTEXTSC(scp) && !(scp->status & MOUSE_ENABLED)) {
scp->status |= (MOUSE_ENABLED | MOUSE_VISIBLE);
scp->mouse_oldpos = scp->mouse_pos;
mark_all(scp);
@@ -1231,7 +1091,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
break;
case MOUSE_HIDE:
- if (scp->status & MOUSE_ENABLED) {
+ if (ISTEXTSC(scp) && (scp->status & MOUSE_ENABLED)) {
scp->status &= ~(MOUSE_ENABLED | MOUSE_VISIBLE);
mark_all(scp);
return 0;
@@ -1276,7 +1136,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
if (mouse_status.flags == 0)
return 0;
- if (cur_console->status & MOUSE_ENABLED)
+ if (ISTEXTSC(cur_console) && (cur_console->status & MOUSE_ENABLED))
cur_console->status |= MOUSE_VISIBLE;
if ((MOUSE_TTY)->t_state & TS_ISOPEN) {
@@ -1321,7 +1181,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
else if (mouse->operation == MOUSE_ACTION && cut_buffer != NULL) {
/* process button presses */
if ((cur_console->mouse_buttons ^ mouse->u.data.buttons) &&
- !(cur_console->status & UNKNOWN_MODE)) {
+ ISTEXTSC(cur_console)) {
cur_console->mouse_buttons = mouse->u.data.buttons;
if (cur_console->mouse_buttons & MOUSE_BUTTON1DOWN)
mouse_cut_start(cur_console);
@@ -1358,7 +1218,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
if (mouse_status.flags == 0)
return 0;
- if (cur_console->status & MOUSE_ENABLED)
+ if (ISTEXTSC(cur_console) && (cur_console->status & MOUSE_ENABLED))
cur_console->status |= MOUSE_VISIBLE;
if ((MOUSE_TTY)->t_state & TS_ISOPEN) {
@@ -1387,7 +1247,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
break;
}
- if ((cur_console->status & UNKNOWN_MODE) || (cut_buffer == NULL))
+ if (!ISTEXTSC(cur_console) || (cut_buffer == NULL))
break;
switch (mouse->u.event.id) {
@@ -1567,18 +1427,41 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return 0;
case CONS_IDLE: /* see if the screen has been idle */
- *(int *)data = (scrn_idle && !(cur_console->status & UNKNOWN_MODE));
+ /*
+ * When the screen is in the GRAPHICS_MODE or UNKNOWN_MODE,
+ * the user process may have been writing something on the
+ * screen and syscons is not aware of it. Declare the screen
+ * is NOT idle if it is in one of these modes. But there is
+ * an exception to it; if a screen saver is running in the
+ * graphics mode in the current screen, we should say that the
+ * screen has been idle.
+ */
+ *(int *)data = scrn_idle
+ && (!ISGRAPHSC(cur_console)
+ || (cur_console->status & SAVER_RUNNING));
return 0;
case CONS_SAVERMODE: /* set saver mode */
switch(*(int *)data) {
case CONS_USR_SAVER:
- /* if a LKM screen saver is running, it will eventually stop... */
+ /* if a LKM screen saver is running, stop it first. */
+ scsplash_stick(FALSE);
saver_mode = *(int *)data;
+ s = spltty();
+ if ((error = wait_scrn_saver_stop())) {
+ splx(s);
+ return error;
+ }
+ scp->status |= SAVER_RUNNING;
scsplash_stick(TRUE);
+ splx(s);
break;
case CONS_LKM_SAVER:
+ s = spltty();
+ if ((saver_mode == CONS_USR_SAVER) && (scp->status & SAVER_RUNNING))
+ scp->status &= ~SAVER_RUNNING;
saver_mode = *(int *)data;
+ splx(s);
break;
default:
return EINVAL;
@@ -1597,226 +1480,6 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
splx(s);
return 0;
- /* VGA TEXT MODES */
- case SW_VGA_C40x25:
- case SW_VGA_C80x25: case SW_VGA_M80x25:
- case SW_VGA_C80x30: case SW_VGA_M80x30:
- case SW_VGA_C80x50: case SW_VGA_M80x50:
- case SW_VGA_C80x60: case SW_VGA_M80x60:
- case SW_B40x25: case SW_C40x25:
- case SW_B80x25: case SW_C80x25:
- case SW_ENH_B40x25: case SW_ENH_C40x25:
- case SW_ENH_B80x25: case SW_ENH_C80x25:
- case SW_ENH_B80x43: case SW_ENH_C80x43:
- case SW_EGAMONO80x25:
-
- if (crtc_type != KD_VGA)
- return ENODEV;
- mp = get_mode_param(scp, cmd & 0xff);
- if (mp == NULL)
- return ENODEV;
-
- s = spltty();
- if ((error = wait_scrn_saver_stop())) {
- splx(s);
- return error;
- }
-
- scp->status &= ~MOUSE_VISIBLE;
- remove_cutmarking(scp);
- if (scp->history != NULL)
- i = imax(scp->history_size / scp->xsize
- - imax(SC_HISTORY_SIZE, scp->ysize), 0);
- else
- i = 0;
- switch (cmd & 0xff) {
- case M_VGA_C80x60: case M_VGA_M80x60:
- if (!(fonts_loaded & FONT_8)) {
- splx(s);
- return EINVAL;
- }
- /*
- * This is a kludge to fend off scrn_update() while we
- * muck around with scp. XXX
- */
- scp->status |= UNKNOWN_MODE;
- scp->xsize = 80;
- scp->ysize = 60;
- scp->font_size = 8;
- break;
- case M_VGA_C80x50: case M_VGA_M80x50:
- if (!(fonts_loaded & FONT_8)) {
- splx(s);
- return EINVAL;
- }
- scp->status |= UNKNOWN_MODE;
- scp->xsize = 80;
- scp->ysize = 50;
- scp->font_size = 8;
- break;
- case M_ENH_B80x43: case M_ENH_C80x43:
- if (!(fonts_loaded & FONT_8)) {
- splx(s);
- return EINVAL;
- }
- scp->status |= UNKNOWN_MODE;
- scp->xsize = 80;
- scp->ysize = 43;
- scp->font_size = 8;
- break;
- case M_VGA_C80x30: case M_VGA_M80x30:
- scp->status |= UNKNOWN_MODE;
- scp->xsize = 80;
- scp->ysize = 30;
- scp->font_size = mp[2];
- break;
- case M_ENH_C40x25: case M_ENH_B40x25:
- case M_ENH_C80x25: case M_ENH_B80x25:
- case M_EGAMONO80x25:
- if (!(fonts_loaded & FONT_14)) {
- splx(s);
- return EINVAL;
- }
- /* FALL THROUGH */
- default:
- if ((cmd & 0xff) > M_VGA_CG320) {
- splx(s);
- return EINVAL;
- }
- scp->status |= UNKNOWN_MODE;
- scp->xsize = mp[0];
- scp->ysize = mp[1] + rows_offset;
- scp->font_size = mp[2];
- break;
- }
-
- scp->mode = cmd & 0xff;
- scp->xpixel = scp->xsize * 8;
- scp->ypixel = scp->ysize * scp->font_size;
- free(scp->scr_buf, M_DEVBUF);
- scp->scr_buf = (u_short *)
- malloc(scp->xsize*scp->ysize*sizeof(u_short), M_DEVBUF, M_WAITOK);
- /* move the text cursor to the home position */
- move_crsr(scp, 0, 0);
- /* move the mouse cursor at the center of the screen */
- scp->mouse_xpos = scp->xpixel / 2;
- scp->mouse_ypos = scp->ypixel / 2;
- scp->mouse_pos = scp->mouse_oldpos =
- scp->scr_buf + (scp->mouse_ypos / scp->font_size) * scp->xsize
- + scp->mouse_xpos / 8;
- /* allocate a larger cut buffer if necessary */
- if ((cut_buffer == NULL)
- || (cut_buffer_size < scp->xsize * scp->ysize + 1)) {
- if (cut_buffer != NULL)
- free(cut_buffer, M_DEVBUF);
- cut_buffer_size = scp->xsize * scp->ysize + 1;
- cut_buffer = (char *)malloc(cut_buffer_size, M_DEVBUF, M_NOWAIT);
- if (cut_buffer != NULL)
- cut_buffer[0] = '\0';
- }
- splx(s);
-
- usp = scp->history;
- scp->history = NULL;
- if (usp != NULL) {
- free(usp, M_DEVBUF);
- extra_history_size += i;
- }
- scp->history_size = imax(SC_HISTORY_SIZE, scp->ysize) * scp->xsize;
- usp = (u_short *)malloc(scp->history_size * sizeof(u_short),
- M_DEVBUF, M_NOWAIT);
- if (usp != NULL)
- bzero(usp, scp->history_size * sizeof(u_short));
- scp->history_head = scp->history_pos = usp;
- scp->history = usp;
- if (scp == cur_console)
- set_mode(scp);
- clear_screen(scp);
- scp->status &= ~UNKNOWN_MODE;
-
- if (tp->t_winsize.ws_col != scp->xsize
- || tp->t_winsize.ws_row != scp->ysize) {
- tp->t_winsize.ws_col = scp->xsize;
- tp->t_winsize.ws_row = scp->ysize;
- pgsignal(tp->t_pgrp, SIGWINCH, 1);
- }
- return 0;
-
- /* GRAPHICS MODES */
- case SW_BG320: case SW_BG640:
- case SW_CG320: case SW_CG320_D: case SW_CG640_E:
- case SW_CG640x350: case SW_ENH_CG640:
- case SW_BG640x480: case SW_CG640x480: case SW_VGA_CG320:
-
- if (crtc_type != KD_VGA)
- return ENODEV;
- mp = get_mode_param(scp, cmd & 0xff);
- if (mp == NULL)
- return ENODEV;
-
- s = spltty();
- if ((error = wait_scrn_saver_stop())) {
- splx(s);
- return error;
- }
-
- scp->status &= ~MOUSE_VISIBLE;
- remove_cutmarking(scp);
- scp->status |= UNKNOWN_MODE; /* graphics mode */
- scp->mode = cmd & 0xFF;
- scp->xpixel = mp[0] * 8;
- scp->ypixel = (mp[1] + rows_offset) * mp[2];
- scp->font_size = FONT_NONE;
- /* move the mouse cursor at the center of the screen */
- scp->mouse_xpos = scp->xpixel / 2;
- scp->mouse_ypos = scp->ypixel / 2;
- splx(s);
-
- if (scp == cur_console)
- set_mode(scp);
- /* clear_graphics();*/
-
- if (tp->t_winsize.ws_xpixel != scp->xpixel
- || tp->t_winsize.ws_ypixel != scp->ypixel) {
- tp->t_winsize.ws_xpixel = scp->xpixel;
- tp->t_winsize.ws_ypixel = scp->ypixel;
- pgsignal(tp->t_pgrp, SIGWINCH, 1);
- }
- return 0;
-
- case SW_VGA_MODEX:
- if (crtc_type != KD_VGA)
- return ENODEV;
- mp = get_mode_param(scp, cmd & 0xff);
- if (mp == NULL)
- return ENODEV;
-
- s = spltty();
- if ((error = wait_scrn_saver_stop())) {
- splx(s);
- return error;
- }
-
- scp->status &= ~MOUSE_VISIBLE;
- remove_cutmarking(scp);
- scp->status |= UNKNOWN_MODE; /* graphics mode */
- scp->mode = cmd & 0xFF;
- scp->xpixel = 320;
- scp->ypixel = 240;
- scp->font_size = FONT_NONE;
- splx(s);
-
- if (scp == cur_console)
- set_mode(scp);
- /* clear_graphics();*/
- if (tp->t_winsize.ws_xpixel != scp->xpixel
- || tp->t_winsize.ws_ypixel != scp->ypixel) {
- tp->t_winsize.ws_xpixel = scp->xpixel;
- tp->t_winsize.ws_ypixel = scp->ypixel;
- pgsignal(tp->t_pgrp, SIGWINCH, 1);
- }
- return 0;
-
case VT_SETMODE: /* set screen switcher mode */
{
struct vt_mode *mode;
@@ -1839,7 +1502,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return 0;
case VT_RELDISP: /* screen switcher ioctl */
- switch(*data) {
+ switch(*(int *)data) {
case VT_FALSE: /* user refuses to release screen, abort */
if (scp == old_scp && (scp->status & SWITCH_WAIT_REL)) {
old_scp->status &= ~SWITCH_WAIT_REL;
@@ -1879,32 +1542,32 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
for (i = 0; i < MAXCONS; i++) {
tp = VIRTUAL_TTY(i);
if (!(tp->t_state & TS_ISOPEN)) {
- *data = i + 1;
+ *(int *)data = i + 1;
return 0;
}
}
return EINVAL;
case VT_ACTIVATE: /* switch to screen *data */
- return switch_scr(scp, (*data) - 1);
+ return switch_scr(scp, *(int *)data - 1);
case VT_WAITACTIVE: /* wait for switch to occur */
- if (*data > MAXCONS || *data < 0)
+ if (*(int *)data > MAXCONS || *(int *)data < 0)
return EINVAL;
- if (minor(dev) == (*data) - 1)
+ if (minor(dev) == *(int *)data - 1)
return 0;
- if (*data == 0) {
+ if (*(int *)data == 0) {
if (scp == cur_console)
return 0;
}
else
- scp = console[(*data) - 1];
+ scp = console[*(int *)data - 1];
while ((error=tsleep((caddr_t)&scp->smode, PZERO|PCATCH,
"waitvt", 0)) == ERESTART) ;
return error;
case VT_GETACTIVE:
- *data = get_scr_num()+1;
+ *(int *)data = get_scr_num()+1;
return 0;
case KDENABIO: /* allow io operations */
@@ -1920,102 +1583,28 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
p->p_md.md_regs->tf_eflags &= ~PSL_IOPL;
return 0;
- case KDSETMODE: /* set current mode of this (virtual) console */
- switch (*data) {
- case KD_TEXT: /* switch to TEXT (known) mode */
- /* restore fonts & palette ! */
- if (crtc_type == KD_VGA) {
- if (!VESA_MODE(scp->mode)) {
-#if 0
- /*
- * FONT KLUDGE
- * Don't load fonts for now... XXX
- */
- if (fonts_loaded & FONT_8)
- copy_font(LOAD, FONT_8, font_8);
- if (fonts_loaded & FONT_14)
- copy_font(LOAD, FONT_14, font_14);
- if (fonts_loaded & FONT_16)
- copy_font(LOAD, FONT_16, font_16);
-#endif
- }
- load_palette(palette);
- }
-
- /* move hardware cursor out of the way */
- outb(crtc_addr, 14);
- outb(crtc_addr + 1, 0xff);
- outb(crtc_addr, 15);
- outb(crtc_addr + 1, 0xff);
-
- /* FALL THROUGH */
-
- case KD_TEXT1: /* switch to TEXT (known) mode */
- s = spltty();
- if ((error = wait_scrn_saver_stop())) {
- splx(s);
- return error;
- }
- scp->status &= ~MOUSE_VISIBLE;
- remove_cutmarking(scp);
- scp->status |= UNKNOWN_MODE;
- splx(s);
- /* no restore fonts & palette */
- if (crtc_type == KD_VGA)
- set_mode(scp);
- scp->status &= ~UNKNOWN_MODE;
- clear_screen(scp);
- return 0;
-
- case KD_GRAPHICS: /* switch to GRAPHICS (unknown) mode */
- s = spltty();
- if ((error = wait_scrn_saver_stop())) {
- splx(s);
- return error;
- }
- scp->status &= ~MOUSE_VISIBLE;
- remove_cutmarking(scp);
- scp->status |= UNKNOWN_MODE;
- splx(s);
- return 0;
- default:
+ case KDSKBSTATE: /* set keyboard state (locks) */
+ if (*(int *)data & ~LOCK_KEY_MASK)
return EINVAL;
- }
- /* NOT REACHED */
-
- case KDGETMODE: /* get current mode of this (virtual) console */
- *data = (scp->status & UNKNOWN_MODE) ? KD_GRAPHICS : KD_TEXT;
- return 0;
-
- case KDSBORDER: /* set border color of this (virtual) console */
- scp->border = *data;
+ scp->status &= ~LOCK_KEY_MASK;
+ scp->status |= *(int *)data;
if (scp == cur_console)
- set_border(scp->border);
+ update_leds(scp->status);
return 0;
- case KDSKBSTATE: /* set keyboard state (locks) */
- if (*data >= 0 && *data <= LOCK_KEY_MASK) {
- scp->status &= ~LOCK_KEY_MASK;
- scp->status |= *data;
- if (scp == cur_console)
- update_leds(scp->status);
- return 0;
- }
- return EINVAL;
-
case KDGKBSTATE: /* get keyboard state (locks) */
- *data = scp->status & LOCK_KEY_MASK;
+ *(int *)data = scp->status & LOCK_KEY_MASK;
return 0;
case KDSETRAD: /* set keyboard repeat & delay rates */
- if (*data & 0x80)
+ if (*(int *)data & ~0x7f)
return EINVAL;
if (sc_kbdc != NULL)
- set_keyboard(KBDC_SET_TYPEMATIC, *data);
+ set_keyboard(KBDC_SET_TYPEMATIC, *(int *)data);
return 0;
case KDSKBMODE: /* set keyboard mode */
- switch (*data) {
+ switch (*(int *)data) {
case K_RAW: /* switch to RAW scancode mode */
scp->status &= ~KBD_CODE_MODE;
scp->status |= KBD_RAW_MODE;
@@ -2037,7 +1626,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
/* NOT REACHED */
case KDGKBMODE: /* get keyboard mode */
- *data = (scp->status & KBD_RAW_MODE) ? K_RAW :
+ *(int *)data = (scp->status & KBD_RAW_MODE) ? K_RAW :
((scp->status & KBD_CODE_MODE) ? K_CODE : K_XLATE);
return 0;
@@ -2074,21 +1663,20 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return 0;
case KDGKBTYPE: /* get keyboard type */
- *data = 0; /* type not known (yet) */
+ *(int *)data = 0; /* type not known (yet) */
return 0;
case KDSETLED: /* set keyboard LED status */
- if (*data >= 0 && *data <= LED_MASK) {
- scp->status &= ~LED_MASK;
- scp->status |= *data;
- if (scp == cur_console)
- update_leds(scp->status);
- return 0;
- }
- return EINVAL;
+ if (*(int *)data & ~LED_MASK)
+ return EINVAL;
+ scp->status &= ~LED_MASK;
+ scp->status |= *(int *)data;
+ if (scp == cur_console)
+ update_leds(scp->status);
+ return 0;
case KDGETLED: /* get keyboard LED status */
- *data = scp->status & LED_MASK;
+ *(int *)data = scp->status & LED_MASK;
return 0;
case GETFKEY: /* get functionkey string */
@@ -2143,7 +1731,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return 0;
case PIO_FONT8x8: /* set 8x8 dot font */
- if (crtc_type != KD_VGA)
+ if (!ISFONTAVAIL(get_adapter(scp)->va_flags))
return ENXIO;
bcopy(data, font_8, 8*256);
fonts_loaded |= FONT_8;
@@ -2152,17 +1740,12 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
* Always use the font page #0. XXX
* Don't load if the current font size is not 8x8.
*/
- if (!VESA_MODE(cur_console->mode)
- && !(cur_console->status & UNKNOWN_MODE)
- && (cur_console->font_size < 14)) {
- copy_font(LOAD, FONT_8, font_8);
- if (flags & CHAR_CURSOR)
- set_destructive_cursor(cur_console);
- }
+ if (ISTEXTSC(cur_console) && (cur_console->font_size < 14))
+ copy_font(cur_console, LOAD, 8, font_8);
return 0;
case GIO_FONT8x8: /* get 8x8 dot font */
- if (crtc_type != KD_VGA)
+ if (!ISFONTAVAIL(get_adapter(scp)->va_flags))
return ENXIO;
if (fonts_loaded & FONT_8) {
bcopy(font_8, data, 8*256);
@@ -2172,7 +1755,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return ENXIO;
case PIO_FONT8x14: /* set 8x14 dot font */
- if (crtc_type != KD_VGA)
+ if (!ISFONTAVAIL(get_adapter(scp)->va_flags))
return ENXIO;
bcopy(data, font_14, 14*256);
fonts_loaded |= FONT_14;
@@ -2181,17 +1764,13 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
* Always use the font page #0. XXX
* Don't load if the current font size is not 8x14.
*/
- if (!VESA_MODE(cur_console->mode)
- && !(cur_console->status & UNKNOWN_MODE)
- && (cur_console->font_size >= 14) && (cur_console->font_size < 16)) {
- copy_font(LOAD, FONT_14, font_14);
- if (flags & CHAR_CURSOR)
- set_destructive_cursor(cur_console);
- }
+ if (ISTEXTSC(cur_console)
+ && (cur_console->font_size >= 14) && (cur_console->font_size < 16))
+ copy_font(cur_console, LOAD, 14, font_14);
return 0;
case GIO_FONT8x14: /* get 8x14 dot font */
- if (crtc_type != KD_VGA)
+ if (!ISFONTAVAIL(get_adapter(scp)->va_flags))
return ENXIO;
if (fonts_loaded & FONT_14) {
bcopy(font_14, data, 14*256);
@@ -2201,7 +1780,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return ENXIO;
case PIO_FONT8x16: /* set 8x16 dot font */
- if (crtc_type != KD_VGA)
+ if (!ISFONTAVAIL(get_adapter(scp)->va_flags))
return ENXIO;
bcopy(data, font_16, 16*256);
fonts_loaded |= FONT_16;
@@ -2210,17 +1789,12 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
* Always use the font page #0. XXX
* Don't load if the current font size is not 8x16.
*/
- if (!VESA_MODE(cur_console->mode)
- && !(cur_console->status & UNKNOWN_MODE)
- && (cur_console->font_size >= 16)) {
- copy_font(LOAD, FONT_16, font_16);
- if (flags & CHAR_CURSOR)
- set_destructive_cursor(cur_console);
- }
+ if (ISTEXTSC(cur_console) && (cur_console->font_size >= 16))
+ copy_font(cur_console, LOAD, 16, font_16);
return 0;
case GIO_FONT8x16: /* get 8x16 dot font */
- if (crtc_type != KD_VGA)
+ if (!ISFONTAVAIL(get_adapter(scp)->va_flags))
return ENXIO;
if (fonts_loaded & FONT_16) {
bcopy(font_16, data, 16*256);
@@ -2247,7 +1821,7 @@ scstart(struct tty *tp)
struct clist *rbp;
int s, len;
u_char buf[PCBURST];
- scr_stat *scp = get_scr_stat(tp->t_dev);
+ scr_stat *scp = sc_get_scr_stat(tp->t_dev);
if (scp->status & SLKED || blink_in_progress)
return; /* XXX who repeats the call when the above flags are cleared? */
@@ -2329,7 +1903,7 @@ sccnputc(dev_t dev, int c)
scp->term = kernel_console;
current_default = &kernel_default;
- if (scp == cur_console && !(scp->status & UNKNOWN_MODE))
+ if (scp == cur_console && !ISGRAPHSC(scp))
remove_cursor_image(scp);
buf[0] = c;
ansi_put(scp, buf, 1);
@@ -2384,25 +1958,28 @@ sccnupdate(scr_stat *scp)
if (font_loading_in_progress)
return;
- if (panicstr) {
+ if (panicstr || shutdown_in_progress) {
scsplash_stick(FALSE);
run_scrn_saver = FALSE;
+ } else if (scp != cur_console) {
+ return;
}
+
if (!run_scrn_saver)
scrn_idle = FALSE;
if ((saver_mode != CONS_LKM_SAVER) || !scrn_idle)
- if (scrn_blanked > 0)
+ if (scp->status & SAVER_RUNNING)
stop_scrn_saver(current_saver);
if (scp != cur_console || blink_in_progress || switch_in_progress)
return;
- if ((scp->status & UNKNOWN_MODE) == 0 && scrn_blanked <= 0)
+ if (!ISGRAPHSC(scp) && !(scp->status & SAVER_RUNNING))
scrn_update(scp, TRUE);
}
-static scr_stat
-*get_scr_stat(dev_t dev)
+scr_stat
+*sc_get_scr_stat(dev_t dev)
{
int unit = minor(dev);
@@ -2461,6 +2038,8 @@ scrn_timer(void *arg)
scintr(0);
}
+ scp = cur_console;
+
/* should we stop the screen saver? */
getmicrouptime(&tv);
if (panicstr || shutdown_in_progress) {
@@ -2476,7 +2055,7 @@ scrn_timer(void *arg)
run_scrn_saver = TRUE;
}
if ((saver_mode != CONS_LKM_SAVER) || !scrn_idle)
- if (scrn_blanked > 0)
+ if (scp->status & SAVER_RUNNING)
stop_scrn_saver(current_saver);
/* should we just return ? */
@@ -2488,14 +2067,13 @@ scrn_timer(void *arg)
}
/* Update the screen */
- scp = cur_console;
- if ((scp->status & UNKNOWN_MODE) == 0 && scrn_blanked <= 0)
+ if (!ISGRAPHSC(scp) && !(scp->status & SAVER_RUNNING))
scrn_update(scp, TRUE);
/* should we activate the screen saver? */
if ((saver_mode == CONS_LKM_SAVER) && scrn_idle)
- if ((scp->status & UNKNOWN_MODE) == 0 || scrn_blanked > 0)
- (*current_saver)(TRUE);
+ if (!ISGRAPHSC(scp) || (scp->status & SAVER_RUNNING))
+ scrn_saver(current_saver, TRUE);
if (arg)
timeout(scrn_timer, (void *)TRUE, hz / 25);
@@ -2583,9 +2161,9 @@ add_scrn_saver(void (*this_saver)(int))
if (current_saver != default_saver)
return EBUSY;
- current_saver = this_saver;
+ run_scrn_saver = FALSE;
saver_mode = CONS_LKM_SAVER;
- run_scrn_saver = (scrn_blank_time > 0);
+ current_saver = this_saver;
return 0;
}
@@ -2613,9 +2191,21 @@ remove_scrn_saver(void (*this_saver)(int))
}
static void
+scrn_saver(void (*saver)(int), int blank)
+{
+ static int busy = FALSE;
+
+ if (busy)
+ return;
+ busy = TRUE;
+ (*saver)(blank);
+ busy = FALSE;
+}
+
+static void
stop_scrn_saver(void (*saver)(int))
{
- (*saver)(FALSE);
+ scrn_saver(saver, FALSE);
run_scrn_saver = FALSE;
/* the screen saver may have chosen not to stop after all... */
if (scrn_blanked > 0)
@@ -2632,8 +2222,8 @@ wait_scrn_saver_stop(void)
{
int error = 0;
- run_scrn_saver = FALSE;
while (scrn_blanked > 0) {
+ run_scrn_saver = FALSE;
error = tsleep((caddr_t)&scrn_blanked, PZERO | PCATCH, "scrsav", 0);
run_scrn_saver = FALSE;
if (error != ERESTART)
@@ -2642,8 +2232,8 @@ wait_scrn_saver_stop(void)
return error;
}
-static void
-clear_screen(scr_stat *scp)
+void
+sc_clear_screen(scr_stat *scp)
{
move_crsr(scp, 0, 0);
scp->cursor_oldpos = scp->cursor_pos;
@@ -2668,8 +2258,7 @@ switch_scr(scr_stat *scp, u_int next_scr)
switch_in_progress = FALSE;
if (next_scr >= MAXCONS || switch_in_progress ||
- (cur_console->smode.mode == VT_AUTO
- && cur_console->status & UNKNOWN_MODE)) {
+ (cur_console->smode.mode == VT_AUTO && ISGRAPHSC(cur_console))) {
do_bell(scp, BELL_PITCH, BELL_DURATION);
return EINVAL;
}
@@ -2721,25 +2310,26 @@ exchange_scr(void)
{
move_crsr(old_scp, old_scp->xpos, old_scp->ypos);
cur_console = new_scp;
- if (old_scp->mode != new_scp->mode || (old_scp->status & UNKNOWN_MODE)){
- if (crtc_type == KD_VGA)
+ if (old_scp->mode != new_scp->mode || ISUNKNOWNSC(old_scp)) {
+ if (adp_flags & V_ADP_MODECHANGE)
set_mode(new_scp);
}
move_crsr(new_scp, new_scp->xpos, new_scp->ypos);
- if (!(new_scp->status & UNKNOWN_MODE) && (flags & CHAR_CURSOR))
+ if (ISTEXTSC(new_scp) && (flags & CHAR_CURSOR))
set_destructive_cursor(new_scp);
- if ((old_scp->status & UNKNOWN_MODE) && crtc_type == KD_VGA)
- load_palette(palette);
+ if (ISGRAPHSC(old_scp))
+ load_palette(new_scp, palette);
if (old_scp->status & KBD_RAW_MODE || new_scp->status & KBD_RAW_MODE ||
old_scp->status & KBD_CODE_MODE || new_scp->status & KBD_CODE_MODE)
shfts = ctls = alts = agrs = metas = accents = 0;
- set_border(new_scp->border);
+ set_border(new_scp, new_scp->border);
update_leds(new_scp->status);
delayed_next_scr = FALSE;
mark_all(new_scp);
- if (new_scp->mode == 0x102) {
- bzero(Crtat, 800*600/8);
- }
+
+ /* FIXME: the screen size may be larger than a 64K segment. */
+ if (ISPIXELSC(new_scp))
+ bzero(Crtat, new_scp->xpixel*new_scp->ypixel/8);
}
static void
@@ -2788,7 +2378,7 @@ scan_esc(scr_stat *scp, u_char c)
return;
#endif
case 'c': /* Clear screen & home */
- clear_screen(scp);
+ sc_clear_screen(scp);
break;
case '(': /* iso-2022: designate 94 character set to G0 */
@@ -2874,7 +2464,7 @@ scan_esc(scr_stat *scp, u_char c)
scp->cursor_pos,
scp->scr_buf + scp->xsize * scp->ysize - scp->cursor_pos);
mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
- mark_for_update(scp, scp->xsize * scp->ysize);
+ mark_for_update(scp, scp->xsize * scp->ysize - 1);
remove_cutmarking(scp);
break;
case 1: /* clear from beginning of display to cursor */
@@ -2936,7 +2526,7 @@ scan_esc(scr_stat *scp, u_char c)
fillw(scp->term.cur_color | scr_map[0x20], src,
n * scp->xsize);
mark_for_update(scp, scp->ypos * scp->xsize);
- mark_for_update(scp, scp->xsize * scp->ysize);
+ mark_for_update(scp, scp->xsize * scp->ysize - 1);
break;
case 'M': /* Delete n lines */
@@ -2951,7 +2541,7 @@ scan_esc(scr_stat *scp, u_char c)
fillw(scp->term.cur_color | scr_map[0x20], src,
n * scp->xsize);
mark_for_update(scp, scp->ypos * scp->xsize);
- mark_for_update(scp, scp->xsize * scp->ysize);
+ mark_for_update(scp, scp->xsize * scp->ysize - 1);
break;
case 'P': /* Delete n chars */
@@ -3192,7 +2782,7 @@ scan_esc(scr_stat *scp, u_char c)
if (scp->term.num_param == 1) {
scp->border=scp->term.param[0] & 0xff;
if (scp == cur_console)
- set_border(scp->border);
+ set_border(cur_console, scp->border);
}
break;
@@ -3209,8 +2799,8 @@ scan_esc(scr_stat *scp, u_char c)
flags |= BLINK_CURSOR;
else
flags &= ~BLINK_CURSOR;
- if ((scp->term.param[0] & 0x02) &&
- crtc_type == KD_VGA && !VESA_MODE(bios_video_mode))
+ if ((scp->term.param[0] & 0x02)
+ && ISFONTAVAIL(get_adapter(scp)->va_flags))
flags |= CHAR_CURSOR;
else
flags &= ~CHAR_CURSOR;
@@ -3223,9 +2813,9 @@ scan_esc(scr_stat *scp, u_char c)
* The cursor shape is global property; all virtual consoles
* are affected. Update the cursor in the current console...
*/
- if (!(cur_console->status & UNKNOWN_MODE)) {
+ if (!ISGRAPHSC(cur_console)) {
remove_cursor_image(cur_console);
- if (crtc_type == KD_VGA && (flags & CHAR_CURSOR))
+ if (flags & CHAR_CURSOR)
set_destructive_cursor(cur_console);
draw_cursor_image(cur_console);
}
@@ -3366,7 +2956,7 @@ outloop:
break;
case 0x0c: /* form feed, clears screen */
- clear_screen(scp);
+ sc_clear_screen(scp);
break;
case 0x0d: /* return, return to pos 0 */
@@ -3413,42 +3003,17 @@ outloop:
static void
scinit(void)
{
- u_int hw_cursor;
+ int col;
+ int row;
u_int i;
if (init_done != COLD)
return;
init_done = WARM;
- /*
- * Ensure a zero start address. This is mainly to recover after
- * switching from pcvt using userconfig(). The registers are w/o
- * for old hardware so it's too hard to relocate the active screen
- * memory.
- */
- outb(crtc_addr, 12);
- outb(crtc_addr + 1, 0);
- outb(crtc_addr, 13);
- outb(crtc_addr + 1, 0);
-
- /* extract cursor location */
- outb(crtc_addr, 14);
- hw_cursor = inb(crtc_addr + 1) << 8;
- outb(crtc_addr, 15);
- hw_cursor |= inb(crtc_addr + 1);
-
- /*
- * Validate cursor location. It may be off the screen. Then we must
- * not use it for the initial buffer offset.
- */
- if (hw_cursor >= ROW * COL)
- hw_cursor = (ROW - 1) * COL;
-
- /* move hardware cursor out of the way */
- outb(crtc_addr, 14);
- outb(crtc_addr + 1, 0xff);
- outb(crtc_addr, 15);
- outb(crtc_addr + 1, 0xff);
+ /* extract the hardware cursor location and move it out of the way */
+ (*biosvidsw.read_hw_cursor)(V_ADP_PRIMARY, &col, &row);
+ (*biosvidsw.set_hw_cursor)(V_ADP_PRIMARY, -1, -1);
/* set up the first console */
current_default = &user_default;
@@ -3456,51 +3021,22 @@ scinit(void)
init_scp(console[0]);
cur_console = console[0];
- /* discard the video mode table if we are not familiar with it... */
- if (video_mode_ptr) {
- bzero(mode_map, sizeof(mode_map));
- bcopy(video_mode_ptr + MODE_PARAM_SIZE*console[0]->mode,
- vgaregs2, sizeof(vgaregs2));
- switch (comp_vgaregs(vgaregs, video_mode_ptr
- + MODE_PARAM_SIZE*console[0]->mode)) {
- case COMP_IDENTICAL:
- map_mode_table(mode_map, video_mode_ptr, M_VGA_CG320 + 1);
- /*
- * This is a kludge for Toshiba DynaBook SS433 whose BIOS video
- * mode table entry has the actual # of rows at the offset 1;
- * BIOSes from other manufacturers store the # of rows - 1 there.
- * XXX
- */
- rows_offset = vgaregs[1] + 1
- - video_mode_ptr[MODE_PARAM_SIZE*console[0]->mode + 1];
- break;
- case COMP_SIMILAR:
- map_mode_table(mode_map, video_mode_ptr, M_VGA_CG320 + 1);
- mode_map[console[0]->mode] = vgaregs;
- rows_offset = vgaregs[1] + 1
- - video_mode_ptr[MODE_PARAM_SIZE*console[0]->mode + 1];
- vgaregs[1] -= rows_offset - 1;
- break;
- case COMP_DIFFERENT:
- default:
- video_mode_ptr = NULL;
- mode_map[console[0]->mode] = vgaregs;
- rows_offset = 1;
- break;
- }
- }
-
/* copy screen to temporary buffer */
- if (!VESA_MODE(console[0]->mode))
+ if (ISTEXTSC(console[0]))
generic_bcopy(Crtat, sc_buffer,
console[0]->xsize * console[0]->ysize * sizeof(u_short));
console[0]->scr_buf = console[0]->mouse_pos = console[0]->mouse_oldpos
= sc_buffer;
- console[0]->cursor_pos = console[0]->cursor_oldpos = sc_buffer + hw_cursor;
+ if (col >= console[0]->xsize)
+ col = 0;
+ if (row >= console[0]->ysize)
+ row = console[0]->ysize - 1;
+ console[0]->xpos = col;
+ console[0]->ypos = row;
+ console[0]->cursor_pos = console[0]->cursor_oldpos =
+ sc_buffer + row*console[0]->xsize + col;
console[0]->cursor_saveunder = *console[0]->cursor_pos;
- console[0]->xpos = hw_cursor % COL;
- console[0]->ypos = hw_cursor / COL;
for (i=1; i<MAXCONS; i++)
console[i] = NULL;
kernel_console.esc = 0;
@@ -3515,28 +3051,26 @@ scinit(void)
scr_map[i] = scr_rmap[i] = i;
}
- /* Save font and palette if VGA */
- if (crtc_type == KD_VGA) {
- if (!VESA_MODE(bios_video_mode)) {
- if (fonts_loaded & FONT_16) {
- copy_font(LOAD, FONT_16, font_16);
- } else {
- copy_font(SAVE, FONT_16, font_16);
- fonts_loaded = FONT_16;
- }
- set_destructive_cursor(console[0]);
+ /* Save font and palette */
+ if (ISFONTAVAIL(get_adapter(cur_console)->va_flags)) {
+ if (fonts_loaded & FONT_16) {
+ copy_font(cur_console, LOAD, 16, font_16);
+ } else {
+ copy_font(cur_console, SAVE, 16, font_16);
+ fonts_loaded = FONT_16;
+ set_destructive_cursor(cur_console);
}
- save_palette();
+ /*
+ * FONT KLUDGE
+ * Always use the font page #0. XXX
+ */
+ (*biosvidsw.show_font)(cur_console->adp, 0);
}
+ save_palette(cur_console, palette);
#ifdef SC_SPLASH_SCREEN
- /*
- * If not booting verbosely, put up the splash.
- * Note that the splash screen is not currently supported in
- * the VESA mode.
- */
- if (!(boothowto & RB_VERBOSE) && !VESA_MODE(bios_video_mode))
- scsplash_init();
+ /* put up the splash. */
+ scsplash_init(cur_console);
#endif
}
@@ -3551,52 +3085,79 @@ scshutdown(int howto, void *arg)
shutdown_in_progress = TRUE;
}
-static void
-map_mode_table(char *map[], char *table, int max)
+int
+sc_clean_up(scr_stat *scp)
{
- int i;
+ int error;
- for(i = 0; i < max; ++i)
- map[i] = table + i*MODE_PARAM_SIZE;
- for(; i < MODE_MAP_SIZE; ++i)
- map[i] = NULL;
+ if ((error = wait_scrn_saver_stop()))
+ return error;
+ scp->status &= ~MOUSE_VISIBLE;
+ remove_cutmarking(scp);
+ return 0;
}
-static int
-map_mode_num(int mode)
+void
+sc_alloc_scr_buffer(scr_stat *scp, int wait, int clear)
{
- static struct {
- int from;
- int to;
- } mode_map[] = {
- { M_ENH_B80x43, M_ENH_B80x25 },
- { M_ENH_C80x43, M_ENH_C80x25 },
- { M_VGA_M80x30, M_VGA_M80x25 },
- { M_VGA_C80x30, M_VGA_C80x25 },
- { M_VGA_M80x50, M_VGA_M80x25 },
- { M_VGA_C80x50, M_VGA_C80x25 },
- { M_VGA_M80x60, M_VGA_M80x25 },
- { M_VGA_C80x60, M_VGA_C80x25 },
- { M_VGA_MODEX, M_VGA_CG320 },
- };
- int i;
+ if (scp->scr_buf)
+ free(scp->scr_buf, M_DEVBUF);
+ scp->scr_buf = (u_short *)malloc(scp->xsize*scp->ysize*sizeof(u_short),
+ M_DEVBUF, (wait) ? M_WAITOK : M_NOWAIT);
- for (i = 0; i < sizeof(mode_map)/sizeof(mode_map[0]); ++i) {
- if (mode_map[i].from == mode)
- return mode_map[i].to;
+ if (clear) {
+ /* clear the screen and move the text cursor to the top-left position */
+ sc_clear_screen(scp);
+ } else {
+ /* retain the current cursor position, but adjust pointers */
+ move_crsr(scp, scp->xpos, scp->ypos);
+ scp->cursor_oldpos = scp->cursor_pos;
}
- return mode;
+
+ /* move the mouse cursor at the center of the screen */
+ sc_move_mouse(scp, scp->xpixel / 2, scp->ypixel / 2);
}
-static char
-*get_mode_param(scr_stat *scp, int mode)
+void
+sc_alloc_cut_buffer(scr_stat *scp, int wait)
{
- if (mode >= MODE_MAP_SIZE)
- mode = map_mode_num(mode);
- if (mode < MODE_MAP_SIZE)
- return mode_map[mode];
- else
- return NULL;
+ if ((cut_buffer == NULL)
+ || (cut_buffer_size < scp->xsize * scp->ysize + 1)) {
+ if (cut_buffer != NULL)
+ free(cut_buffer, M_DEVBUF);
+ cut_buffer_size = scp->xsize * scp->ysize + 1;
+ cut_buffer = (u_char *)malloc(cut_buffer_size,
+ M_DEVBUF, (wait) ? M_WAITOK : M_NOWAIT);
+ if (cut_buffer != NULL)
+ cut_buffer[0] = '\0';
+ }
+}
+
+void
+sc_alloc_history_buffer(scr_stat *scp, int lines, int extra, int wait)
+{
+ u_short *usp;
+
+ if (lines < scp->ysize)
+ lines = scp->ysize;
+
+ usp = scp->history;
+ scp->history = NULL;
+ if (usp != NULL) {
+ free(usp, M_DEVBUF);
+ if (extra > 0)
+ extra_history_size += extra;
+ }
+
+ scp->history_size = lines * scp->xsize;
+ if (lines > imax(sc_history_size, scp->ysize))
+ extra_history_size -= lines - imax(sc_history_size, scp->ysize);
+ usp = (u_short *)malloc(scp->history_size * sizeof(u_short),
+ M_DEVBUF, (wait) ? M_WAITOK : M_NOWAIT);
+ if (usp != NULL)
+ bzero(usp, scp->history_size * sizeof(u_short));
+ scp->history_head = scp->history_pos = usp;
+ scp->history = usp;
}
static scr_stat
@@ -3606,22 +3167,15 @@ static scr_stat
scp = (scr_stat *)malloc(sizeof(scr_stat), M_DEVBUF, M_WAITOK);
init_scp(scp);
- scp->scr_buf = scp->cursor_pos = scp->cursor_oldpos =
- (u_short *)malloc(scp->xsize*scp->ysize*sizeof(u_short),
- M_DEVBUF, M_WAITOK);
- scp->mouse_pos = scp->mouse_oldpos =
- scp->scr_buf + ((scp->mouse_ypos/scp->font_size)*scp->xsize +
- scp->mouse_xpos/8);
- scp->history_head = scp->history_pos =
- (u_short *)malloc(scp->history_size*sizeof(u_short),
- M_DEVBUF, M_WAITOK);
- bzero(scp->history_head, scp->history_size*sizeof(u_short));
- scp->history = scp->history_head;
+ sc_alloc_scr_buffer(scp, TRUE, TRUE);
+ if (ISMOUSEAVAIL(get_adapter(scp)->va_flags))
+ sc_alloc_cut_buffer(scp, TRUE);
+ sc_alloc_history_buffer(scp, sc_history_size, 0, TRUE);
/* SOS
- if (crtc_type == KD_VGA && video_mode_ptr)
+ if (get_adapter(scp)->va_flags & V_ADP_MODECHANGE)
set_mode(scp);
*/
- clear_screen(scp);
+ sc_clear_screen(scp);
scp->cursor_saveunder = *scp->cursor_pos;
return scp;
}
@@ -3629,43 +3183,29 @@ static scr_stat
static void
init_scp(scr_stat *scp)
{
- switch(crtc_type) {
- case KD_VGA:
- if (VESA_MODE(bios_video_mode))
- scp->mode = bios_video_mode;
- else if (crtc_addr == MONO_BASE)
- scp->mode = M_VGA_M80x25;
- else
- scp->mode = M_VGA_C80x25;
- scp->font_size = 16;
- break;
- case KD_CGA:
- if (crtc_addr == MONO_BASE)
- scp->mode = M_B80x25;
- else
- scp->mode = M_C80x25;
- scp->font_size = 8;
- break;
- case KD_EGA:
- if (crtc_addr == MONO_BASE)
- scp->mode = M_B80x25;
- else
- scp->mode = M_C80x25;
- scp->font_size = 14;
- break;
- case KD_MONO:
- case KD_HERCULES:
- default:
- scp->mode = M_EGAMONO80x25;
- scp->font_size = 14;
- break;
+ video_info_t info;
+
+ scp->adp = V_ADP_PRIMARY;
+ (*biosvidsw.get_info)(scp->adp, initial_video_mode, &info);
+
+ scp->status = 0;
+ scp->mode = scp->initial_mode = initial_video_mode;
+ scp->scr_buf = NULL;
+ if (info.vi_flags & V_INFO_GRAPHICS) {
+ scp->status |= GRAPHICS_MODE;
+ scp->xpixel = info.vi_width;
+ scp->ypixel = info.vi_height;
+ scp->xsize = info.vi_width/8;
+ scp->ysize = info.vi_height/info.vi_cheight;
+ scp->font_size = FONT_NONE;
+ } else {
+ scp->xsize = info.vi_width;
+ scp->ysize = info.vi_height;
+ scp->xpixel = scp->xsize*8;
+ scp->ypixel = scp->ysize*info.vi_cheight;
+ scp->font_size = info.vi_cheight;
}
- scp->initial_mode = scp->mode;
-
- scp->xsize = COL;
- scp->ysize = ROW;
- scp->xpixel = scp->xsize * 8;
- scp->ypixel = scp->ysize * scp->font_size;
+ scp->xoff = scp->yoff = 0;
scp->xpos = scp->ypos = 0;
scp->saved_xpos = scp->saved_ypos = -1;
scp->start = scp->xsize * scp->ysize;
@@ -3677,8 +3217,8 @@ init_scp(scr_stat *scp)
current_default->std_color;
scp->term.rev_color = current_default->rev_color;
scp->border = BG_BLACK;
- scp->cursor_start = *(char *)pa_to_va(0x461);
- scp->cursor_end = *(char *)pa_to_va(0x460);
+ scp->cursor_start = *(u_int8_t *)pa_to_va(0x461);
+ scp->cursor_end = *(u_int8_t *)pa_to_va(0x460);
scp->mouse_xpos = scp->xsize*8/2;
scp->mouse_ypos = scp->ysize*scp->font_size/2;
scp->mouse_cut_start = scp->mouse_cut_end = NULL;
@@ -3687,13 +3227,13 @@ init_scp(scr_stat *scp)
scp->mouse_proc = NULL;
scp->bell_pitch = BELL_PITCH;
scp->bell_duration = BELL_DURATION;
- scp->status = (*(char *)pa_to_va(0x417) & 0x20) ? NLKED : 0;
+ scp->status |= (*(u_int8_t *)pa_to_va(0x417) & 0x20) ? NLKED : 0;
scp->status |= CURSOR_ENABLED;
scp->pid = 0;
scp->proc = NULL;
scp->smode.mode = VT_AUTO;
scp->history_head = scp->history_pos = scp->history = NULL;
- scp->history_size = imax(SC_HISTORY_SIZE, scp->ysize) * scp->xsize;
+ scp->history_size = imax(sc_history_size, scp->ysize) * scp->xsize;
}
static u_char
@@ -4140,9 +3680,9 @@ next_code:
scsplash_stick(FALSE);
stop_scrn_saver(current_saver);
} else {
- if ((cur_console->status & UNKNOWN_MODE) == 0) {
+ if (!ISGRAPHSC(cur_console)) {
scsplash_stick(TRUE);
- (*current_saver)(TRUE);
+ scrn_saver(current_saver, TRUE);
}
}
}
@@ -4409,475 +3949,100 @@ update_leds(int which)
set_keyboard(KBDC_SET_LEDS, xlate_leds[which & LED_MASK]);
}
-void
+int
set_mode(scr_stat *scp)
{
- char special_modetable[MODE_PARAM_SIZE];
- char *mp;
- int s;
- int i;
+ video_info_t info;
+ video_adapter_t *adp;
- if (scp != cur_console)
- return;
+ /* reject unsupported mode */
+ if ((*biosvidsw.get_info)(scp->adp, scp->mode, &info))
+ return 1;
- /*
- * even if mode switching is disabled, we can change back
- * to the initial mode or the custom mode based on the initial
- * mode if we have saved register values upon start-up.
- */
- mp = get_mode_param(scp, scp->mode);
- if (mp == NULL)
- return;
- bcopy(mp, &special_modetable, sizeof(special_modetable));
+ /* if this vty is not currently showing, do nothing */
+ if (scp != cur_console)
+ return 0;
/* setup video hardware for the given mode */
- switch (scp->mode) {
- case M_VGA_C80x60: case M_VGA_M80x60:
- special_modetable[2] = 0x08;
- special_modetable[19] = 0x47;
- goto special_480l;
-
- case M_VGA_C80x30: case M_VGA_M80x30:
- special_modetable[19] = 0x4f;
-special_480l:
- special_modetable[9] |= 0xc0;
- special_modetable[16] = 0x08;
- special_modetable[17] = 0x3e;
- special_modetable[26] = 0xea;
- special_modetable[28] = 0xdf;
- special_modetable[31] = 0xe7;
- special_modetable[32] = 0x04;
- goto setup_mode;
-
- case M_ENH_C80x43: case M_ENH_B80x43:
- special_modetable[28] = 87;
- goto special_80x50;
-
- case M_VGA_C80x50: case M_VGA_M80x50:
-special_80x50:
- special_modetable[2] = 8;
- special_modetable[19] = 7;
- goto setup_mode;
-
- case M_VGA_C40x25: case M_VGA_C80x25:
- case M_VGA_M80x25:
- case M_B40x25: case M_C40x25:
- case M_B80x25: case M_C80x25:
- case M_ENH_B40x25: case M_ENH_C40x25:
- case M_ENH_B80x25: case M_ENH_C80x25:
- case M_EGAMONO80x25:
-
-setup_mode:
- set_vgaregs(special_modetable);
- scp->font_size = special_modetable[2];
-
- /* set font type (size) */
- if (scp->font_size < 14) {
- if (fonts_loaded & FONT_8)
- copy_font(LOAD, FONT_8, font_8);
- i = 0x0a; /* font 2 */
- } else if (scp->font_size >= 16) {
- if (fonts_loaded & FONT_16)
- copy_font(LOAD, FONT_16, font_16);
- i = 0x00; /* font 0 */
- } else {
- if (fonts_loaded & FONT_14)
- copy_font(LOAD, FONT_14, font_14);
- i = 0x05; /* font 1 */
+ adp = get_adapter(scp);
+ (*biosvidsw.set_mode)(scp->adp, scp->mode);
+ Crtat = (u_short *)adp->va_window;
+
+ if (!(scp->status & GRAPHICS_MODE)) {
+ /* load appropriate font */
+ if (!(scp->status & PIXEL_MODE)
+ && ISFONTAVAIL(get_adapter(scp)->va_flags)) {
+ if (scp->font_size < 14) {
+ if (fonts_loaded & FONT_8)
+ copy_font(scp, LOAD, 8, font_8);
+ } else if (scp->font_size >= 16) {
+ if (fonts_loaded & FONT_16)
+ copy_font(scp, LOAD, 16, font_16);
+ } else {
+ if (fonts_loaded & FONT_14)
+ copy_font(scp, LOAD, 14, font_14);
+ }
+ /*
+ * FONT KLUDGE:
+ * This is an interim kludge to display correct font.
+ * Always use the font page #0 on the video plane 2.
+ * Somehow we cannot show the font in other font pages on
+ * some video cards... XXX
+ */
+ (*biosvidsw.show_font)(scp->adp, 0);
}
- /*
- * FONT KLUDGE:
- * This is an interim kludge to display correct font.
- * Always use the font page #0 on the video plane 2.
- * Somehow we cannot show the font in other font pages on
- * some video cards... XXX
- */
- i = 0x00;
- s = splhigh();
- outb(TSIDX, 0x00); outb(TSREG, 0x01);
- outb(TSIDX, 0x03); outb(TSREG, i);
- outb(TSIDX, 0x00); outb(TSREG, 0x03);
- splx(s);
- if (flags & CHAR_CURSOR)
- set_destructive_cursor(scp);
mark_all(scp);
- break;
-
- case M_VGA_MODEX:
- /* "unchain" the VGA mode */
- special_modetable[5-1+0x04] &= 0xf7;
- special_modetable[5-1+0x04] |= 0x04;
- /* turn off doubleword mode */
- special_modetable[10+0x14] &= 0xbf;
- /* turn off word adressing */
- special_modetable[10+0x17] |= 0x40;
- /* set logical screen width */
- special_modetable[10+0x13] = 80;
- /* set 240 lines */
- special_modetable[10+0x11] = 0x2c;
- special_modetable[10+0x06] = 0x0d;
- special_modetable[10+0x07] = 0x3e;
- special_modetable[10+0x10] = 0xea;
- special_modetable[10+0x11] = 0xac;
- special_modetable[10+0x12] = 0xdf;
- special_modetable[10+0x15] = 0xe7;
- special_modetable[10+0x16] = 0x06;
- /* set vertical sync polarity to reflect aspect ratio */
- special_modetable[9] = 0xe3;
- goto setup_grmode;
-
- case M_BG320: case M_CG320: case M_BG640:
- case M_CG320_D: case M_CG640_E:
- case M_CG640x350: case M_ENH_CG640:
- case M_BG640x480: case M_CG640x480: case M_VGA_CG320:
-
-setup_grmode:
- set_vgaregs(special_modetable);
- scp->font_size = FONT_NONE;
- break;
-
- default:
- /* call user defined function XXX */
- break;
- }
-
- /* set border color for this (virtual) console */
- set_border(scp->border);
- return;
-}
-
-void
-set_border(u_char color)
-{
- switch (crtc_type) {
- case KD_EGA:
- case KD_VGA:
- inb(crtc_addr + 6); /* reset flip-flop */
- outb(ATC, 0x31); outb(ATC, color);
- break;
- case KD_CGA:
- outb(crtc_addr + 5, color & 0x0f); /* color select register */
- break;
- case KD_MONO:
- case KD_HERCULES:
- default:
- break;
}
-}
-
-static void
-set_vgaregs(char *modetable)
-{
- int i, s = splhigh();
-
- outb(TSIDX, 0x00); outb(TSREG, 0x01); /* stop sequencer */
- for (i=0; i<4; i++) { /* program sequencer */
- outb(TSIDX, i+1);
- outb(TSREG, modetable[i+5]);
- }
- outb(MISC, modetable[9]); /* set dot-clock */
- outb(TSIDX, 0x00); outb(TSREG, 0x03); /* start sequencer */
- outb(crtc_addr, 0x11);
- outb(crtc_addr+1, inb(crtc_addr+1) & 0x7F);
- for (i=0; i<25; i++) { /* program crtc */
- outb(crtc_addr, i);
- if (i == 14 || i == 15) /* no hardware cursor */
- outb(crtc_addr+1, 0xff);
- else
- outb(crtc_addr+1, modetable[i+10]);
- }
- inb(crtc_addr+6); /* reset flip-flop */
- for (i=0; i<20; i++) { /* program attribute ctrl */
- outb(ATC, i);
- outb(ATC, modetable[i+35]);
- }
- for (i=0; i<9; i++) { /* program graph data ctrl */
- outb(GDCIDX, i);
- outb(GDCREG, modetable[i+55]);
- }
- inb(crtc_addr+6); /* reset flip-flop */
- outb(ATC, 0x20); /* enable palette */
- splx(s);
-}
-
-static void
-read_vgaregs(char *buf)
-{
- int i, j;
- int s;
+ set_border(scp, scp->border);
- bzero(buf, MODE_PARAM_SIZE);
-
- s = splhigh();
-
- outb(TSIDX, 0x00); outb(TSREG, 0x01); /* stop sequencer */
- for (i=0, j=5; i<4; i++) {
- outb(TSIDX, i+1);
- buf[j++] = inb(TSREG);
- }
- buf[9] = inb(MISC + 10); /* dot-clock */
- outb(TSIDX, 0x00); outb(TSREG, 0x03); /* start sequencer */
-
- for (i=0, j=10; i<25; i++) { /* crtc */
- outb(crtc_addr, i);
- buf[j++] = inb(crtc_addr+1);
- }
- for (i=0, j=35; i<20; i++) { /* attribute ctrl */
- inb(crtc_addr+6); /* reset flip-flop */
- outb(ATC, i);
- buf[j++] = inb(ATC + 1);
- }
- for (i=0, j=55; i<9; i++) { /* graph data ctrl */
- outb(GDCIDX, i);
- buf[j++] = inb(GDCREG);
- }
- inb(crtc_addr+6); /* reset flip-flop */
- outb(ATC, 0x20); /* enable palette */
-
- buf[0] = *(char *)pa_to_va(0x44a); /* COLS */
- buf[1] = *(char *)pa_to_va(0x484); /* ROWS */
- buf[2] = *(char *)pa_to_va(0x485); /* POINTS */
- buf[3] = *(char *)pa_to_va(0x44c);
- buf[4] = *(char *)pa_to_va(0x44d);
-
- splx(s);
-}
-
-static int
-comp_vgaregs(u_char *buf1, u_char *buf2)
-{
- static struct {
- u_char mask;
- } params[MODE_PARAM_SIZE] = {
- 0xff, 0x00, 0xff, /* COLS, ROWS, POINTS */
- 0xff, 0xff, /* page length */
- 0xfe, 0xff, 0xff, 0xff, /* sequencer registers */
- 0xf3, /* misc register */
- 0xff, 0xff, 0xff, 0x7f, 0xff, /* CRTC */
- 0xff, 0xff, 0xff, 0x7f, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0x7f, 0xff, 0xff,
- 0x7f, 0xff, 0xff, 0xef, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, /* attribute controller registers */
- 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xf0,
- 0xff, 0xff, 0xff, 0xff, 0xff, /* GDC register */
- 0xff, 0xff, 0xff, 0xff,
- };
- int identical = TRUE;
- int i;
-
- for (i = 0; i < sizeof(params)/sizeof(params[0]); ++i) {
- if (params[i].mask == 0) /* don't care */
- continue;
- if ((buf1[i] & params[i].mask) != (buf2[i] & params[i].mask))
- return COMP_DIFFERENT;
- if (buf1[i] != buf2[i])
- identical = FALSE;
- }
- return (identical) ? COMP_IDENTICAL : COMP_SIMILAR;
-
-#if 0
- for(i = 0; i < 20; ++i) {
- if (*buf1++ != *buf2++)
- return COMP_DIFFERENT;
- }
- buf1 += 2; /* skip the cursor shape */
- buf2 += 2;
- for(i = 22; i < 24; ++i) {
- if (*buf1++ != *buf2++)
- return COMP_DIFFERENT;
- }
- buf1 += 2; /* skip the cursor position */
- buf2 += 2;
- for(i = 26; i < MODE_PARAM_SIZE; ++i) {
- if (*buf1++ != *buf2++)
- return COMP_DIFFERENT;
- }
- return COMP_IDENTICAL;
-#endif
-}
-
-static void
-dump_vgaregs(u_char *buf)
-{
- int i;
+ /* move hardware cursor out of the way */
+ (*biosvidsw.set_hw_cursor)(scp->adp, -1, -1);
- for(i = 0; i < MODE_PARAM_SIZE;) {
- printf("%02x ", buf[i]);
- if ((++i % 16) == 0)
- printf("\n");
- }
+ return 0;
}
-static void
-set_font_mode(u_char *buf)
+void
+copy_font(scr_stat *scp, int operation, int font_size, u_char *buf)
{
- int s = splhigh();
-
+ /*
+ * FONT KLUDGE:
+ * This is an interim kludge to display correct font.
+ * Always use the font page #0 on the video plane 2.
+ * Somehow we cannot show the font in other font pages on
+ * some video cards... XXX
+ */
font_loading_in_progress = TRUE;
-
- /* save register values */
- outb(TSIDX, 0x02); buf[0] = inb(TSREG);
- outb(TSIDX, 0x04); buf[1] = inb(TSREG);
- outb(GDCIDX, 0x04); buf[2] = inb(GDCREG);
- outb(GDCIDX, 0x05); buf[3] = inb(GDCREG);
- outb(GDCIDX, 0x06); buf[4] = inb(GDCREG);
- inb(crtc_addr + 6);
- outb(ATC, 0x10); buf[5] = inb(ATC + 1);
-
- /* setup vga for loading fonts */
- inb(crtc_addr+6); /* reset flip-flop */
- outb(ATC, 0x10); outb(ATC, buf[5] & ~0x01);
- inb(crtc_addr+6); /* reset flip-flop */
- outb(ATC, 0x20); /* enable palette */
-
-#if SLOW_VGA
-#ifndef SC_BAD_FLICKER
- outb(TSIDX, 0x00); outb(TSREG, 0x01);
-#endif
- outb(TSIDX, 0x02); outb(TSREG, 0x04);
- outb(TSIDX, 0x04); outb(TSREG, 0x07);
-#ifndef SC_BAD_FLICKER
- outb(TSIDX, 0x00); outb(TSREG, 0x03);
-#endif
- outb(GDCIDX, 0x04); outb(GDCREG, 0x02);
- outb(GDCIDX, 0x05); outb(GDCREG, 0x00);
- outb(GDCIDX, 0x06); outb(GDCREG, 0x04);
-#else
-#ifndef SC_BAD_FLICKER
- outw(TSIDX, 0x0100);
-#endif
- outw(TSIDX, 0x0402);
- outw(TSIDX, 0x0704);
-#ifndef SC_BAD_FLICKER
- outw(TSIDX, 0x0300);
-#endif
- outw(GDCIDX, 0x0204);
- outw(GDCIDX, 0x0005);
- outw(GDCIDX, 0x0406); /* addr = a0000, 64kb */
-#endif
- splx(s);
-}
-
-static void
-set_normal_mode(u_char *buf)
-{
- char *modetable;
- int s = splhigh();
-
- /* setup vga for normal operation mode again */
- inb(crtc_addr+6); /* reset flip-flop */
- outb(ATC, 0x10); outb(ATC, buf[5]);
- inb(crtc_addr+6); /* reset flip-flop */
- outb(ATC, 0x20); /* enable palette */
-
-#if SLOW_VGA
-#ifndef SC_BAD_FLICKER
- outb(TSIDX, 0x00); outb(TSREG, 0x01);
-#endif
- outb(TSIDX, 0x02); outb(TSREG, buf[0]);
- outb(TSIDX, 0x04); outb(TSREG, buf[1]);
-#ifndef SC_BAD_FLICKER
- outb(TSIDX, 0x00); outb(TSREG, 0x03);
-#endif
- outb(GDCIDX, 0x04); outb(GDCREG, buf[2]);
- outb(GDCIDX, 0x05); outb(GDCREG, buf[3]);
- if (crtc_addr == MONO_BASE) {
- outb(GDCIDX, 0x06); outb(GDCREG,(buf[4] & 0x03) | 0x08);
- } else {
- outb(GDCIDX, 0x06); outb(GDCREG,(buf[4] & 0x03) | 0x0c);
+ if (operation == LOAD) {
+ (*biosvidsw.load_font)(scp->adp, 0, font_size, buf, 0, 256);
+ if (flags & CHAR_CURSOR)
+ set_destructive_cursor(scp);
+ } else if (operation == SAVE) {
+ (*biosvidsw.save_font)(scp->adp, 0, font_size, buf, 0, 256);
}
-#else
-#ifndef SC_BAD_FLICKER
- outw(TSIDX, 0x0100);
-#endif
- outw(TSIDX, 0x0002 | (buf[0] << 8));
- outw(TSIDX, 0x0004 | (buf[1] << 8));
-#ifndef SC_BAD_FLICKER
- outw(TSIDX, 0x0300);
-#endif
- outw(GDCIDX, 0x0004 | (buf[2] << 8));
- outw(GDCIDX, 0x0005 | (buf[3] << 8));
- if (crtc_addr == MONO_BASE)
- outw(GDCIDX, 0x0006 | (((buf[4] & 0x03) | 0x08)<<8));
- else
- outw(GDCIDX, 0x0006 | (((buf[4] & 0x03) | 0x0c)<<8));
-#endif
-
font_loading_in_progress = FALSE;
- splx(s);
-}
-
-void
-copy_font(int operation, int font_type, char* font_image)
-{
- int ch, line, segment, fontsize;
- u_char buf[PARAM_BUFSIZE];
- u_char val;
-
- switch (font_type) {
- default:
- case FONT_8:
- segment = 0x8000;
- fontsize = 8;
- break;
- case FONT_14:
- segment = 0x4000;
- fontsize = 14;
- break;
- case FONT_16:
- segment = 0x0000;
- fontsize = 16;
- break;
- }
- /*
- * FONT KLUDGE
- * Always use the font page #0. XXX
- */
- segment = 0x0000;
- outb(TSIDX, 0x01); val = inb(TSREG); /* disable screen */
- outb(TSIDX, 0x01); outb(TSREG, val | 0x20);
- set_font_mode(buf);
- for (ch=0; ch < 256; ch++)
- for (line=0; line < fontsize; line++)
- if (operation)
- *(char *)pa_to_va(VIDEOMEM+(segment)+(ch*32)+line) =
- font_image[(ch*fontsize)+line];
- else
- font_image[(ch*fontsize)+line] =
- *(char *)pa_to_va(VIDEOMEM+(segment)+(ch*32)+line);
- set_normal_mode(buf);
- outb(TSIDX, 0x01); outb(TSREG, val & 0xDF); /* enable screen */
}
static void
set_destructive_cursor(scr_stat *scp)
{
- u_char buf[PARAM_BUFSIZE];
u_char cursor[32];
- caddr_t address;
+ u_char *font_buffer;
+ int font_size;
int i;
- char *font_buffer;
+
+ if (!ISFONTAVAIL(get_adapter(scp)->va_flags) || !ISTEXTSC(scp))
+ return;
if (scp->font_size < 14) {
font_buffer = font_8;
- address = (caddr_t)VIDEOMEM + 0x8000;
- }
- else if (scp->font_size >= 16) {
+ font_size = 8;
+ } else if (scp->font_size >= 16) {
font_buffer = font_16;
- address = (caddr_t)VIDEOMEM;
- }
- else {
+ font_size = 16;
+ } else {
font_buffer = font_14;
- address = (caddr_t)VIDEOMEM + 0x4000;
+ font_size = 14;
}
- /*
- * FONT KLUDGE
- * Always use the font page #0. XXX
- */
- address = (caddr_t)VIDEOMEM;
if (scp->status & MOUSE_VISIBLE) {
if ((scp->cursor_saveunder & 0xff) == SC_MOUSE_CHAR)
@@ -4902,9 +4067,18 @@ set_destructive_cursor(scr_stat *scp)
#if 1
while (!(inb(crtc_addr+6) & 0x08)) /* wait for vertical retrace */ ;
#endif
- set_font_mode(buf);
- generic_bcopy(cursor, (char *)pa_to_va(address) + DEAD_CHAR * 32, 32);
- set_normal_mode(buf);
+ font_loading_in_progress = TRUE;
+ (*biosvidsw.load_font)(scp->adp, 0, font_size, cursor, DEAD_CHAR, 1);
+ font_loading_in_progress = FALSE;
+}
+
+void
+sc_move_mouse(scr_stat *scp, int x, int y)
+{
+ scp->mouse_xpos = x;
+ scp->mouse_ypos = y;
+ scp->mouse_pos = scp->mouse_oldpos =
+ scp->scr_buf + (y / scp->font_size) * scp->xsize + x / 8;
}
static void
@@ -4916,7 +4090,7 @@ set_mouse_pos(scr_stat *scp)
scp->mouse_xpos = 0;
if (scp->mouse_ypos < 0)
scp->mouse_ypos = 0;
- if (scp->status & UNKNOWN_MODE) {
+ if (!ISTEXTSC(scp)) {
if (scp->mouse_xpos > scp->xpixel-1)
scp->mouse_xpos = scp->xpixel-1;
if (scp->mouse_ypos > scp->ypixel-1)
@@ -5146,35 +4320,26 @@ mouse_paste(scr_stat *scp)
static void
draw_mouse_image(scr_stat *scp)
{
- caddr_t address;
- int i;
- char *font_buffer;
- u_char buf[PARAM_BUFSIZE];
u_short buffer[32];
u_short xoffset, yoffset;
u_short *crt_pos = Crtat + (scp->mouse_pos - scp->scr_buf);
- int font_size = scp->font_size;
+ u_char *font_buffer;
+ int font_size;
+ int i;
- if (font_size < 14) {
+ if (scp->font_size < 14) {
font_buffer = font_8;
- address = (caddr_t)VIDEOMEM + 0x8000;
- }
- else if (font_size >= 16) {
+ font_size = 8;
+ } else if (scp->font_size >= 16) {
font_buffer = font_16;
- address = (caddr_t)VIDEOMEM;
- }
- else {
+ font_size = 16;
+ } else {
font_buffer = font_14;
- address = (caddr_t)VIDEOMEM + 0x4000;
+ font_size = 14;
}
- /*
- * FONT KLUDGE
- * Always use the font page #0. XXX
- */
- address = (caddr_t)VIDEOMEM;
xoffset = scp->mouse_xpos % 8;
- yoffset = scp->mouse_ypos % font_size;
+ yoffset = scp->mouse_ypos % scp->font_size;
/* prepare mousepointer char's bitmaps */
bcopy(font_buffer + ((*(scp->mouse_pos) & 0xff) * font_size),
@@ -5209,9 +4374,11 @@ draw_mouse_image(scr_stat *scp)
/* wait for vertical retrace to avoid jitter on some videocards */
while (!(inb(crtc_addr+6) & 0x08)) /* idle */ ;
#endif
- set_font_mode(buf);
- generic_bcopy(scp->mouse_cursor, (char *)pa_to_va(address) + SC_MOUSE_CHAR * 32, 128);
- set_normal_mode(buf);
+ font_loading_in_progress = TRUE;
+ (*biosvidsw.load_font)(scp->adp, 0, 32, scp->mouse_cursor,
+ SC_MOUSE_CHAR, 4);
+ font_loading_in_progress = FALSE;
+
*(crt_pos) = (*(scp->mouse_pos) & 0xff00) | SC_MOUSE_CHAR;
*(crt_pos+scp->xsize) =
(*(scp->mouse_pos + scp->xsize) & 0xff00) | (SC_MOUSE_CHAR + 2);
@@ -5229,6 +4396,8 @@ remove_mouse_image(scr_stat *scp)
{
u_short *crt_pos = Crtat + (scp->mouse_oldpos - scp->scr_buf);
+ if (!ISTEXTSC(scp))
+ return;
*(crt_pos) = *(scp->mouse_oldpos);
*(crt_pos+1) = *(scp->mouse_oldpos+1);
*(crt_pos+scp->xsize) = *(scp->mouse_oldpos+scp->xsize);
@@ -5279,30 +4448,6 @@ remove_cutmarking(scr_stat *scp)
}
static void
-save_palette(void)
-{
- int i;
-
- outb(PALRADR, 0x00);
- for (i=0x00; i<0x300; i++)
- palette[i] = inb(PALDATA);
- inb(crtc_addr+6); /* reset flip/flop */
-}
-
-void
-load_palette(char *palette)
-{
- int i;
-
- outb(PIXMASK, 0xFF); /* no pixelmask */
- outb(PALWADR, 0x00);
- for (i=0x00; i<0x300; i++)
- outb(PALDATA, palette[i]);
- inb(crtc_addr+6); /* reset flip/flop */
- outb(ATC, 0x20); /* enable palette */
-}
-
-static void
do_bell(scr_stat *scp, int pitch, int duration)
{
if (cold || shutdown_in_progress)
@@ -5330,7 +4475,7 @@ blink_screen(void *arg)
{
scr_stat *scp = arg;
- if ((scp->status & UNKNOWN_MODE) || (blink_in_progress <= 1)) {
+ if (!ISTEXTSC(scp) || (blink_in_progress <= 1)) {
blink_in_progress = FALSE;
mark_all(scp);
if (delayed_next_scr)
@@ -5351,25 +4496,41 @@ blink_screen(void *arg)
void
sc_bcopy(scr_stat *scp, u_short *p, int from, int to, int mark)
{
- if (!VESA_MODE(scp->mode)) {
- generic_bcopy(p+from, Crtat+from, (to-from+1)*sizeof (u_short));
- } else if (scp->mode == 0x102) {
- u_char *d, *e;
- int i,j;
+ u_char *font;
+ u_char *d, *e;
+ u_char *f;
+ int font_size;
+ int line_length;
+ int xsize;
+ int i, j;
+ if (ISTEXTSC(scp)) {
+ generic_bcopy(p+from, Crtat+from, (to-from+1)*sizeof (u_short));
+ } else /* if ISPIXELSC(scp) */ {
if (mark)
- mark = 255;
- d = (u_char *)Crtat;
- d += 10 + 6*16*100 + (from%80) + 16*100*(from/80);
+ mark = 255;
+ font_size = scp->font_size;
+ if (font_size < 14)
+ font = font_8;
+ else if (font_size >= 16)
+ font = font_16;
+ else
+ font = font_14;
+ line_length = scp->xpixel/8;
+ xsize = scp->xsize;
+ d = (u_char *)Crtat
+ + scp->xoff + scp->yoff*font_size*line_length
+ + (from%xsize) + font_size*line_length*(from/xsize);
for (i = from ; i <= to ; i++) {
e = d;
- for (j = 0 ; j < 16; j++) {
- *e = mark^font_16[(p[i]&0xff)*16+j];
- e+=100;
+ f = &font[(p[i] & 0x00ff)*font_size];
+ for (j = 0 ; j < font_size; j++, f++) {
+ *e = mark^*f;
+ e += line_length;
}
d++;
- if ((i % 80) == 79)
- d += 20 + 15*100;
+ if ((i % xsize) == xsize - 1)
+ d += scp->xoff*2 + (font_size - 1)*line_length;
}
}
}
@@ -5377,34 +4538,36 @@ sc_bcopy(scr_stat *scp, u_short *p, int from, int to, int mark)
#ifdef SC_SPLASH_SCREEN
static void
-scsplash_init(void)
+scsplash_init(scr_stat *scp)
{
+ video_info_t info;
+
/*
* We currently assume the splash screen always use
* VGA_CG320 mode and abort installation if this mode is not
* supported with this video card. XXX
*/
- if (crtc_type != KD_VGA || get_mode_param(cur_console, M_VGA_CG320) == NULL)
+ if ((*biosvidsw.get_info)(scp->adp, M_VGA_CG320, &info))
return;
- if (splash_load() == 0 && add_scrn_saver(scsplash) == 0) {
- default_saver = scsplash;
+ if (scsplash_load(scp) == 0 && add_scrn_saver(scsplash_saver) == 0) {
+ default_saver = scsplash_saver;
scrn_blank_time = DEFAULT_BLANKTIME;
run_scrn_saver = TRUE;
- if (!(boothowto & RB_CONFIG)) {
+ if (!(boothowto & (RB_VERBOSE | RB_CONFIG))) {
scsplash_stick(TRUE);
- scsplash(TRUE);
+ scsplash_saver(TRUE);
}
}
}
static void
-scsplash(int show)
+scsplash_saver(int show)
{
if (show)
- splash(TRUE);
+ scsplash(TRUE);
else if (!sticky_splash)
- splash(FALSE);
+ scsplash(FALSE);
}
#endif /* SC_SPLASH_SCREEN */
diff --git a/sys/dev/syscons/syscons.h b/sys/dev/syscons/syscons.h
index b23a2ae..315946b 100644
--- a/sys/dev/syscons/syscons.h
+++ b/sys/dev/syscons/syscons.h
@@ -1,18 +1,18 @@
/*-
- * Copyright (c) 1995-1997 Søren Schmidt
+ * Copyright (c) 1995-1998 Søren Schmidt
* 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
- * in this position and unchanged.
+ * notice, this list of conditions and the following disclaimer,
+ * without modification, immediately at the beginning of the file.
* 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. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission
+ * derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: syscons.h,v 1.38 1998/08/03 09:09:35 yokota Exp $
+ * $Id$
*/
#ifndef _I386_ISA_SYSCONS_H_
@@ -65,6 +65,9 @@
#define MOUSE_MOVED 0x01000
#define MOUSE_CUTTING 0x02000
#define MOUSE_VISIBLE 0x04000
+#define GRAPHICS_MODE 0x08000
+#define PIXEL_MODE 0x10000
+#define SAVER_RUNNING 0x20000
/* configuration flags */
#define VISUAL_BELL 0x00001
@@ -74,6 +77,7 @@
#define XT_KEYBD 0x00010
#define KBD_NORESET 0x00020
#define QUIET_BELL 0x00040
+#define VESA800X600 0x00080
/* attribute flags */
#define NORMAL_ATTR 0x00
@@ -84,9 +88,6 @@
#define FOREGROUND_CHANGED 0x10
#define BACKGROUND_CHANGED 0x20
-/* video hardware memory addresses */
-#define VIDEOMEM 0x000A0000
-
/* misc defines */
#define FALSE 0
#define TRUE 1
@@ -104,20 +105,6 @@
#define FONT_14 4
#define FONT_16 8
-/* defines related to hardware addresses */
-#define MONO_BASE 0x3B4 /* crt controller base mono */
-#define COLOR_BASE 0x3D4 /* crt controller base color */
-#define MISC 0x3C2 /* misc output register */
-#define ATC IO_VGA+0x00 /* attribute controller */
-#define TSIDX IO_VGA+0x04 /* timing sequencer idx */
-#define TSREG IO_VGA+0x05 /* timing sequencer data */
-#define PIXMASK IO_VGA+0x06 /* pixel write mask */
-#define PALRADR IO_VGA+0x07 /* palette read address */
-#define PALWADR IO_VGA+0x08 /* palette write address */
-#define PALDATA IO_VGA+0x09 /* palette data register */
-#define GDCIDX IO_VGA+0x0E /* graph data controller idx */
-#define GDCREG IO_VGA+0x0F /* graph data controller data */
-
/* special characters */
#define cntlc 0x03
#define cntld 0x04
@@ -141,6 +128,7 @@ typedef struct term_stat {
} term_stat;
typedef struct scr_stat {
+ int adp; /* video adapter index */
u_short *scr_buf; /* buffer when off screen */
int xpos; /* current X position */
int ypos; /* current Y position */
@@ -150,6 +138,8 @@ typedef struct scr_stat {
int ysize; /* Y text size */
int xpixel; /* X graphics size */
int ypixel; /* Y graphics size */
+ int xoff; /* X offset in pixel mode */
+ int yoff; /* Y offset in pixel mode */
int font_size; /* fontsize in Y direction */
int start; /* modified area start */
int end; /* modified area end */
@@ -186,7 +176,8 @@ typedef struct scr_stat {
int history_size; /* size of history buffer */
struct apmhook r_hook; /* reconfiguration support */
#ifdef SC_SPLASH_SCREEN
- u_char splash_save_mode; /* saved mode for splash screen */
+ int splash_save_mode; /* saved mode for splash screen */
+ int splash_save_status; /* saved status for splash screen */
#endif
} scr_stat;
@@ -195,18 +186,59 @@ typedef struct default_attr {
int rev_color; /* reverse hardware color */
} default_attr;
+
+#define ISTEXTSC(scp) (!((scp)->status \
+ & (UNKNOWN_MODE | GRAPHICS_MODE | PIXEL_MODE)))
+#define ISGRAPHSC(scp) (((scp)->status \
+ & (UNKNOWN_MODE | GRAPHICS_MODE)))
+#define ISPIXELSC(scp) (((scp)->status \
+ & (UNKNOWN_MODE | GRAPHICS_MODE | PIXEL_MODE))\
+ == PIXEL_MODE)
+#define ISUNKNOWNSC(scp) ((scp)->status & UNKNOWN_MODE)
+
+#define ISFONTAVAIL(af) ((af) & V_ADP_FONT)
+#define ISMOUSEAVAIL(af) ((af) & V_ADP_FONT)
+#define ISPALAVAIL(af) ((af) & V_ADP_PALETTE)
+
/* misc prototypes used by different syscons related LKM's */
-void set_border(u_char color);
-void set_mode(scr_stat *scp);
-void copy_font(int operation, int font_type, char* font_image);
-void load_palette(char *palette);
+
+/* syscons.c */
+extern int (*sc_user_ioctl)(dev_t dev, int cmd, caddr_t data, int flag,
+ struct proc *p);
+
+int set_mode(scr_stat *scp);
+scr_stat *sc_get_scr_stat(dev_t dev);
+
+void copy_font(scr_stat *scp, int operation, int font_size, u_char *font_image);
+#define save_palette(scp, pal) (*biosvidsw.save_palette)((scp)->adp, pal)
+#define load_palette(scp, pal) (*biosvidsw.load_palette)((scp)->adp, pal)
+#define set_border(scp, col) (*biosvidsw.set_border)((scp)->adp, col)
+#define get_adapter(scp) (*biosvidsw.adapter)((scp)->adp)
+
int add_scrn_saver(void (*this)(int));
int remove_scrn_saver(void (*this)(int));
+void sc_clear_screen(scr_stat *scp);
+void sc_move_mouse(scr_stat *scp, int x, int y);
+int sc_clean_up(scr_stat *scp);
+void sc_alloc_scr_buffer(scr_stat *scp, int wait, int clear);
+void sc_alloc_cut_buffer(scr_stat *scp, int wait);
+void sc_alloc_history_buffer(scr_stat *scp, int lines, int extra, int wait);
+
+/* scvidctl.c */
+int sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode,
+ int xsize, int ysize, int fontsize);
+int sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode);
+int sc_set_pixel_mode(scr_stat *scp, struct tty *tp,
+ int xsize, int ysize, int fontsize);
+int sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag,
+ struct proc *p);
+
#ifdef SC_SPLASH_SCREEN
-void splash(int);
-int splash_load(void);
-int splash_unload(void);
+/* splash.c */
+void scsplash(int);
+int scsplash_load(scr_stat *scp);
+int scsplash_unload(scr_stat *scp);
#endif
#endif /* !_I386_ISA_SYSCONS_H_ */
diff --git a/sys/i386/conf/LINT b/sys/i386/conf/LINT
index 2d8c4a8..8b20f86 100644
--- a/sys/i386/conf/LINT
+++ b/sys/i386/conf/LINT
@@ -2,7 +2,7 @@
# LINT -- config file for checking all the sources, tries to pull in
# as much of the source tree as it can.
#
-# $Id: LINT,v 1.464 1998/09/15 10:01:13 gibbs Exp $
+# $Id: LINT,v 1.465 1998/09/15 11:44:43 phk Exp $
#
# NB: You probably don't want to try running a kernel built from this
# file. Instead, you should start from GENERIC, and add options from
@@ -803,6 +803,9 @@ options SC_HISTORY_SIZE=200 # number of history buffer lines
options SC_DISABLE_REBOOT # disable reboot key sequence
# If the screen flickers badly when the mouse pointer is moved, try this.
options SC_BAD_FLICKER
+# To include support for VESA video modes
+# Dont use together with SMP!!
+options VESA # needs VM86 defined too!!
#
# `flags' for sc0:
diff --git a/sys/i386/conf/NOTES b/sys/i386/conf/NOTES
index 2d8c4a8..8b20f86 100644
--- a/sys/i386/conf/NOTES
+++ b/sys/i386/conf/NOTES
@@ -2,7 +2,7 @@
# LINT -- config file for checking all the sources, tries to pull in
# as much of the source tree as it can.
#
-# $Id: LINT,v 1.464 1998/09/15 10:01:13 gibbs Exp $
+# $Id: LINT,v 1.465 1998/09/15 11:44:43 phk Exp $
#
# NB: You probably don't want to try running a kernel built from this
# file. Instead, you should start from GENERIC, and add options from
@@ -803,6 +803,9 @@ options SC_HISTORY_SIZE=200 # number of history buffer lines
options SC_DISABLE_REBOOT # disable reboot key sequence
# If the screen flickers badly when the mouse pointer is moved, try this.
options SC_BAD_FLICKER
+# To include support for VESA video modes
+# Dont use together with SMP!!
+options VESA # needs VM86 defined too!!
#
# `flags' for sc0:
diff --git a/sys/i386/conf/files.i386 b/sys/i386/conf/files.i386
index 5302df4..6a08470 100644
--- a/sys/i386/conf/files.i386
+++ b/sys/i386/conf/files.i386
@@ -1,7 +1,7 @@
# This file tells config what files go into building a kernel,
# files marked standard are always included.
#
-# $Id: files.i386,v 1.202 1998/09/08 20:57:46 sos Exp $
+# $Id: files.i386,v 1.203 1998/09/15 10:01:13 gibbs Exp $
#
# The long compile-with and dependency lines are required because of
# limitations in config: backslash-newline doesn't work in strings, and
@@ -240,6 +240,10 @@ i386/isa/spigot.c optional spigot device-driver
i386/isa/spkr.c optional speaker device-driver
i386/isa/stallion.c optional stl device-driver
i386/isa/syscons.c optional sc device-driver
+i386/isa/scvidctl.c optional sc device-driver
+i386/isa/scvesactl.c optional sc device-driver
+i386/isa/videoio.c optional sc device-driver
+i386/isa/vesa.c optional sc device-driver
i386/isa/tw.c optional tw device-driver
#i386/isa/ultra14f.c optional uha device-driver
i386/isa/wd.c optional wdc device-driver
diff --git a/sys/i386/conf/options.i386 b/sys/i386/conf/options.i386
index c07d086..21c4598 100644
--- a/sys/i386/conf/options.i386
+++ b/sys/i386/conf/options.i386
@@ -1,4 +1,4 @@
-# $Id: options.i386,v 1.85 1998/09/08 18:09:50 brian Exp $
+# $Id: options.i386,v 1.86 1998/09/15 10:01:14 gibbs Exp $
BOUNCEPAGES opt_bounce.h
DISABLE_PSE
@@ -77,6 +77,8 @@ SC_DISABLE_REBOOT opt_syscons.h
SC_MOUSE_CHAR opt_syscons.h
SC_BAD_FLICKER opt_syscons.h
+VESA opt_vesa.h
+
PSM_HOOKAPM opt_psm.h
PSM_RESETAFTERSUSPEND opt_psm.h
PSM_DEBUG opt_psm.h
diff --git a/sys/i386/include/console.h b/sys/i386/include/console.h
index 7503746..3373e60 100644
--- a/sys/i386/include/console.h
+++ b/sys/i386/include/console.h
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: console.h,v 1.37 1998/07/06 06:29:06 imp Exp $
+ * $Id: console.h,v 1.38 1998/08/03 11:30:28 yokota Exp $
*/
#ifndef _MACHINE_CONSOLE_H_
@@ -51,6 +51,7 @@
#define KDGETLED _IOR('K', 65, int)
#define KDSETLED _IO('K', 66 /*, int */)
#define KDSETRAD _IO('K', 67 /*, int */)
+#define KDRASTER _IOW('K', 100, scr_size_t)
#define GETFKEY _IOWR('k', 0, fkeyarg_t)
#define SETFKEY _IOWR('k', 1, fkeyarg_t)
@@ -84,6 +85,11 @@
#define GIO_FONT8x16 _IOR('c', 69, fnt16_t)
#define CONS_GETINFO _IOWR('c', 73, vid_info_t)
#define CONS_GETVERS _IOR('c', 74, int)
+#define CONS_CURRENTADP _IOR('c', 100, int)
+#define CONS_ADPINFO _IOWR('c', 101, video_adapter_t)
+#define CONS_MODEINFO _IOWR('c', 102, video_info_t)
+#define CONS_FINDMODE _IOWR('c', 103, video_info_t)
+#define CONS_SETWINORG _IO('c', 104 /* u_int */)
/* CONS_SAVERMODE */
#define CONS_LKM_SAVER 0
@@ -169,6 +175,7 @@ struct mouse_info {
#define KD_TEXT0 0 /* ditto */
#define KD_TEXT1 2 /* set text mode !restore fonts */
#define KD_GRAPHICS 1 /* set graphics mode */
+#define KD_PIXEL 3 /* set pixel mode */
#define K_RAW 0 /* keyboard returns scancodes */
#define K_XLATE 1 /* keyboard returns ascii */
@@ -263,6 +270,55 @@ struct ssaver {
long time;
};
+/* adapter infromation block */
+struct video_adapter {
+ int va_index;
+ int va_type;
+ int va_flags;
+#define V_ADP_COLOR (1<<0)
+#define V_ADP_MODECHANGE (1<<1)
+#define V_ADP_STATESAVE (1<<2)
+#define V_ADP_STATELOAD (1<<3)
+#define V_ADP_FONT (1<<4)
+#define V_ADP_PALETTE (1<<5)
+#define V_ADP_BORDER (1<<6)
+#define V_ADP_VESA (1<<7)
+ int va_crtc_addr;
+ u_int va_window; /* virtual address */
+ size_t va_window_size;
+ size_t va_window_gran;
+ u_int va_buffer; /* virtual address */
+ size_t va_buffer_size;
+ int va_initial_mode;
+ int va_initial_bios_mode;
+ int va_mode;
+};
+
+#define V_ADP_PRIMARY 0
+#define V_ADP_SECONDARY 1
+
+/* video mode information block */
+struct video_info {
+ int vi_mode;
+ int vi_flags;
+#define V_INFO_COLOR (1<<0)
+#define V_INFO_GRAPHICS (1<<1)
+#define V_INFO_LENEAR (1<<2)
+#define V_INFO_VESA (1<<3)
+ int vi_width;
+ int vi_height;
+ int vi_cwidth;
+ int vi_cheight;
+ int vi_depth;
+ int vi_planes;
+ u_int vi_window; /* physical address */
+ size_t vi_window_size;
+ size_t vi_window_gran;
+ u_int vi_buffer; /* physical address */
+ size_t vi_buffer_size;
+ /* XXX pixel format, memory model,... */
+};
+
typedef struct accentmap accentmap_t;
typedef struct fkeytab fkeytab_t;
typedef struct fkeyarg fkeyarg_t;
@@ -273,6 +329,9 @@ typedef struct {char fnt8x8[8*256];} fnt8_t;
typedef struct {char fnt8x14[14*256];} fnt14_t;
typedef struct {char fnt8x16[16*256];} fnt16_t;
typedef struct ssaver ssaver_t;
+typedef struct video_adapter video_adapter_t;
+typedef struct video_info video_info_t;
+typedef struct {int scr_size[3];} scr_size_t;
/* defines for "special" keys (spcl bit set in keymap) */
#define NOP 0x00 /* nothing (dead key) */
@@ -378,8 +437,6 @@ typedef struct ssaver ssaver_t;
#define M_HGC_P1 0xe1 /* hercules graphics - page 1 @ B8000 */
#define M_MCA_MODE 0xff /* monochrome adapter mode */
-#define M_VESA_BASE 0x100 /* VESA mode number base */
-
#define SW_PC98_80x25 _IO('S', M_PC98_80x25)
#define SW_PC98_80x30 _IO('S', M_PC98_80x30)
#define SW_B40x25 _IO('S', M_B40x25)
@@ -421,4 +478,68 @@ typedef struct ssaver ssaver_t;
#define SW_VGA_CG640 _IO('S', M_VGA_CG640)
#define SW_VGA_MODEX _IO('S', M_VGA_MODEX)
+#define M_VESA_BASE 0x100 /* VESA mode number base */
+
+#define M_VESA_CG640x400 0x100 /* 640x400, 256 color */
+#define M_VESA_CG640x480 0x101 /* 640x480, 256 color */
+#define M_VESA_800x600 0x102 /* 800x600, 16 color */
+#define M_VESA_CG800x600 0x103 /* 800x600, 256 color */
+#define M_VESA_1024x768 0x104 /* 1024x768, 16 color */
+#define M_VESA_CG1024x768 0x105 /* 1024x768, 256 color */
+#define M_VESA_1280x1024 0x106 /* 1280x1024, 16 color */
+#define M_VESA_CG1280x1024 0x107 /* 1280x1024, 256 color */
+#define M_VESA_C80x60 0x108 /* 8x8 font */
+#define M_VESA_C132x25 0x109 /* 8x16 font */
+#define M_VESA_C132x43 0x10a /* 8x14 font */
+#define M_VESA_C132x50 0x10b /* 8x8 font */
+#define M_VESA_C132x60 0x10c /* 8x8 font */
+#define M_VESA_32K_320 0x10d /* 320x200, 5:5:5 */
+#define M_VESA_64K_320 0x10e /* 320x200, 5:6:5 */
+#define M_VESA_FULL_320 0x10f /* 320x200, 8:8:8 */
+#define M_VESA_32K_640 0x110 /* 640x480, 5:5:5 */
+#define M_VESA_64K_640 0x111 /* 640x480, 5:6:5 */
+#define M_VESA_FULL_640 0x112 /* 640x480, 8:8:8 */
+#define M_VESA_32K_800 0x113 /* 800x600, 5:5:5 */
+#define M_VESA_64K_800 0x114 /* 800x600, 5:6:5 */
+#define M_VESA_FULL_800 0x115 /* 800x600, 8:8:8 */
+#define M_VESA_32K_1024 0x116 /* 1024x768, 5:5:5 */
+#define M_VESA_64K_1024 0x117 /* 1024x768, 5:6:5 */
+#define M_VESA_FULL_1024 0x118 /* 1024x768, 8:8:8 */
+#define M_VESA_32K_1280 0x119 /* 1280x1024, 5:5:5 */
+#define M_VESA_64K_1280 0x11a /* 1280x1024, 5:6:5 */
+#define M_VESA_FULL_1280 0x11b /* 1280x1024, 8:8:8 */
+#define M_VESA_MODE_MAX 0x1ff
+#define M_VESA_USER 0x1ff
+
+#define SW_VESA_CG640x400 _IO('V', M_VESA_CG640x400 - M_VESA_BASE)
+#define SW_VESA_CG640x480 _IO('V', M_VESA_CG640x480 - M_VESA_BASE)
+#define SW_VESA_800x600 _IO('V', M_VESA_800x600 - M_VESA_BASE)
+#define SW_VESA_CG800x600 _IO('V', M_VESA_CG800x600 - M_VESA_BASE)
+#define SW_VESA_1024x768 _IO('V', M_VESA_1024x768 - M_VESA_BASE)
+#define SW_VESA_CG1024x768 _IO('V', M_VESA_CG1024x768 - M_VESA_BASE)
+#define SW_VESA_1280x1024 _IO('V', M_VESA_1280x1024 - M_VESA_BASE)
+#define SW_VESA_CG1280x1024 _IO('V', M_VESA_CG1280x1024 - M_VESA_BASE)
+#define SW_VESA_C80x60 _IO('V', M_VESA_C80x60 - M_VESA_BASE)
+#define SW_VESA_C132x25 _IO('V', M_VESA_C132x25 - M_VESA_BASE)
+#define SW_VESA_C132x43 _IO('V', M_VESA_C132x43 - M_VESA_BASE)
+#define SW_VESA_C132x50 _IO('V', M_VESA_C132x50 - M_VESA_BASE)
+#define SW_VESA_C132x60 _IO('V', M_VESA_C132x60 - M_VESA_BASE)
+#define SW_VESA_32K_320 _IO('V', M_VESA_32K_320 - M_VESA_BASE)
+#define SW_VESA_64K_320 _IO('V', M_VESA_64K_320 - M_VESA_BASE)
+#define SW_VESA_FULL_320 _IO('V', M_VESA_FULL_320 - M_VESA_BASE)
+#define SW_VESA_32K_640 _IO('V', M_VESA_32K_640 - M_VESA_BASE)
+#define SW_VESA_64K_640 _IO('V', M_VESA_64K_640 - M_VESA_BASE)
+#define SW_VESA_FULL_640 _IO('V', M_VESA_FULL_640 - M_VESA_BASE)
+#define SW_VESA_32K_800 _IO('V', M_VESA_32K_800 - M_VESA_BASE)
+#define SW_VESA_64K_800 _IO('V', M_VESA_64K_800 - M_VESA_BASE)
+#define SW_VESA_FULL_800 _IO('V', M_VESA_FULL_800 - M_VESA_BASE)
+#define SW_VESA_32K_1024 _IO('V', M_VESA_32K_1024 - M_VESA_BASE)
+#define SW_VESA_64K_1024 _IO('V', M_VESA_64K_1024 - M_VESA_BASE)
+#define SW_VESA_FULL_1024 _IO('V', M_VESA_FULL_1024 - M_VESA_BASE)
+#define SW_VESA_32K_1280 _IO('V', M_VESA_32K_1280 - M_VESA_BASE)
+#define SW_VESA_64K_1280 _IO('V', M_VESA_64K_1280 - M_VESA_BASE)
+#define SW_VESA_FULL_1280 _IO('V', M_VESA_FULL_1280 - M_VESA_BASE)
+#define SW_VESA_USER _IO('V', M_VESA_USER - M_VESA_BASE)
+
#endif /* !_MACHINE_CONSOLE_H_ */
+
diff --git a/sys/i386/include/pc/vesa.h b/sys/i386/include/pc/vesa.h
new file mode 100644
index 0000000..4fa38ee
--- /dev/null
+++ b/sys/i386/include/pc/vesa.h
@@ -0,0 +1,127 @@
+/*-
+ * Copyright (c) 1998 Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp)
+ * 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. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#ifndef _MACHINE_PC_VESA_H
+#define _MACHINE_PC_VESA_H
+
+struct vesa_info
+{
+ /* mandatory fields */
+ u_int8_t v_sig[4] __attribute__ ((packed)); /* VESA */
+ u_int16_t v_version __attribute__ ((packed)); /* ver in BCD */
+ u_int32_t v_oemstr __attribute__ ((packed)); /* OEM string */
+ u_int32_t v_flags __attribute__ ((packed)); /* flags */
+#define V_DAC8 (1<<0)
+#define V_NONVGA (1<<1)
+#define V_SNOW (1<<2)
+ u_int32_t v_modetable __attribute__ ((packed)); /* modes */
+ u_int16_t v_memsize __attribute__ ((packed)); /* in 64K */
+ /* 2.0 */
+ u_int16_t v_revision __attribute__ ((packed)); /* software rev */
+ u_int32_t v_venderstr __attribute__ ((packed)); /* vender */
+ u_int32_t v_prodstr __attribute__ ((packed)); /* product name */
+ u_int32_t v_revstr __attribute__ ((packed)); /* product rev */
+};
+
+struct vesa_mode
+{
+ /* mandatory fields */
+ u_int16_t v_modeattr;
+#define V_MODESUPP (1<<0) /* VESA mode attributes */
+#define V_MODEOPTINFO (1<<1)
+#define V_MODEBIOSOUT (1<<2)
+#define V_MODECOLOR (1<<3)
+#define V_MODEGRAPHICS (1<<4)
+#define V_MODENONVGA (1<<5)
+#define V_MODENONBANK (1<<6)
+#define V_MODELFB (1<<7)
+#define V_MODEVESA (1<<16) /* Private attributes */
+ u_int8_t v_waattr;
+ u_int8_t v_wbattr;
+#define V_WATTREXIST (1<<0)
+#define V_WATTRREAD (1<<1)
+#define V_WATTRWRITE (1<<2)
+ u_int16_t v_wgran;
+ u_int16_t v_wsize;
+ u_int16_t v_waseg;
+ u_int16_t v_wbseg;
+ u_int32_t v_posfunc;
+ u_int16_t v_bpscanline;
+ /* fields optional for 1.0/1.1 implementations */
+ u_int16_t v_width;
+ u_int16_t v_height;
+ u_int8_t v_cwidth;
+ u_int8_t v_cheight;
+ u_int8_t v_planes;
+ u_int8_t v_bpp;
+ u_int8_t v_banks;
+ u_int8_t v_memmodel;
+#define V_MMTEXT 0
+#define V_MMCGA 1
+#define V_MMHGC 2
+#define V_MMEGA 3
+#define V_MMPACKED 4
+#define V_MMSEQU256 5
+#define V_MMDIRCOLOR 6
+#define V_MMYUV 7
+ u_int8_t v_banksize;
+ u_int8_t v_ipages;
+ u_int8_t v_reserved0;
+ /* fields for 1.2+ implementations */
+ u_int8_t v_redmasksize;
+ u_int8_t v_redfieldpos;
+ u_int8_t v_greenmasksize;
+ u_int8_t v_greenfieldpos;
+ u_int8_t v_bluemasksize;
+ u_int8_t v_bluefieldpos;
+ u_int8_t v_resmasksize;
+ u_int8_t v_resfieldpos;
+ u_int8_t v_dircolormode;
+ /* 2.0 implementations */
+ u_int32_t v_lfb;
+ u_int32_t v_offscreen;
+ u_int8_t v_offscreensize;
+};
+
+#ifdef KERNEL
+
+#define VESA_MODE(x) ((x) >= M_VESA_BASE)
+
+int vesa_load_ioctl(void);
+int vesa_unload_ioctl(void);
+
+#ifndef VESA_MODULE
+int vesa_load(void);
+#endif
+
+#endif /* KERNEL */
+
+#endif /* !_MACHINE_PC_VESA_H */
diff --git a/sys/i386/isa/kbdtables.h b/sys/i386/isa/kbdtables.h
index d36b39a..61376f4 100644
--- a/sys/i386/isa/kbdtables.h
+++ b/sys/i386/isa/kbdtables.h
@@ -1,18 +1,18 @@
/*-
- * Copyright (c) 1992-1995 Søren Schmidt
+ * Copyright (c) 1992-1998 Søren Schmidt
* 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
- * in this position and unchanged.
+ * notice, this list of conditions and the following disclaimer,
+ * without modification, immediately at the beginning of the file.
* 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. The name of the author may not be used to endorse or promote products
- * derived from this software withough specific prior written permission
+ * derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: kbdtables.h,v 1.39 1998/01/28 08:45:18 yokota Exp $
+ * $Id$
*/
#define SET8 0x80 /* set eight bit on */
diff --git a/sys/i386/isa/pcaudio.c b/sys/i386/isa/pcaudio.c
index 25b5237..e2b0c65 100644
--- a/sys/i386/isa/pcaudio.c
+++ b/sys/i386/isa/pcaudio.c
@@ -1,18 +1,18 @@
/*-
- * Copyright (c) 1994 Søren Schmidt
+ * Copyright (c) 1994-1998 Søren Schmidt
* 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
- * in this position and unchanged.
+ * notice, this list of conditions and the following disclaimer,
+ * without modification, immediately at the beginning of the file.
* 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. The name of the author may not be used to endorse or promote products
- * derived from this software withough specific prior written permission
+ * derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: pcaudio.c,v 1.41 1998/06/07 17:10:48 dfr Exp $
+ * $Id$
*/
#include "pca.h"
diff --git a/sys/i386/isa/scvesactl.c b/sys/i386/isa/scvesactl.c
new file mode 100644
index 0000000..9678177
--- /dev/null
+++ b/sys/i386/isa/scvesactl.c
@@ -0,0 +1,150 @@
+/*-
+ * Copyright (c) 1998 Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp)
+ * 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. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#include "sc.h"
+#include "opt_vesa.h"
+#include "opt_vm86.h"
+
+#if (NSC > 0 && defined(VESA) && defined(VM86)) || defined(VESA_MODULE)
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/tty.h>
+#include <sys/kernel.h>
+
+#include <machine/apm_bios.h>
+#include <machine/console.h>
+#include <machine/pc/vesa.h>
+
+#include <i386/isa/videoio.h>
+#include <i386/isa/syscons.h>
+
+static int (*prev_user_ioctl)(dev_t dev, int cmd, caddr_t data, int flag,
+ struct proc *p);
+
+extern struct tty *scdevtotty(dev_t dev);
+
+int
+vesa_ioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
+{
+ scr_stat *scp;
+ struct tty *tp;
+ video_info_t info;
+ video_adapter_t *adp;
+ int mode;
+ int error;
+ int s;
+
+ tp = scdevtotty(dev);
+ if (!tp)
+ return ENXIO;
+ scp = sc_get_scr_stat(tp->t_dev);
+
+ switch (cmd) {
+ case SW_VESA_USER:
+
+ mode = (int)data;
+ if ((*biosvidsw.get_info)(scp->adp, mode, &info))
+ return ENODEV;
+ if (info.vi_flags & V_INFO_GRAPHICS)
+ goto vesa_graphics;
+ else
+ goto vesa_text;
+
+ /* text modes */
+ case SW_VESA_C80x60:
+ case SW_VESA_C132x25:
+ case SW_VESA_C132x43:
+ case SW_VESA_C132x50:
+ case SW_VESA_C132x60:
+ adp = get_adapter(scp);
+ if (!(adp->va_flags & V_ADP_MODECHANGE))
+ return ENODEV;
+ mode = (cmd & 0xff) + M_VESA_BASE;
+vesa_text:
+ return sc_set_text_mode(scp, tp, mode, 0, 0, 0);
+
+ /* graphics modes */
+ case SW_VESA_32K_320: case SW_VESA_64K_320:
+ case SW_VESA_FULL_320:
+
+ case SW_VESA_CG640x400:
+
+ case SW_VESA_CG640x480:
+ case SW_VESA_32K_640: case SW_VESA_64K_640:
+ case SW_VESA_FULL_640:
+
+ case SW_VESA_800x600: case SW_VESA_CG800x600:
+ case SW_VESA_32K_800: case SW_VESA_64K_800:
+ case SW_VESA_FULL_800:
+
+ case SW_VESA_1024x768: case SW_VESA_CG1024x768:
+ case SW_VESA_32K_1024: case SW_VESA_64K_1024:
+ case SW_VESA_FULL_1024:
+
+ case SW_VESA_1280x1024: case SW_VESA_CG1280x1024:
+ case SW_VESA_32K_1280: case SW_VESA_64K_1280:
+ case SW_VESA_FULL_1280:
+ adp = get_adapter(scp);
+ if (!(adp->va_flags & V_ADP_MODECHANGE))
+ return ENODEV;
+ mode = (cmd & 0xff) + M_VESA_BASE;
+vesa_graphics:
+ return sc_set_graphics_mode(scp, tp, mode);
+ }
+
+ if (prev_user_ioctl)
+ return (*prev_user_ioctl)(dev, cmd, data, flag, p);
+ else
+ return ENOIOCTL;
+}
+
+int
+vesa_load_ioctl(void)
+{
+ if (prev_user_ioctl)
+ return EBUSY;
+ prev_user_ioctl = sc_user_ioctl;
+ sc_user_ioctl = vesa_ioctl;
+ return 0;
+}
+
+int
+vesa_unload_ioctl(void)
+{
+ if (sc_user_ioctl != vesa_ioctl)
+ return EBUSY;
+ sc_user_ioctl = prev_user_ioctl;
+ prev_user_ioctl = NULL;
+ return 0;
+}
+
+#endif /* (NSC > 0 && VESA && VM86) || VESA_MODULE */
diff --git a/sys/i386/isa/scvidctl.c b/sys/i386/isa/scvidctl.c
new file mode 100644
index 0000000..464933e
--- /dev/null
+++ b/sys/i386/isa/scvidctl.c
@@ -0,0 +1,486 @@
+/*-
+ * Copyright (c) 1998 Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp)
+ * 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. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#include "sc.h"
+#include "opt_syscons.h"
+
+#if NSC > 0
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/signalvar.h>
+#include <sys/tty.h>
+#include <sys/kernel.h>
+
+#include <machine/apm_bios.h>
+#include <machine/console.h>
+
+#include <i386/isa/videoio.h>
+#include <i386/isa/syscons.h>
+
+/* video ioctl */
+
+extern scr_stat *cur_console;
+extern u_short *Crtat;
+extern int fonts_loaded;
+extern int sc_history_size;
+extern u_char palette[];
+
+int
+sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, int xsize, int ysize,
+ int fontsize)
+{
+ video_adapter_t *adp;
+ video_info_t info;
+ int error;
+ int s;
+ int i;
+
+ if ((*biosvidsw.get_info)(scp->adp, mode, &info))
+ return ENODEV;
+ adp = get_adapter(scp);
+
+ /* adjust argument values */
+ if (fontsize <= 0)
+ fontsize = info.vi_cheight;
+ if (fontsize < 14) {
+ fontsize = 8;
+ if (!(fonts_loaded & FONT_8))
+ return EINVAL;
+ } else if (fontsize >= 16) {
+ fontsize = 16;
+ if (!(fonts_loaded & FONT_16))
+ return EINVAL;
+ } else {
+ fontsize = 14;
+ if (!(fonts_loaded & FONT_14))
+ return EINVAL;
+ }
+ if ((xsize <= 0) || (xsize > info.vi_width))
+ xsize = info.vi_width;
+ if ((ysize <= 0) || (ysize > info.vi_height))
+ ysize = info.vi_height;
+
+ /* stop screen saver, etc */
+ s = spltty();
+ if ((error = sc_clean_up(scp))) {
+ splx(s);
+ return error;
+ }
+
+ /* set up scp */
+ if (scp->history != NULL)
+ i = imax(scp->history_size / scp->xsize
+ - imax(sc_history_size, scp->ysize), 0);
+ else
+ i = 0;
+ /*
+ * This is a kludge to fend off scrn_update() while we
+ * muck around with scp. XXX
+ */
+ scp->status |= UNKNOWN_MODE;
+ scp->status &= ~(GRAPHICS_MODE | PIXEL_MODE);
+ scp->mode = mode;
+ scp->font_size = fontsize;
+ scp->xsize = xsize;
+ scp->ysize = ysize;
+ scp->xpixel = scp->xsize*8;
+ scp->ypixel = scp->ysize*fontsize;
+
+ /* allocate buffers */
+ sc_alloc_scr_buffer(scp, TRUE, TRUE);
+ if (ISMOUSEAVAIL(adp->va_flags))
+ sc_alloc_cut_buffer(scp, FALSE);
+ sc_alloc_history_buffer(scp, sc_history_size, i, FALSE);
+ splx(s);
+
+ if (scp == cur_console)
+ set_mode(scp);
+ scp->status &= ~UNKNOWN_MODE;
+
+ if (tp == NULL)
+ return 0;
+ if (tp->t_winsize.ws_col != scp->xsize
+ || tp->t_winsize.ws_row != scp->ysize) {
+ tp->t_winsize.ws_col = scp->xsize;
+ tp->t_winsize.ws_row = scp->ysize;
+ pgsignal(tp->t_pgrp, SIGWINCH, 1);
+ }
+
+ return 0;
+}
+
+int
+sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode)
+{
+ video_adapter_t *adp;
+ video_info_t info;
+ int error;
+ int s;
+
+ if ((*biosvidsw.get_info)(scp->adp, mode, &info))
+ return ENODEV;
+ adp = get_adapter(scp);
+
+ /* stop screen saver, etc */
+ s = spltty();
+ if ((error = sc_clean_up(scp))) {
+ splx(s);
+ return error;
+ }
+
+ /* set up scp */
+ scp->status |= (UNKNOWN_MODE | GRAPHICS_MODE);
+ scp->status &= ~PIXEL_MODE;
+ scp->mode = mode;
+ scp->xpixel = info.vi_width;
+ scp->ypixel = info.vi_height;
+ scp->xsize = info.vi_width/8;
+ scp->ysize = info.vi_height/info.vi_cheight;
+ scp->font_size = FONT_NONE;
+ /* move the mouse cursor at the center of the screen */
+ sc_move_mouse(scp, scp->xpixel / 2, scp->ypixel / 2);
+ splx(s);
+
+ if (scp == cur_console)
+ set_mode(scp);
+ /* clear_graphics();*/
+ scp->status &= ~UNKNOWN_MODE;
+
+ if (tp == NULL)
+ return 0;
+ if (tp->t_winsize.ws_xpixel != scp->xpixel
+ || tp->t_winsize.ws_ypixel != scp->ypixel) {
+ tp->t_winsize.ws_xpixel = scp->xpixel;
+ tp->t_winsize.ws_ypixel = scp->ypixel;
+ pgsignal(tp->t_pgrp, SIGWINCH, 1);
+ }
+
+ return 0;
+}
+
+int
+sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize,
+ int fontsize)
+{
+ video_adapter_t *adp;
+ video_info_t info;
+ int error;
+ int s;
+ int i;
+
+ if ((*biosvidsw.get_info)(scp->adp, scp->mode, &info))
+ return ENODEV; /* this shouldn't happen */
+ adp = get_adapter(scp);
+
+#ifdef SC_VIDEO_DEBUG
+ if (scp->scr_buf != NULL) {
+ printf("set_pixel_mode(): mode:%x, col:%d, row:%d, font:%d\n",
+ scp->mode, xsize, ysize, fontsize);
+ }
+#endif
+
+ /* adjust argument values */
+ if ((fontsize <= 0) || (fontsize == FONT_NONE))
+ fontsize = info.vi_cheight;
+ if (fontsize < 14) {
+ fontsize = 8;
+ if (!(fonts_loaded & FONT_8))
+ return EINVAL;
+ } else if (fontsize >= 16) {
+ fontsize = 16;
+ if (!(fonts_loaded & FONT_16))
+ return EINVAL;
+ } else {
+ fontsize = 14;
+ if (!(fonts_loaded & FONT_14))
+ return EINVAL;
+ }
+ if (xsize <= 0)
+ xsize = info.vi_width/8;
+ if (ysize <= 0)
+ ysize = info.vi_height/fontsize;
+
+#ifdef SC_VIDEO_DEBUG
+ if (scp->scr_buf != NULL) {
+ printf("set_pixel_mode(): mode:%x, col:%d, row:%d, font:%d\n",
+ scp->mode, xsize, ysize, fontsize);
+ printf("set_pixel_mode(): Crtat:%x, %dx%d, xoff:%d, yoff:%d\n",
+ Crtat, info.vi_width, info.vi_height,
+ (info.vi_width/8 - xsize)/2,
+ (info.vi_height/fontsize - ysize)/2);
+ }
+#endif
+
+ /* stop screen saver, etc */
+ s = spltty();
+ if ((error = sc_clean_up(scp))) {
+ splx(s);
+ return error;
+ }
+
+ /* set up scp */
+ if (scp->history != NULL)
+ i = imax(scp->history_size / scp->xsize
+ - imax(sc_history_size, scp->ysize), 0);
+ else
+ i = 0;
+ scp->status |= (UNKNOWN_MODE | PIXEL_MODE);
+ scp->status &= ~(GRAPHICS_MODE | MOUSE_ENABLED);
+ scp->xsize = xsize;
+ scp->ysize = ysize;
+ scp->font_size = fontsize;
+ scp->xoff = (scp->xpixel/8 - xsize)/2;
+ scp->yoff = (scp->ypixel/fontsize - ysize)/2;
+
+ /* allocate buffers */
+ sc_alloc_scr_buffer(scp, TRUE, TRUE);
+ if (ISMOUSEAVAIL(adp->va_flags))
+ sc_alloc_cut_buffer(scp, FALSE);
+ sc_alloc_history_buffer(scp, sc_history_size, i, FALSE);
+ splx(s);
+
+ /* FIXME */
+ if (scp == cur_console)
+ bzero(Crtat, scp->xpixel*scp->ypixel/8);
+
+ scp->status &= ~UNKNOWN_MODE;
+
+#ifdef SC_VIDEO_DEBUG
+ printf("set_pixel_mode(): status:%x\n", scp->status);
+#endif
+
+ if (tp == NULL)
+ return 0;
+ if (tp->t_winsize.ws_col != scp->xsize
+ || tp->t_winsize.ws_row != scp->ysize) {
+ tp->t_winsize.ws_col = scp->xsize;
+ tp->t_winsize.ws_row = scp->ysize;
+ pgsignal(tp->t_pgrp, SIGWINCH, 1);
+ }
+
+ return 0;
+}
+
+int
+sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p)
+{
+ scr_stat *scp;
+ video_adapter_t *adp;
+ int error;
+ int s;
+
+ scp = sc_get_scr_stat(tp->t_dev);
+
+ switch (cmd) {
+
+ case CONS_CURRENT: /* get current adapter type */
+ adp = get_adapter(scp);
+ *(int *)data = adp->va_type;
+ return 0;
+
+ case CONS_CURRENTADP: /* get current adapter index */
+ *(int *)data = scp->adp;
+ return 0;
+
+ case CONS_ADPINFO: /* adapter information */
+ adp = (*biosvidsw.adapter)(((video_adapter_t *)data)->va_index);
+ if (adp == NULL)
+ return ENODEV;
+ bcopy(adp, data, sizeof(*adp));
+ return 0;
+
+ case CONS_GET: /* get current video mode */
+ *(int *)data = scp->mode;
+ return 0;
+
+ case CONS_MODEINFO: /* get mode information */
+ return ((*biosvidsw.get_info)(scp->adp,
+ ((video_info_t *)data)->vi_mode, (video_info_t *)data)
+ ? ENODEV : 0);
+
+ case CONS_FINDMODE: /* find a matching video mode */
+ return ((*biosvidsw.query_mode)(scp->adp, (video_info_t *)data)
+ ? ENODEV : 0);
+
+ case CONS_SETWINORG:
+ return ((*biosvidsw.set_win_org)(scp->adp, *(u_int *)data)
+ ? ENODEV : 0);
+
+ /* VGA TEXT MODES */
+ case SW_VGA_C40x25:
+ case SW_VGA_C80x25: case SW_VGA_M80x25:
+ case SW_VGA_C80x30: case SW_VGA_M80x30:
+ case SW_VGA_C80x50: case SW_VGA_M80x50:
+ case SW_VGA_C80x60: case SW_VGA_M80x60:
+ case SW_B40x25: case SW_C40x25:
+ case SW_B80x25: case SW_C80x25:
+ case SW_ENH_B40x25: case SW_ENH_C40x25:
+ case SW_ENH_B80x25: case SW_ENH_C80x25:
+ case SW_ENH_B80x43: case SW_ENH_C80x43:
+ case SW_EGAMONO80x25:
+ adp = get_adapter(scp);
+ if (!(adp->va_flags & V_ADP_MODECHANGE))
+ return ENODEV;
+ return sc_set_text_mode(scp, tp, cmd & 0xff, 0, 0, 0);
+
+ /* GRAPHICS MODES */
+ case SW_BG320: case SW_BG640:
+ case SW_CG320: case SW_CG320_D: case SW_CG640_E:
+ case SW_CG640x350: case SW_ENH_CG640:
+ case SW_BG640x480: case SW_CG640x480: case SW_VGA_CG320:
+ case SW_VGA_MODEX:
+ adp = get_adapter(scp);
+ if (!(adp->va_flags & V_ADP_MODECHANGE))
+ return ENODEV;
+ return sc_set_graphics_mode(scp, tp, cmd & 0xff);
+
+ case KDSETMODE: /* set current mode of this (virtual) console */
+ switch (*data) {
+ case KD_TEXT: /* switch to TEXT (known) mode */
+ /*
+ * If scp->mode is of graphics modes, we don't know which
+ * text mode to switch back to...
+ */
+ if (scp->status & GRAPHICS_MODE)
+ return EINVAL;
+ /* restore fonts & palette ! */
+#if 0
+ adp = get_adapter(scp);
+ if (ISFONTAVAIL(adp->va_flags)
+ && !(scp->status & (GRAPHICS_MODE | PIXEL_MODE)))
+ /*
+ * FONT KLUDGE
+ * Don't load fonts for now... XXX
+ */
+ if (fonts_loaded & FONT_8)
+ copy_font(scp, LOAD, 8, font_8);
+ if (fonts_loaded & FONT_14)
+ copy_font(scp, LOAD, 14, font_14);
+ if (fonts_loaded & FONT_16)
+ copy_font(scp, LOAD, 16, font_16);
+ }
+#endif
+ load_palette(scp, palette);
+
+ /* move hardware cursor out of the way */
+ (*biosvidsw.set_hw_cursor)(scp->adp, -1, -1);
+
+ /* FALL THROUGH */
+
+ case KD_TEXT1: /* switch to TEXT (known) mode */
+ /*
+ * If scp->mode is of graphics modes, we don't know which
+ * text/pixel mode to switch back to...
+ */
+ if (scp->status & GRAPHICS_MODE)
+ return EINVAL;
+ s = spltty();
+ if ((error = sc_clean_up(scp))) {
+ splx(s);
+ return error;
+ }
+ scp->status |= UNKNOWN_MODE;
+ splx(s);
+ /* no restore fonts & palette */
+ if (scp == cur_console) {
+ set_mode(scp);
+ /* FIXME */
+ if (scp->status & PIXEL_MODE)
+ bzero(Crtat, scp->xpixel*scp->ypixel/8);
+ }
+ sc_clear_screen(scp);
+ scp->status &= ~UNKNOWN_MODE;
+ return 0;
+
+ case KD_PIXEL: /* pixel (raster) display */
+ if (!(scp->status & (GRAPHICS_MODE | PIXEL_MODE)))
+ return EINVAL;
+ if (!(scp->status & PIXEL_MODE))
+ return sc_set_pixel_mode(scp, tp, scp->xsize, scp->ysize,
+ scp->font_size);
+ s = spltty();
+ if ((error = sc_clean_up(scp))) {
+ splx(s);
+ return error;
+ }
+ scp->status |= (UNKNOWN_MODE | PIXEL_MODE);
+ splx(s);
+ if (scp == cur_console) {
+ set_mode(scp);
+ load_palette(scp, palette);
+ /* FIXME */
+ bzero(Crtat, scp->xpixel*scp->ypixel/8);
+ }
+ sc_clear_screen(scp);
+ scp->status &= ~UNKNOWN_MODE;
+ return 0;
+
+ case KD_GRAPHICS: /* switch to GRAPHICS (unknown) mode */
+ s = spltty();
+ if ((error = sc_clean_up(scp))) {
+ splx(s);
+ return error;
+ }
+ scp->status |= UNKNOWN_MODE;
+ splx(s);
+ return 0;
+
+ default:
+ return EINVAL;
+ }
+ /* NOT REACHED */
+
+ case KDRASTER: /* set pixel (raster) display mode */
+ if (ISUNKNOWNSC(scp) || ISTEXTSC(scp))
+ return ENODEV;
+ return sc_set_pixel_mode(scp, tp, ((int *)data)[0], ((int *)data)[1],
+ ((int *)data)[2]);
+
+ case KDGETMODE: /* get current mode of this (virtual) console */
+ /*
+ * From the user program's point of view, KD_PIXEL is the same
+ * as KD_TEXT...
+ */
+ *data = ISGRAPHSC(scp) ? KD_GRAPHICS : KD_TEXT;
+ return 0;
+
+ case KDSBORDER: /* set border color of this (virtual) console */
+ scp->border = *data;
+ if (scp == cur_console)
+ set_border(cur_console, scp->border);
+ return 0;
+ }
+
+ return ENOIOCTL;
+}
+
+#endif /* NSC > 0 */
diff --git a/sys/i386/isa/syscons.c b/sys/i386/isa/syscons.c
index ebc243f..50e0f19 100644
--- a/sys/i386/isa/syscons.c
+++ b/sys/i386/isa/syscons.c
@@ -1,18 +1,18 @@
/*-
- * Copyright (c) 1992-1997 Søren Schmidt
+ * Copyright (c) 1992-1998 Søren Schmidt
* 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
- * in this position and unchanged.
+ * notice, this list of conditions and the following disclaimer,
+ * without modification, immediately at the beginning of the file.
* 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. The name of the author may not be used to endorse or promote products
- * derived from this software withough specific prior written permission
+ * derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@@ -25,13 +25,15 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: syscons.c,v 1.276 1998/08/23 08:26:41 bde Exp $
+ * $Id$
*/
#include "sc.h"
#include "apm.h"
#include "opt_ddb.h"
#include "opt_devfs.h"
+#include "opt_vesa.h"
+#include "opt_vm86.h"
#include "opt_syscons.h"
#if NSC > 0
@@ -57,9 +59,9 @@
#include <machine/psl.h>
#include <machine/frame.h>
#include <machine/pc/display.h>
+#include <machine/pc/vesa.h>
#include <machine/apm_bios.h>
#include <machine/random.h>
-#include <machine/bootinfo.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
@@ -70,6 +72,7 @@
#include <i386/isa/timerreg.h>
#include <i386/isa/kbdtables.h>
#include <i386/isa/kbdio.h>
+#include <i386/isa/videoio.h>
#include <i386/isa/syscons.h>
#if !defined(MAXCONS)
@@ -96,11 +99,6 @@
#define COLD 0
#define WARM 1
-#define VESA_MODE(x) ((x) >= M_VESA_BASE)
-
-#define MODE_MAP_SIZE (M_VGA_CG320 + 1)
-#define MODE_PARAM_SIZE 64
-
#define DEFAULT_BLANKTIME (5*60) /* 5 minutes */
#define MAX_BLANKTIME (7*24*60*60) /* 7 days!? */
@@ -159,6 +157,7 @@ static int blinkrate = 0;
u_int crtc_addr = MONO_BASE;
char crtc_type = KD_MONO;
char crtc_vga = FALSE;
+static int adp_flags = 0;
static u_char shfts = 0, ctls = 0, alts = 0, agrs = 0, metas = 0;
static u_char accents = 0;
static u_char nlkcnt = 0, clkcnt = 0, slkcnt = 0, alkcnt = 0;
@@ -172,7 +171,7 @@ static int run_scrn_saver = FALSE; /* should run the saver? */
static int scrn_idle = FALSE; /* about to run the saver */
u_char scr_map[256];
u_char scr_rmap[256];
- char *video_mode_ptr = NULL;
+static int initial_video_mode; /* initial video mode # */
static int bios_video_mode; /* video mode # set by BIOS */
int fonts_loaded = 0
#ifdef STD8X16FONT
@@ -180,19 +179,15 @@ static int bios_video_mode; /* video mode # set by BIOS */
#endif
;
- char font_8[256*8];
- char font_14[256*14];
+ u_char font_8[256*8];
+ u_char font_14[256*14];
#ifdef STD8X16FONT
extern
#endif
- unsigned char font_16[256*16];
- char palette[256*3];
-static char *mode_map[MODE_MAP_SIZE];
-static char vgaregs[MODE_PARAM_SIZE];
-static char vgaregs2[MODE_PARAM_SIZE];
-static int rows_offset = 1;
-static char *cut_buffer;
-static int cut_buffer_size;
+ u_char font_16[256*16];
+ u_char palette[256*3];
+static u_char *cut_buffer = NULL;
+static int cut_buffer_size = 0;
static int mouse_level = 0; /* sysmouse protocol level */
static mousestatus_t mouse_status = { 0, 0, 0, 0, 0, 0 };
static u_short mouse_and_mask[16] = {
@@ -208,13 +203,14 @@ static u_short mouse_or_mask[16] = {
0x0000, 0x0000, 0x0000, 0x0000
};
-static int extra_history_size =
+ int sc_history_size = SC_HISTORY_SIZE;
+static int extra_history_size =
SC_MAX_HISTORY_SIZE - SC_HISTORY_SIZE * MAXCONS;
static void none_saver(int blank) { }
static void (*current_saver)(int blank) = none_saver;
static void (*default_saver)(int blank) = none_saver;
-int (*sc_user_ioctl)(dev_t dev, int cmd, caddr_t data,
+ int (*sc_user_ioctl)(dev_t dev, int cmd, caddr_t data,
int flag, struct proc *p) = NULL;
static int sticky_splash = FALSE;
@@ -233,8 +229,6 @@ static struct tty sccons[MAXCONS+2];
#endif
#define SC_MOUSE 128
#define SC_CONSOLE 255
-#define MONO_BUF pa_to_va(0xB0000)
-#define CGA_BUF pa_to_va(0xB8000)
u_short *Crtat;
static const int nsccons = MAXCONS+2;
@@ -243,9 +237,6 @@ static const int nsccons = MAXCONS+2;
+ (offset)) % (scp->history_size)))
#define ISSIGVALID(sig) ((sig) > 0 && (sig) < NSIG)
-/* this should really be in `rtc.h' */
-#define RTC_EQUIPMENT 0x14
-
/* prototypes */
static int scattach(struct isa_device *dev);
static int scparam(struct tty *tp, struct termios *t);
@@ -256,30 +247,26 @@ static void scstart(struct tty *tp);
static void scmousestart(struct tty *tp);
static void scinit(void);
static void scshutdown(int howto, void *arg);
-static void map_mode_table(char *map[], char *table, int max);
-static int map_mode_num(int mode);
-static char *get_mode_param(scr_stat *scp, int mode);
static u_int scgetc(u_int flags);
#define SCGETC_CN 1
#define SCGETC_NONBLOCK 2
static void sccnupdate(scr_stat *scp);
-static scr_stat *get_scr_stat(dev_t dev);
static scr_stat *alloc_scp(void);
static void init_scp(scr_stat *scp);
static void sc_bcopy(scr_stat *scp, u_short *p, int from, int to, int mark);
static int get_scr_num(void);
static timeout_t scrn_timer;
static void scrn_update(scr_stat *scp, int show_cursor);
+static void scrn_saver(void (*saver)(int), int blank);
static void stop_scrn_saver(void (*saver)(int));
static int wait_scrn_saver_stop(void);
-static void clear_screen(scr_stat *scp);
static int switch_scr(scr_stat *scp, u_int next_scr);
static void exchange_scr(void);
-static void move_crsr(scr_stat *scp, int x, int y);
static void scan_esc(scr_stat *scp, u_char c);
+static void ansi_put(scr_stat *scp, u_char *buf, int len);
static void draw_cursor_image(scr_stat *scp);
static void remove_cursor_image(scr_stat *scp);
-static void ansi_put(scr_stat *scp, u_char *buf, int len);
+static void move_crsr(scr_stat *scp, int x, int y);
static u_char *get_fstr(u_int c, u_int *len);
static void history_to_screen(scr_stat *scp);
static int history_up_line(scr_stat *scp);
@@ -287,16 +274,6 @@ static int history_down_line(scr_stat *scp);
static int mask2attr(struct term_stat *term);
static void set_keyboard(int command, int data);
static void update_leds(int which);
-static void set_vgaregs(char *modetable);
-static void read_vgaregs(char *buf);
-#define COMP_IDENTICAL 0
-#define COMP_SIMILAR 1
-#define COMP_DIFFERENT 2
-static int comp_vgaregs(u_char *buf1, u_char *buf2);
-static void dump_vgaregs(u_char *buf);
-#define PARAM_BUFSIZE 6
-static void set_font_mode(u_char *buf);
-static void set_normal_mode(u_char *buf);
static void set_destructive_cursor(scr_stat *scp);
static void set_mouse_pos(scr_stat *scp);
static int skip_spc_right(scr_stat *scp, u_short *p);
@@ -312,12 +289,11 @@ static void draw_mouse_image(scr_stat *scp);
static void remove_mouse_image(scr_stat *scp);
static void draw_cutmarking(scr_stat *scp);
static void remove_cutmarking(scr_stat *scp);
-static void save_palette(void);
static void do_bell(scr_stat *scp, int pitch, int duration);
static timeout_t blink_screen;
#ifdef SC_SPLASH_SCREEN
-static void scsplash_init(void);
-static void scsplash(int show);
+static void scsplash_init(scr_stat *scp);
+static void scsplash_saver(int show);
#define scsplash_stick(stick) (sticky_splash = (stick))
#else
#define scsplash_stick(stick)
@@ -332,7 +308,7 @@ static d_close_t scclose;
static d_read_t scread;
static d_write_t scwrite;
static d_ioctl_t scioctl;
-static d_devtotty_t scdevtotty;
+ d_devtotty_t scdevtotty;
static d_mmap_t scmmap;
#define CDEV_MAJOR 12
@@ -353,7 +329,7 @@ draw_cursor_image(scr_stat *scp)
u_short cursor_image, *ptr = Crtat + (scp->cursor_pos - scp->scr_buf);
u_short prev_image;
- if (VESA_MODE(scp->mode)) {
+ if (ISPIXELSC(scp)) {
sc_bcopy(scp, scp->scr_buf, scp->cursor_pos - scp->scr_buf,
scp->cursor_pos - scp->scr_buf, 1);
return;
@@ -405,7 +381,7 @@ draw_cursor_image(scr_stat *scp)
static void
remove_cursor_image(scr_stat *scp)
{
- if (VESA_MODE(scp->mode))
+ if (ISPIXELSC(scp))
sc_bcopy(scp, scp->scr_buf, scp->cursor_oldpos - scp->scr_buf,
scp->cursor_oldpos - scp->scr_buf, 0);
else
@@ -436,6 +412,12 @@ scprobe(struct isa_device *dev)
printf("sc%d: no video adapter is found.\n", dev->id_unit);
return (0);
}
+ (*biosvidsw.diag)(bootverbose);
+#if defined(VESA) && defined(VM86)
+ if (vesa_load())
+ return FALSE;
+ (*biosvidsw.diag)(bootverbose);
+#endif
sc_port = dev->id_iobase;
if (sckbdprobe(dev->id_unit, dev->id_flags))
@@ -448,99 +430,24 @@ scprobe(struct isa_device *dev)
static int
scvidprobe(int unit, int flags)
{
- /*
- * XXX don't try to `printf' anything here, the console may not have
- * been configured yet.
- */
- u_short volatile *cp;
- u_short was;
- u_int pa;
- u_int segoff;
+ video_adapter_t *adp;
/* do this test only once */
if (init_done != COLD)
- return (Crtat != 0);
-
- /*
- * Finish defaulting crtc variables for a mono screen. Crtat is a
- * bogus common variable so that it can be shared with pcvt, so it
- * can't be statically initialized. XXX.
- */
- Crtat = (u_short *)MONO_BUF;
- crtc_type = KD_MONO;
- /* If CGA memory seems to work, switch to color. */
- cp = (u_short *)CGA_BUF;
- was = *cp;
- *cp = (u_short) 0xA55A;
- bios_video_mode = *(u_char *)pa_to_va(0x449);
- if (bootinfo.bi_vesa == 0x102) {
- bios_video_mode = bootinfo.bi_vesa;
- Crtat = (u_short *)pa_to_va(0xA0000);
- crtc_addr = COLOR_BASE;
- crtc_type = KD_VGA;
- bzero(Crtat, 800*600/8);
- } else if (*cp == 0xA55A) {
- Crtat = (u_short *)CGA_BUF;
- crtc_addr = COLOR_BASE;
- crtc_type = KD_CGA;
- } else {
- cp = Crtat;
- was = *cp;
- *cp = (u_short) 0xA55A;
- if (*cp != 0xA55A) {
- /* no screen at all, bail out */
- Crtat = 0;
- return FALSE;
- }
- }
- *cp = was;
+ return (crtc_type != -1);
- if (!VESA_MODE(bios_video_mode)) {
- /*
- * Check rtc and BIOS date area.
- * XXX: don't use BIOSDATA_EQUIPMENT, it is not a dead copy
- * of RTC_EQUIPMENT. The bit 4 and 5 of the ETC_EQUIPMENT are
- * zeros for EGA and VGA. However, the EGA/VGA BIOS will set
- * these bits in BIOSDATA_EQUIPMENT according to the monitor
- * type detected.
- */
- switch ((rtcin(RTC_EQUIPMENT) >> 4) & 3) { /* bit 4 and 5 */
- case 0: /* EGA/VGA, or nothing */
- crtc_type = KD_EGA;
- /* the color adapter may be in the 40x25 mode... XXX */
- break;
- case 1: /* CGA 40x25 */
- /* switch to the 80x25 mode? XXX */
- /* FALL THROUGH */
- case 2: /* CGA 80x25 */
- /* `crtc_type' has already been set... */
- /* crtc_type = KD_CGA; */
- break;
- case 3: /* MDA */
- /* `crtc_type' has already been set... */
- /* crtc_type = KD_MONO; */
- break;
- }
+ if ((*biosvidsw.init)() <= 0)
+ return FALSE;
+ if ((adp = (*biosvidsw.adapter)(V_ADP_PRIMARY)) == NULL)
+ return FALSE;
- /* is this a VGA or higher ? */
- outb(crtc_addr, 7);
- if (inb(crtc_addr) == 7) {
-
- crtc_type = KD_VGA;
- crtc_vga = TRUE;
- read_vgaregs(vgaregs);
-
- /* Get the BIOS video mode pointer */
- segoff = *(u_int *)pa_to_va(0x4a8);
- pa = ((segoff & 0xffff0000) >> 12) + (segoff & 0xffff);
- if (ISMAPPED(pa, sizeof(u_int))) {
- segoff = *(u_int *)pa_to_va(pa);
- pa = ((segoff & 0xffff0000) >> 12) + (segoff & 0xffff);
- if (ISMAPPED(pa, MODE_PARAM_SIZE))
- video_mode_ptr = (char *)pa_to_va(pa);
- }
- }
- }
+ crtc_type = adp->va_type;
+ crtc_vga = (crtc_type == KD_VGA);
+ crtc_addr = adp->va_crtc_addr;
+ Crtat = (u_short *)adp->va_window;
+ adp_flags = adp->va_flags;
+ initial_video_mode = adp->va_initial_mode;
+ bios_video_mode = adp->va_initial_bios_mode;
return TRUE;
}
@@ -728,48 +635,42 @@ static int
scattach(struct isa_device *dev)
{
scr_stat *scp;
+ video_info_t info;
dev_t cdev = makedev(CDEV_MAJOR, 0);
- char *p;
#ifdef DEVFS
int vc;
#endif
scinit();
flags = dev->id_flags;
- if (crtc_type != KD_VGA || VESA_MODE(bios_video_mode))
+ if (!ISFONTAVAIL(adp_flags))
flags &= ~CHAR_CURSOR;
scp = console[0];
- if (crtc_type == KD_VGA) {
- cut_buffer_size = scp->xsize * scp->ysize + 1;
- cut_buffer = (char *)malloc(cut_buffer_size, M_DEVBUF, M_NOWAIT);
- if (cut_buffer != NULL)
- cut_buffer[0] = '\0';
- }
-
- scp->scr_buf = (u_short *)malloc(scp->xsize*scp->ysize*sizeof(u_short),
- M_DEVBUF, M_NOWAIT);
-
/* copy temporary buffer to final buffer */
- bcopy(sc_buffer, scp->scr_buf, scp->xsize * scp->ysize * sizeof(u_short));
+ scp->scr_buf = NULL;
+ sc_alloc_scr_buffer(scp, FALSE, FALSE);
+ bcopy(sc_buffer, scp->scr_buf, scp->xsize*scp->ysize*sizeof(u_short));
- scp->cursor_pos = scp->cursor_oldpos =
- scp->scr_buf + scp->xpos + scp->ypos * scp->xsize;
- scp->mouse_pos = scp->mouse_oldpos =
- scp->scr_buf + ((scp->mouse_ypos/scp->font_size)*scp->xsize +
- scp->mouse_xpos/8);
+ /* cut buffer is available only when the mouse pointer is used */
+ if (ISMOUSEAVAIL(adp_flags))
+ sc_alloc_cut_buffer(scp, FALSE);
/* initialize history buffer & pointers */
- scp->history_head = scp->history_pos =
- (u_short *)malloc(scp->history_size*sizeof(u_short),
- M_DEVBUF, M_NOWAIT);
- if (scp->history_head != NULL)
- bzero(scp->history_head, scp->history_size*sizeof(u_short));
- scp->history = scp->history_head;
+ sc_alloc_history_buffer(scp, sc_history_size, 0, FALSE);
+
+#if defined(VESA) && defined(VM86)
+ if ((flags & VESA800X600)
+ && ((*biosvidsw.get_info)(scp->adp, M_VESA_800x600, &info) == 0)) {
+ sc_set_graphics_mode(scp, NULL, M_VESA_800x600);
+ sc_set_pixel_mode(scp, NULL, COL, ROW, 16);
+ initial_video_mode = M_VESA_800x600;
+ }
+#endif /* VESA && VM86 */
/* initialize cursor stuff */
- if (!(scp->status & UNKNOWN_MODE))
+ if (!ISGRAPHSC(scp))
draw_cursor_image(scp);
/* get screen update going */
@@ -777,42 +678,13 @@ scattach(struct isa_device *dev)
update_leds(scp->status);
- if ((crtc_type == KD_VGA) && bootverbose) {
- printf("sc%d: BIOS video mode:%d\n", dev->id_unit, bios_video_mode);
- printf("sc%d: VGA registers upon power-up\n", dev->id_unit);
- dump_vgaregs(vgaregs);
- printf("sc%d: video mode:%d\n", dev->id_unit, scp->mode);
- printf("sc%d: VGA registers in BIOS for mode:%d\n",
- dev->id_unit, scp->mode);
- dump_vgaregs(vgaregs2);
- p = get_mode_param(scp, scp->mode);
- if (p != NULL) {
- printf("sc%d: VGA registers to be used for mode:%d\n",
- dev->id_unit, scp->mode);
- dump_vgaregs(p);
- }
- printf("sc%d: rows_offset:%d\n", dev->id_unit, rows_offset);
- }
- if ((crtc_type == KD_VGA) && !VESA_MODE(bios_video_mode)
- && (video_mode_ptr == NULL))
- printf("sc%d: WARNING: video mode switching is only partially supported\n",
- dev->id_unit);
-
printf("sc%d: ", dev->id_unit);
switch(crtc_type) {
case KD_VGA:
- if (VESA_MODE(bios_video_mode))
- printf("Graphics display (VESA mode = 0x%x)", bios_video_mode);
- else if (crtc_addr == MONO_BASE)
- printf("VGA mono");
- else
- printf("VGA color");
+ printf("VGA %s", (adp_flags & V_ADP_COLOR) ? "color" : "mono");
break;
case KD_EGA:
- if (crtc_addr == MONO_BASE)
- printf("EGA mono");
- else
- printf("EGA color");
+ printf("EGA %s", (adp_flags & V_ADP_COLOR) ? "color" : "mono");
break;
case KD_CGA:
printf("CGA");
@@ -820,7 +692,7 @@ scattach(struct isa_device *dev)
case KD_MONO:
case KD_HERCULES:
default:
- printf("MDA/hercules");
+ printf("MDA/Hercules");
break;
}
printf(" <%d virtual consoles, flags=0x%x>\n", MAXCONS, flags);
@@ -896,6 +768,8 @@ scopen(dev_t dev, int flag, int mode, struct proc *p)
return(EBUSY);
if (minor(dev) < MAXCONS && !console[minor(dev)]) {
console[minor(dev)] = alloc_scp();
+ if (ISGRAPHSC(console[minor(dev)]))
+ sc_set_pixel_mode(console[minor(dev)], NULL, COL, ROW, 16);
}
if (minor(dev)<MAXCONS && !tp->t_winsize.ws_col && !tp->t_winsize.ws_row) {
tp->t_winsize.ws_col = console[minor(dev)]->xsize;
@@ -913,7 +787,7 @@ scclose(dev_t dev, int flag, int mode, struct proc *p)
if (!tp)
return(ENXIO);
if (minor(dev) < MAXCONS) {
- scp = get_scr_stat(tp->t_dev);
+ scp = sc_get_scr_stat(tp->t_dev);
if (scp->status & SWITCH_WAIT_ACQ)
wakeup((caddr_t)&scp->smode);
#if not_yet_done
@@ -927,9 +801,9 @@ scclose(dev_t dev, int flag, int mode, struct proc *p)
if (scp->history != NULL) {
free(scp->history, M_DEVBUF);
if (scp->history_size / scp->xsize
- > imax(SC_HISTORY_SIZE, scp->ysize))
+ > imax(sc_history_size, scp->ysize))
extra_history_size += scp->history_size / scp->xsize
- - imax(SC_HISTORY_SIZE, scp->ysize);
+ - imax(sc_history_size, scp->ysize);
}
free(scp, M_DEVBUF);
console[minor(dev)] = NULL;
@@ -1008,10 +882,17 @@ scintr(int unit)
}
}
+#if 0
if (cur_console->status & MOUSE_ENABLED) {
cur_console->status &= ~MOUSE_VISIBLE;
remove_mouse_image(cur_console);
}
+#else
+ if (cur_console->status & MOUSE_VISIBLE) {
+ remove_mouse_image(cur_console);
+ cur_console->status &= ~MOUSE_VISIBLE;
+ }
+#endif
}
static int
@@ -1030,21 +911,25 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
u_int i;
struct tty *tp;
scr_stat *scp;
- u_short *usp;
- char *mp;
+ video_adapter_t *adp;
int s;
tp = scdevtotty(dev);
if (!tp)
return ENXIO;
- scp = get_scr_stat(tp->t_dev);
+ scp = sc_get_scr_stat(tp->t_dev);
/* If there is a user_ioctl function call that first */
if (sc_user_ioctl) {
- if (error = (*sc_user_ioctl)(dev, cmd, data, flag, p))
+ error = (*sc_user_ioctl)(dev, cmd, data, flag, p);
+ if (error != ENOIOCTL)
return error;
}
+ error = sc_vid_ioctl(tp, cmd, data, flag, p);
+ if (error != ENOIOCTL)
+ return error;
+
switch (cmd) { /* process console hardware related ioctl's */
case GIO_ATTR: /* get current attributes */
@@ -1052,18 +937,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return 0;
case GIO_COLOR: /* is this a color console ? */
- if (crtc_addr == COLOR_BASE)
- *(int*)data = 1;
- else
- *(int*)data = 0;
- return 0;
-
- case CONS_CURRENT: /* get current adapter type */
- *(int *)data = crtc_type;
- return 0;
-
- case CONS_GET: /* get current video mode */
- *(int*)data = scp->mode;
+ *(int *)data = (adp_flags & V_ADP_COLOR) ? 1 : 0;
return 0;
case CONS_BLANKTIME: /* set screen saver timeout (0 = no saver) */
@@ -1081,7 +955,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
else
flags &= ~BLINK_CURSOR;
if ((*(int*)data) & 0x02) {
- if (crtc_type != KD_VGA || VESA_MODE(bios_video_mode))
+ if (!ISFONTAVAIL(get_adapter(scp)->va_flags))
return ENXIO;
flags |= CHAR_CURSOR;
} else
@@ -1090,7 +964,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
* The cursor shape is global property; all virtual consoles
* are affected. Update the cursor in the current console...
*/
- if (!(cur_console->status & UNKNOWN_MODE)) {
+ if (!ISGRAPHSC(cur_console)) {
remove_cursor_image(cur_console);
if (flags & CHAR_CURSOR)
set_destructive_cursor(cur_console);
@@ -1117,37 +991,22 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
lines = imax(*(int *)data, scp->ysize);
lines0 = (scp->history != NULL) ?
scp->history_size / scp->xsize : scp->ysize;
+ if (lines0 > imax(sc_history_size, scp->ysize))
+ i = lines0 - imax(sc_history_size, scp->ysize);
+ else
+ i = 0;
/*
* syscons unconditionally allocates buffers upto SC_HISTORY_SIZE
* lines or scp->ysize lines, whichever is larger. A value
* greater than that is allowed, subject to extra_history_size.
*/
- if (lines > imax(lines0, SC_HISTORY_SIZE) + extra_history_size)
- return EINVAL;
+ if (lines > imax(sc_history_size, scp->ysize))
+ if (lines - imax(sc_history_size, scp->ysize) >
+ extra_history_size + i)
+ return EINVAL;
if (cur_console->status & BUFFER_SAVED)
return EBUSY;
- usp = scp->history;
- scp->history = NULL;
- if (usp != NULL)
- free(usp, M_DEVBUF);
- scp->history_size = lines * scp->xsize;
- /*
- * extra_history_size +=
- * (lines0 > imax(SC_HISTORY_SIZE, scp->ysize)) ?
- * lines0 - imax(SC_HISTORY_SIZE, scp->ysize)) : 0;
- * extra_history_size -=
- * (lines > imax(SC_HISTORY_SIZE, scp->ysize)) ?
- * lines - imax(SC_HISTORY_SIZE, scp->ysize)) : 0;
- * lines0 >= ysize && lines >= ysize... Hey, the above can be
- * reduced to the following...
- */
- extra_history_size +=
- imax(lines0, SC_HISTORY_SIZE) - imax(lines, SC_HISTORY_SIZE);
- usp = (u_short *)malloc(scp->history_size * sizeof(u_short),
- M_DEVBUF, M_WAITOK);
- bzero(usp, scp->history_size * sizeof(u_short));
- scp->history_head = scp->history_pos = usp;
- scp->history = usp;
+ sc_alloc_history_buffer(scp, lines, i, TRUE);
return 0;
}
else
@@ -1171,7 +1030,8 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
mouse_info_t *mouse = (mouse_info_t*)data;
mouse_info_t buf;
- if (crtc_type != KD_VGA || VESA_MODE(bios_video_mode))
+ /* FIXME: */
+ if (!ISMOUSEAVAIL(get_adapter(scp)->va_flags))
return ENODEV;
if (cmd == OLD_CONS_MOUSECTL) {
@@ -1220,7 +1080,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return 0;
case MOUSE_SHOW:
- if (!(scp->status & MOUSE_ENABLED)) {
+ if (ISTEXTSC(scp) && !(scp->status & MOUSE_ENABLED)) {
scp->status |= (MOUSE_ENABLED | MOUSE_VISIBLE);
scp->mouse_oldpos = scp->mouse_pos;
mark_all(scp);
@@ -1231,7 +1091,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
break;
case MOUSE_HIDE:
- if (scp->status & MOUSE_ENABLED) {
+ if (ISTEXTSC(scp) && (scp->status & MOUSE_ENABLED)) {
scp->status &= ~(MOUSE_ENABLED | MOUSE_VISIBLE);
mark_all(scp);
return 0;
@@ -1276,7 +1136,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
if (mouse_status.flags == 0)
return 0;
- if (cur_console->status & MOUSE_ENABLED)
+ if (ISTEXTSC(cur_console) && (cur_console->status & MOUSE_ENABLED))
cur_console->status |= MOUSE_VISIBLE;
if ((MOUSE_TTY)->t_state & TS_ISOPEN) {
@@ -1321,7 +1181,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
else if (mouse->operation == MOUSE_ACTION && cut_buffer != NULL) {
/* process button presses */
if ((cur_console->mouse_buttons ^ mouse->u.data.buttons) &&
- !(cur_console->status & UNKNOWN_MODE)) {
+ ISTEXTSC(cur_console)) {
cur_console->mouse_buttons = mouse->u.data.buttons;
if (cur_console->mouse_buttons & MOUSE_BUTTON1DOWN)
mouse_cut_start(cur_console);
@@ -1358,7 +1218,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
if (mouse_status.flags == 0)
return 0;
- if (cur_console->status & MOUSE_ENABLED)
+ if (ISTEXTSC(cur_console) && (cur_console->status & MOUSE_ENABLED))
cur_console->status |= MOUSE_VISIBLE;
if ((MOUSE_TTY)->t_state & TS_ISOPEN) {
@@ -1387,7 +1247,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
break;
}
- if ((cur_console->status & UNKNOWN_MODE) || (cut_buffer == NULL))
+ if (!ISTEXTSC(cur_console) || (cut_buffer == NULL))
break;
switch (mouse->u.event.id) {
@@ -1567,18 +1427,41 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return 0;
case CONS_IDLE: /* see if the screen has been idle */
- *(int *)data = (scrn_idle && !(cur_console->status & UNKNOWN_MODE));
+ /*
+ * When the screen is in the GRAPHICS_MODE or UNKNOWN_MODE,
+ * the user process may have been writing something on the
+ * screen and syscons is not aware of it. Declare the screen
+ * is NOT idle if it is in one of these modes. But there is
+ * an exception to it; if a screen saver is running in the
+ * graphics mode in the current screen, we should say that the
+ * screen has been idle.
+ */
+ *(int *)data = scrn_idle
+ && (!ISGRAPHSC(cur_console)
+ || (cur_console->status & SAVER_RUNNING));
return 0;
case CONS_SAVERMODE: /* set saver mode */
switch(*(int *)data) {
case CONS_USR_SAVER:
- /* if a LKM screen saver is running, it will eventually stop... */
+ /* if a LKM screen saver is running, stop it first. */
+ scsplash_stick(FALSE);
saver_mode = *(int *)data;
+ s = spltty();
+ if ((error = wait_scrn_saver_stop())) {
+ splx(s);
+ return error;
+ }
+ scp->status |= SAVER_RUNNING;
scsplash_stick(TRUE);
+ splx(s);
break;
case CONS_LKM_SAVER:
+ s = spltty();
+ if ((saver_mode == CONS_USR_SAVER) && (scp->status & SAVER_RUNNING))
+ scp->status &= ~SAVER_RUNNING;
saver_mode = *(int *)data;
+ splx(s);
break;
default:
return EINVAL;
@@ -1597,226 +1480,6 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
splx(s);
return 0;
- /* VGA TEXT MODES */
- case SW_VGA_C40x25:
- case SW_VGA_C80x25: case SW_VGA_M80x25:
- case SW_VGA_C80x30: case SW_VGA_M80x30:
- case SW_VGA_C80x50: case SW_VGA_M80x50:
- case SW_VGA_C80x60: case SW_VGA_M80x60:
- case SW_B40x25: case SW_C40x25:
- case SW_B80x25: case SW_C80x25:
- case SW_ENH_B40x25: case SW_ENH_C40x25:
- case SW_ENH_B80x25: case SW_ENH_C80x25:
- case SW_ENH_B80x43: case SW_ENH_C80x43:
- case SW_EGAMONO80x25:
-
- if (crtc_type != KD_VGA)
- return ENODEV;
- mp = get_mode_param(scp, cmd & 0xff);
- if (mp == NULL)
- return ENODEV;
-
- s = spltty();
- if ((error = wait_scrn_saver_stop())) {
- splx(s);
- return error;
- }
-
- scp->status &= ~MOUSE_VISIBLE;
- remove_cutmarking(scp);
- if (scp->history != NULL)
- i = imax(scp->history_size / scp->xsize
- - imax(SC_HISTORY_SIZE, scp->ysize), 0);
- else
- i = 0;
- switch (cmd & 0xff) {
- case M_VGA_C80x60: case M_VGA_M80x60:
- if (!(fonts_loaded & FONT_8)) {
- splx(s);
- return EINVAL;
- }
- /*
- * This is a kludge to fend off scrn_update() while we
- * muck around with scp. XXX
- */
- scp->status |= UNKNOWN_MODE;
- scp->xsize = 80;
- scp->ysize = 60;
- scp->font_size = 8;
- break;
- case M_VGA_C80x50: case M_VGA_M80x50:
- if (!(fonts_loaded & FONT_8)) {
- splx(s);
- return EINVAL;
- }
- scp->status |= UNKNOWN_MODE;
- scp->xsize = 80;
- scp->ysize = 50;
- scp->font_size = 8;
- break;
- case M_ENH_B80x43: case M_ENH_C80x43:
- if (!(fonts_loaded & FONT_8)) {
- splx(s);
- return EINVAL;
- }
- scp->status |= UNKNOWN_MODE;
- scp->xsize = 80;
- scp->ysize = 43;
- scp->font_size = 8;
- break;
- case M_VGA_C80x30: case M_VGA_M80x30:
- scp->status |= UNKNOWN_MODE;
- scp->xsize = 80;
- scp->ysize = 30;
- scp->font_size = mp[2];
- break;
- case M_ENH_C40x25: case M_ENH_B40x25:
- case M_ENH_C80x25: case M_ENH_B80x25:
- case M_EGAMONO80x25:
- if (!(fonts_loaded & FONT_14)) {
- splx(s);
- return EINVAL;
- }
- /* FALL THROUGH */
- default:
- if ((cmd & 0xff) > M_VGA_CG320) {
- splx(s);
- return EINVAL;
- }
- scp->status |= UNKNOWN_MODE;
- scp->xsize = mp[0];
- scp->ysize = mp[1] + rows_offset;
- scp->font_size = mp[2];
- break;
- }
-
- scp->mode = cmd & 0xff;
- scp->xpixel = scp->xsize * 8;
- scp->ypixel = scp->ysize * scp->font_size;
- free(scp->scr_buf, M_DEVBUF);
- scp->scr_buf = (u_short *)
- malloc(scp->xsize*scp->ysize*sizeof(u_short), M_DEVBUF, M_WAITOK);
- /* move the text cursor to the home position */
- move_crsr(scp, 0, 0);
- /* move the mouse cursor at the center of the screen */
- scp->mouse_xpos = scp->xpixel / 2;
- scp->mouse_ypos = scp->ypixel / 2;
- scp->mouse_pos = scp->mouse_oldpos =
- scp->scr_buf + (scp->mouse_ypos / scp->font_size) * scp->xsize
- + scp->mouse_xpos / 8;
- /* allocate a larger cut buffer if necessary */
- if ((cut_buffer == NULL)
- || (cut_buffer_size < scp->xsize * scp->ysize + 1)) {
- if (cut_buffer != NULL)
- free(cut_buffer, M_DEVBUF);
- cut_buffer_size = scp->xsize * scp->ysize + 1;
- cut_buffer = (char *)malloc(cut_buffer_size, M_DEVBUF, M_NOWAIT);
- if (cut_buffer != NULL)
- cut_buffer[0] = '\0';
- }
- splx(s);
-
- usp = scp->history;
- scp->history = NULL;
- if (usp != NULL) {
- free(usp, M_DEVBUF);
- extra_history_size += i;
- }
- scp->history_size = imax(SC_HISTORY_SIZE, scp->ysize) * scp->xsize;
- usp = (u_short *)malloc(scp->history_size * sizeof(u_short),
- M_DEVBUF, M_NOWAIT);
- if (usp != NULL)
- bzero(usp, scp->history_size * sizeof(u_short));
- scp->history_head = scp->history_pos = usp;
- scp->history = usp;
- if (scp == cur_console)
- set_mode(scp);
- clear_screen(scp);
- scp->status &= ~UNKNOWN_MODE;
-
- if (tp->t_winsize.ws_col != scp->xsize
- || tp->t_winsize.ws_row != scp->ysize) {
- tp->t_winsize.ws_col = scp->xsize;
- tp->t_winsize.ws_row = scp->ysize;
- pgsignal(tp->t_pgrp, SIGWINCH, 1);
- }
- return 0;
-
- /* GRAPHICS MODES */
- case SW_BG320: case SW_BG640:
- case SW_CG320: case SW_CG320_D: case SW_CG640_E:
- case SW_CG640x350: case SW_ENH_CG640:
- case SW_BG640x480: case SW_CG640x480: case SW_VGA_CG320:
-
- if (crtc_type != KD_VGA)
- return ENODEV;
- mp = get_mode_param(scp, cmd & 0xff);
- if (mp == NULL)
- return ENODEV;
-
- s = spltty();
- if ((error = wait_scrn_saver_stop())) {
- splx(s);
- return error;
- }
-
- scp->status &= ~MOUSE_VISIBLE;
- remove_cutmarking(scp);
- scp->status |= UNKNOWN_MODE; /* graphics mode */
- scp->mode = cmd & 0xFF;
- scp->xpixel = mp[0] * 8;
- scp->ypixel = (mp[1] + rows_offset) * mp[2];
- scp->font_size = FONT_NONE;
- /* move the mouse cursor at the center of the screen */
- scp->mouse_xpos = scp->xpixel / 2;
- scp->mouse_ypos = scp->ypixel / 2;
- splx(s);
-
- if (scp == cur_console)
- set_mode(scp);
- /* clear_graphics();*/
-
- if (tp->t_winsize.ws_xpixel != scp->xpixel
- || tp->t_winsize.ws_ypixel != scp->ypixel) {
- tp->t_winsize.ws_xpixel = scp->xpixel;
- tp->t_winsize.ws_ypixel = scp->ypixel;
- pgsignal(tp->t_pgrp, SIGWINCH, 1);
- }
- return 0;
-
- case SW_VGA_MODEX:
- if (crtc_type != KD_VGA)
- return ENODEV;
- mp = get_mode_param(scp, cmd & 0xff);
- if (mp == NULL)
- return ENODEV;
-
- s = spltty();
- if ((error = wait_scrn_saver_stop())) {
- splx(s);
- return error;
- }
-
- scp->status &= ~MOUSE_VISIBLE;
- remove_cutmarking(scp);
- scp->status |= UNKNOWN_MODE; /* graphics mode */
- scp->mode = cmd & 0xFF;
- scp->xpixel = 320;
- scp->ypixel = 240;
- scp->font_size = FONT_NONE;
- splx(s);
-
- if (scp == cur_console)
- set_mode(scp);
- /* clear_graphics();*/
- if (tp->t_winsize.ws_xpixel != scp->xpixel
- || tp->t_winsize.ws_ypixel != scp->ypixel) {
- tp->t_winsize.ws_xpixel = scp->xpixel;
- tp->t_winsize.ws_ypixel = scp->ypixel;
- pgsignal(tp->t_pgrp, SIGWINCH, 1);
- }
- return 0;
-
case VT_SETMODE: /* set screen switcher mode */
{
struct vt_mode *mode;
@@ -1839,7 +1502,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return 0;
case VT_RELDISP: /* screen switcher ioctl */
- switch(*data) {
+ switch(*(int *)data) {
case VT_FALSE: /* user refuses to release screen, abort */
if (scp == old_scp && (scp->status & SWITCH_WAIT_REL)) {
old_scp->status &= ~SWITCH_WAIT_REL;
@@ -1879,32 +1542,32 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
for (i = 0; i < MAXCONS; i++) {
tp = VIRTUAL_TTY(i);
if (!(tp->t_state & TS_ISOPEN)) {
- *data = i + 1;
+ *(int *)data = i + 1;
return 0;
}
}
return EINVAL;
case VT_ACTIVATE: /* switch to screen *data */
- return switch_scr(scp, (*data) - 1);
+ return switch_scr(scp, *(int *)data - 1);
case VT_WAITACTIVE: /* wait for switch to occur */
- if (*data > MAXCONS || *data < 0)
+ if (*(int *)data > MAXCONS || *(int *)data < 0)
return EINVAL;
- if (minor(dev) == (*data) - 1)
+ if (minor(dev) == *(int *)data - 1)
return 0;
- if (*data == 0) {
+ if (*(int *)data == 0) {
if (scp == cur_console)
return 0;
}
else
- scp = console[(*data) - 1];
+ scp = console[*(int *)data - 1];
while ((error=tsleep((caddr_t)&scp->smode, PZERO|PCATCH,
"waitvt", 0)) == ERESTART) ;
return error;
case VT_GETACTIVE:
- *data = get_scr_num()+1;
+ *(int *)data = get_scr_num()+1;
return 0;
case KDENABIO: /* allow io operations */
@@ -1920,102 +1583,28 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
p->p_md.md_regs->tf_eflags &= ~PSL_IOPL;
return 0;
- case KDSETMODE: /* set current mode of this (virtual) console */
- switch (*data) {
- case KD_TEXT: /* switch to TEXT (known) mode */
- /* restore fonts & palette ! */
- if (crtc_type == KD_VGA) {
- if (!VESA_MODE(scp->mode)) {
-#if 0
- /*
- * FONT KLUDGE
- * Don't load fonts for now... XXX
- */
- if (fonts_loaded & FONT_8)
- copy_font(LOAD, FONT_8, font_8);
- if (fonts_loaded & FONT_14)
- copy_font(LOAD, FONT_14, font_14);
- if (fonts_loaded & FONT_16)
- copy_font(LOAD, FONT_16, font_16);
-#endif
- }
- load_palette(palette);
- }
-
- /* move hardware cursor out of the way */
- outb(crtc_addr, 14);
- outb(crtc_addr + 1, 0xff);
- outb(crtc_addr, 15);
- outb(crtc_addr + 1, 0xff);
-
- /* FALL THROUGH */
-
- case KD_TEXT1: /* switch to TEXT (known) mode */
- s = spltty();
- if ((error = wait_scrn_saver_stop())) {
- splx(s);
- return error;
- }
- scp->status &= ~MOUSE_VISIBLE;
- remove_cutmarking(scp);
- scp->status |= UNKNOWN_MODE;
- splx(s);
- /* no restore fonts & palette */
- if (crtc_type == KD_VGA)
- set_mode(scp);
- scp->status &= ~UNKNOWN_MODE;
- clear_screen(scp);
- return 0;
-
- case KD_GRAPHICS: /* switch to GRAPHICS (unknown) mode */
- s = spltty();
- if ((error = wait_scrn_saver_stop())) {
- splx(s);
- return error;
- }
- scp->status &= ~MOUSE_VISIBLE;
- remove_cutmarking(scp);
- scp->status |= UNKNOWN_MODE;
- splx(s);
- return 0;
- default:
+ case KDSKBSTATE: /* set keyboard state (locks) */
+ if (*(int *)data & ~LOCK_KEY_MASK)
return EINVAL;
- }
- /* NOT REACHED */
-
- case KDGETMODE: /* get current mode of this (virtual) console */
- *data = (scp->status & UNKNOWN_MODE) ? KD_GRAPHICS : KD_TEXT;
- return 0;
-
- case KDSBORDER: /* set border color of this (virtual) console */
- scp->border = *data;
+ scp->status &= ~LOCK_KEY_MASK;
+ scp->status |= *(int *)data;
if (scp == cur_console)
- set_border(scp->border);
+ update_leds(scp->status);
return 0;
- case KDSKBSTATE: /* set keyboard state (locks) */
- if (*data >= 0 && *data <= LOCK_KEY_MASK) {
- scp->status &= ~LOCK_KEY_MASK;
- scp->status |= *data;
- if (scp == cur_console)
- update_leds(scp->status);
- return 0;
- }
- return EINVAL;
-
case KDGKBSTATE: /* get keyboard state (locks) */
- *data = scp->status & LOCK_KEY_MASK;
+ *(int *)data = scp->status & LOCK_KEY_MASK;
return 0;
case KDSETRAD: /* set keyboard repeat & delay rates */
- if (*data & 0x80)
+ if (*(int *)data & ~0x7f)
return EINVAL;
if (sc_kbdc != NULL)
- set_keyboard(KBDC_SET_TYPEMATIC, *data);
+ set_keyboard(KBDC_SET_TYPEMATIC, *(int *)data);
return 0;
case KDSKBMODE: /* set keyboard mode */
- switch (*data) {
+ switch (*(int *)data) {
case K_RAW: /* switch to RAW scancode mode */
scp->status &= ~KBD_CODE_MODE;
scp->status |= KBD_RAW_MODE;
@@ -2037,7 +1626,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
/* NOT REACHED */
case KDGKBMODE: /* get keyboard mode */
- *data = (scp->status & KBD_RAW_MODE) ? K_RAW :
+ *(int *)data = (scp->status & KBD_RAW_MODE) ? K_RAW :
((scp->status & KBD_CODE_MODE) ? K_CODE : K_XLATE);
return 0;
@@ -2074,21 +1663,20 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return 0;
case KDGKBTYPE: /* get keyboard type */
- *data = 0; /* type not known (yet) */
+ *(int *)data = 0; /* type not known (yet) */
return 0;
case KDSETLED: /* set keyboard LED status */
- if (*data >= 0 && *data <= LED_MASK) {
- scp->status &= ~LED_MASK;
- scp->status |= *data;
- if (scp == cur_console)
- update_leds(scp->status);
- return 0;
- }
- return EINVAL;
+ if (*(int *)data & ~LED_MASK)
+ return EINVAL;
+ scp->status &= ~LED_MASK;
+ scp->status |= *(int *)data;
+ if (scp == cur_console)
+ update_leds(scp->status);
+ return 0;
case KDGETLED: /* get keyboard LED status */
- *data = scp->status & LED_MASK;
+ *(int *)data = scp->status & LED_MASK;
return 0;
case GETFKEY: /* get functionkey string */
@@ -2143,7 +1731,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return 0;
case PIO_FONT8x8: /* set 8x8 dot font */
- if (crtc_type != KD_VGA)
+ if (!ISFONTAVAIL(get_adapter(scp)->va_flags))
return ENXIO;
bcopy(data, font_8, 8*256);
fonts_loaded |= FONT_8;
@@ -2152,17 +1740,12 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
* Always use the font page #0. XXX
* Don't load if the current font size is not 8x8.
*/
- if (!VESA_MODE(cur_console->mode)
- && !(cur_console->status & UNKNOWN_MODE)
- && (cur_console->font_size < 14)) {
- copy_font(LOAD, FONT_8, font_8);
- if (flags & CHAR_CURSOR)
- set_destructive_cursor(cur_console);
- }
+ if (ISTEXTSC(cur_console) && (cur_console->font_size < 14))
+ copy_font(cur_console, LOAD, 8, font_8);
return 0;
case GIO_FONT8x8: /* get 8x8 dot font */
- if (crtc_type != KD_VGA)
+ if (!ISFONTAVAIL(get_adapter(scp)->va_flags))
return ENXIO;
if (fonts_loaded & FONT_8) {
bcopy(font_8, data, 8*256);
@@ -2172,7 +1755,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return ENXIO;
case PIO_FONT8x14: /* set 8x14 dot font */
- if (crtc_type != KD_VGA)
+ if (!ISFONTAVAIL(get_adapter(scp)->va_flags))
return ENXIO;
bcopy(data, font_14, 14*256);
fonts_loaded |= FONT_14;
@@ -2181,17 +1764,13 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
* Always use the font page #0. XXX
* Don't load if the current font size is not 8x14.
*/
- if (!VESA_MODE(cur_console->mode)
- && !(cur_console->status & UNKNOWN_MODE)
- && (cur_console->font_size >= 14) && (cur_console->font_size < 16)) {
- copy_font(LOAD, FONT_14, font_14);
- if (flags & CHAR_CURSOR)
- set_destructive_cursor(cur_console);
- }
+ if (ISTEXTSC(cur_console)
+ && (cur_console->font_size >= 14) && (cur_console->font_size < 16))
+ copy_font(cur_console, LOAD, 14, font_14);
return 0;
case GIO_FONT8x14: /* get 8x14 dot font */
- if (crtc_type != KD_VGA)
+ if (!ISFONTAVAIL(get_adapter(scp)->va_flags))
return ENXIO;
if (fonts_loaded & FONT_14) {
bcopy(font_14, data, 14*256);
@@ -2201,7 +1780,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return ENXIO;
case PIO_FONT8x16: /* set 8x16 dot font */
- if (crtc_type != KD_VGA)
+ if (!ISFONTAVAIL(get_adapter(scp)->va_flags))
return ENXIO;
bcopy(data, font_16, 16*256);
fonts_loaded |= FONT_16;
@@ -2210,17 +1789,12 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
* Always use the font page #0. XXX
* Don't load if the current font size is not 8x16.
*/
- if (!VESA_MODE(cur_console->mode)
- && !(cur_console->status & UNKNOWN_MODE)
- && (cur_console->font_size >= 16)) {
- copy_font(LOAD, FONT_16, font_16);
- if (flags & CHAR_CURSOR)
- set_destructive_cursor(cur_console);
- }
+ if (ISTEXTSC(cur_console) && (cur_console->font_size >= 16))
+ copy_font(cur_console, LOAD, 16, font_16);
return 0;
case GIO_FONT8x16: /* get 8x16 dot font */
- if (crtc_type != KD_VGA)
+ if (!ISFONTAVAIL(get_adapter(scp)->va_flags))
return ENXIO;
if (fonts_loaded & FONT_16) {
bcopy(font_16, data, 16*256);
@@ -2247,7 +1821,7 @@ scstart(struct tty *tp)
struct clist *rbp;
int s, len;
u_char buf[PCBURST];
- scr_stat *scp = get_scr_stat(tp->t_dev);
+ scr_stat *scp = sc_get_scr_stat(tp->t_dev);
if (scp->status & SLKED || blink_in_progress)
return; /* XXX who repeats the call when the above flags are cleared? */
@@ -2329,7 +1903,7 @@ sccnputc(dev_t dev, int c)
scp->term = kernel_console;
current_default = &kernel_default;
- if (scp == cur_console && !(scp->status & UNKNOWN_MODE))
+ if (scp == cur_console && !ISGRAPHSC(scp))
remove_cursor_image(scp);
buf[0] = c;
ansi_put(scp, buf, 1);
@@ -2384,25 +1958,28 @@ sccnupdate(scr_stat *scp)
if (font_loading_in_progress)
return;
- if (panicstr) {
+ if (panicstr || shutdown_in_progress) {
scsplash_stick(FALSE);
run_scrn_saver = FALSE;
+ } else if (scp != cur_console) {
+ return;
}
+
if (!run_scrn_saver)
scrn_idle = FALSE;
if ((saver_mode != CONS_LKM_SAVER) || !scrn_idle)
- if (scrn_blanked > 0)
+ if (scp->status & SAVER_RUNNING)
stop_scrn_saver(current_saver);
if (scp != cur_console || blink_in_progress || switch_in_progress)
return;
- if ((scp->status & UNKNOWN_MODE) == 0 && scrn_blanked <= 0)
+ if (!ISGRAPHSC(scp) && !(scp->status & SAVER_RUNNING))
scrn_update(scp, TRUE);
}
-static scr_stat
-*get_scr_stat(dev_t dev)
+scr_stat
+*sc_get_scr_stat(dev_t dev)
{
int unit = minor(dev);
@@ -2461,6 +2038,8 @@ scrn_timer(void *arg)
scintr(0);
}
+ scp = cur_console;
+
/* should we stop the screen saver? */
getmicrouptime(&tv);
if (panicstr || shutdown_in_progress) {
@@ -2476,7 +2055,7 @@ scrn_timer(void *arg)
run_scrn_saver = TRUE;
}
if ((saver_mode != CONS_LKM_SAVER) || !scrn_idle)
- if (scrn_blanked > 0)
+ if (scp->status & SAVER_RUNNING)
stop_scrn_saver(current_saver);
/* should we just return ? */
@@ -2488,14 +2067,13 @@ scrn_timer(void *arg)
}
/* Update the screen */
- scp = cur_console;
- if ((scp->status & UNKNOWN_MODE) == 0 && scrn_blanked <= 0)
+ if (!ISGRAPHSC(scp) && !(scp->status & SAVER_RUNNING))
scrn_update(scp, TRUE);
/* should we activate the screen saver? */
if ((saver_mode == CONS_LKM_SAVER) && scrn_idle)
- if ((scp->status & UNKNOWN_MODE) == 0 || scrn_blanked > 0)
- (*current_saver)(TRUE);
+ if (!ISGRAPHSC(scp) || (scp->status & SAVER_RUNNING))
+ scrn_saver(current_saver, TRUE);
if (arg)
timeout(scrn_timer, (void *)TRUE, hz / 25);
@@ -2583,9 +2161,9 @@ add_scrn_saver(void (*this_saver)(int))
if (current_saver != default_saver)
return EBUSY;
- current_saver = this_saver;
+ run_scrn_saver = FALSE;
saver_mode = CONS_LKM_SAVER;
- run_scrn_saver = (scrn_blank_time > 0);
+ current_saver = this_saver;
return 0;
}
@@ -2613,9 +2191,21 @@ remove_scrn_saver(void (*this_saver)(int))
}
static void
+scrn_saver(void (*saver)(int), int blank)
+{
+ static int busy = FALSE;
+
+ if (busy)
+ return;
+ busy = TRUE;
+ (*saver)(blank);
+ busy = FALSE;
+}
+
+static void
stop_scrn_saver(void (*saver)(int))
{
- (*saver)(FALSE);
+ scrn_saver(saver, FALSE);
run_scrn_saver = FALSE;
/* the screen saver may have chosen not to stop after all... */
if (scrn_blanked > 0)
@@ -2632,8 +2222,8 @@ wait_scrn_saver_stop(void)
{
int error = 0;
- run_scrn_saver = FALSE;
while (scrn_blanked > 0) {
+ run_scrn_saver = FALSE;
error = tsleep((caddr_t)&scrn_blanked, PZERO | PCATCH, "scrsav", 0);
run_scrn_saver = FALSE;
if (error != ERESTART)
@@ -2642,8 +2232,8 @@ wait_scrn_saver_stop(void)
return error;
}
-static void
-clear_screen(scr_stat *scp)
+void
+sc_clear_screen(scr_stat *scp)
{
move_crsr(scp, 0, 0);
scp->cursor_oldpos = scp->cursor_pos;
@@ -2668,8 +2258,7 @@ switch_scr(scr_stat *scp, u_int next_scr)
switch_in_progress = FALSE;
if (next_scr >= MAXCONS || switch_in_progress ||
- (cur_console->smode.mode == VT_AUTO
- && cur_console->status & UNKNOWN_MODE)) {
+ (cur_console->smode.mode == VT_AUTO && ISGRAPHSC(cur_console))) {
do_bell(scp, BELL_PITCH, BELL_DURATION);
return EINVAL;
}
@@ -2721,25 +2310,26 @@ exchange_scr(void)
{
move_crsr(old_scp, old_scp->xpos, old_scp->ypos);
cur_console = new_scp;
- if (old_scp->mode != new_scp->mode || (old_scp->status & UNKNOWN_MODE)){
- if (crtc_type == KD_VGA)
+ if (old_scp->mode != new_scp->mode || ISUNKNOWNSC(old_scp)) {
+ if (adp_flags & V_ADP_MODECHANGE)
set_mode(new_scp);
}
move_crsr(new_scp, new_scp->xpos, new_scp->ypos);
- if (!(new_scp->status & UNKNOWN_MODE) && (flags & CHAR_CURSOR))
+ if (ISTEXTSC(new_scp) && (flags & CHAR_CURSOR))
set_destructive_cursor(new_scp);
- if ((old_scp->status & UNKNOWN_MODE) && crtc_type == KD_VGA)
- load_palette(palette);
+ if (ISGRAPHSC(old_scp))
+ load_palette(new_scp, palette);
if (old_scp->status & KBD_RAW_MODE || new_scp->status & KBD_RAW_MODE ||
old_scp->status & KBD_CODE_MODE || new_scp->status & KBD_CODE_MODE)
shfts = ctls = alts = agrs = metas = accents = 0;
- set_border(new_scp->border);
+ set_border(new_scp, new_scp->border);
update_leds(new_scp->status);
delayed_next_scr = FALSE;
mark_all(new_scp);
- if (new_scp->mode == 0x102) {
- bzero(Crtat, 800*600/8);
- }
+
+ /* FIXME: the screen size may be larger than a 64K segment. */
+ if (ISPIXELSC(new_scp))
+ bzero(Crtat, new_scp->xpixel*new_scp->ypixel/8);
}
static void
@@ -2788,7 +2378,7 @@ scan_esc(scr_stat *scp, u_char c)
return;
#endif
case 'c': /* Clear screen & home */
- clear_screen(scp);
+ sc_clear_screen(scp);
break;
case '(': /* iso-2022: designate 94 character set to G0 */
@@ -2874,7 +2464,7 @@ scan_esc(scr_stat *scp, u_char c)
scp->cursor_pos,
scp->scr_buf + scp->xsize * scp->ysize - scp->cursor_pos);
mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
- mark_for_update(scp, scp->xsize * scp->ysize);
+ mark_for_update(scp, scp->xsize * scp->ysize - 1);
remove_cutmarking(scp);
break;
case 1: /* clear from beginning of display to cursor */
@@ -2936,7 +2526,7 @@ scan_esc(scr_stat *scp, u_char c)
fillw(scp->term.cur_color | scr_map[0x20], src,
n * scp->xsize);
mark_for_update(scp, scp->ypos * scp->xsize);
- mark_for_update(scp, scp->xsize * scp->ysize);
+ mark_for_update(scp, scp->xsize * scp->ysize - 1);
break;
case 'M': /* Delete n lines */
@@ -2951,7 +2541,7 @@ scan_esc(scr_stat *scp, u_char c)
fillw(scp->term.cur_color | scr_map[0x20], src,
n * scp->xsize);
mark_for_update(scp, scp->ypos * scp->xsize);
- mark_for_update(scp, scp->xsize * scp->ysize);
+ mark_for_update(scp, scp->xsize * scp->ysize - 1);
break;
case 'P': /* Delete n chars */
@@ -3192,7 +2782,7 @@ scan_esc(scr_stat *scp, u_char c)
if (scp->term.num_param == 1) {
scp->border=scp->term.param[0] & 0xff;
if (scp == cur_console)
- set_border(scp->border);
+ set_border(cur_console, scp->border);
}
break;
@@ -3209,8 +2799,8 @@ scan_esc(scr_stat *scp, u_char c)
flags |= BLINK_CURSOR;
else
flags &= ~BLINK_CURSOR;
- if ((scp->term.param[0] & 0x02) &&
- crtc_type == KD_VGA && !VESA_MODE(bios_video_mode))
+ if ((scp->term.param[0] & 0x02)
+ && ISFONTAVAIL(get_adapter(scp)->va_flags))
flags |= CHAR_CURSOR;
else
flags &= ~CHAR_CURSOR;
@@ -3223,9 +2813,9 @@ scan_esc(scr_stat *scp, u_char c)
* The cursor shape is global property; all virtual consoles
* are affected. Update the cursor in the current console...
*/
- if (!(cur_console->status & UNKNOWN_MODE)) {
+ if (!ISGRAPHSC(cur_console)) {
remove_cursor_image(cur_console);
- if (crtc_type == KD_VGA && (flags & CHAR_CURSOR))
+ if (flags & CHAR_CURSOR)
set_destructive_cursor(cur_console);
draw_cursor_image(cur_console);
}
@@ -3366,7 +2956,7 @@ outloop:
break;
case 0x0c: /* form feed, clears screen */
- clear_screen(scp);
+ sc_clear_screen(scp);
break;
case 0x0d: /* return, return to pos 0 */
@@ -3413,42 +3003,17 @@ outloop:
static void
scinit(void)
{
- u_int hw_cursor;
+ int col;
+ int row;
u_int i;
if (init_done != COLD)
return;
init_done = WARM;
- /*
- * Ensure a zero start address. This is mainly to recover after
- * switching from pcvt using userconfig(). The registers are w/o
- * for old hardware so it's too hard to relocate the active screen
- * memory.
- */
- outb(crtc_addr, 12);
- outb(crtc_addr + 1, 0);
- outb(crtc_addr, 13);
- outb(crtc_addr + 1, 0);
-
- /* extract cursor location */
- outb(crtc_addr, 14);
- hw_cursor = inb(crtc_addr + 1) << 8;
- outb(crtc_addr, 15);
- hw_cursor |= inb(crtc_addr + 1);
-
- /*
- * Validate cursor location. It may be off the screen. Then we must
- * not use it for the initial buffer offset.
- */
- if (hw_cursor >= ROW * COL)
- hw_cursor = (ROW - 1) * COL;
-
- /* move hardware cursor out of the way */
- outb(crtc_addr, 14);
- outb(crtc_addr + 1, 0xff);
- outb(crtc_addr, 15);
- outb(crtc_addr + 1, 0xff);
+ /* extract the hardware cursor location and move it out of the way */
+ (*biosvidsw.read_hw_cursor)(V_ADP_PRIMARY, &col, &row);
+ (*biosvidsw.set_hw_cursor)(V_ADP_PRIMARY, -1, -1);
/* set up the first console */
current_default = &user_default;
@@ -3456,51 +3021,22 @@ scinit(void)
init_scp(console[0]);
cur_console = console[0];
- /* discard the video mode table if we are not familiar with it... */
- if (video_mode_ptr) {
- bzero(mode_map, sizeof(mode_map));
- bcopy(video_mode_ptr + MODE_PARAM_SIZE*console[0]->mode,
- vgaregs2, sizeof(vgaregs2));
- switch (comp_vgaregs(vgaregs, video_mode_ptr
- + MODE_PARAM_SIZE*console[0]->mode)) {
- case COMP_IDENTICAL:
- map_mode_table(mode_map, video_mode_ptr, M_VGA_CG320 + 1);
- /*
- * This is a kludge for Toshiba DynaBook SS433 whose BIOS video
- * mode table entry has the actual # of rows at the offset 1;
- * BIOSes from other manufacturers store the # of rows - 1 there.
- * XXX
- */
- rows_offset = vgaregs[1] + 1
- - video_mode_ptr[MODE_PARAM_SIZE*console[0]->mode + 1];
- break;
- case COMP_SIMILAR:
- map_mode_table(mode_map, video_mode_ptr, M_VGA_CG320 + 1);
- mode_map[console[0]->mode] = vgaregs;
- rows_offset = vgaregs[1] + 1
- - video_mode_ptr[MODE_PARAM_SIZE*console[0]->mode + 1];
- vgaregs[1] -= rows_offset - 1;
- break;
- case COMP_DIFFERENT:
- default:
- video_mode_ptr = NULL;
- mode_map[console[0]->mode] = vgaregs;
- rows_offset = 1;
- break;
- }
- }
-
/* copy screen to temporary buffer */
- if (!VESA_MODE(console[0]->mode))
+ if (ISTEXTSC(console[0]))
generic_bcopy(Crtat, sc_buffer,
console[0]->xsize * console[0]->ysize * sizeof(u_short));
console[0]->scr_buf = console[0]->mouse_pos = console[0]->mouse_oldpos
= sc_buffer;
- console[0]->cursor_pos = console[0]->cursor_oldpos = sc_buffer + hw_cursor;
+ if (col >= console[0]->xsize)
+ col = 0;
+ if (row >= console[0]->ysize)
+ row = console[0]->ysize - 1;
+ console[0]->xpos = col;
+ console[0]->ypos = row;
+ console[0]->cursor_pos = console[0]->cursor_oldpos =
+ sc_buffer + row*console[0]->xsize + col;
console[0]->cursor_saveunder = *console[0]->cursor_pos;
- console[0]->xpos = hw_cursor % COL;
- console[0]->ypos = hw_cursor / COL;
for (i=1; i<MAXCONS; i++)
console[i] = NULL;
kernel_console.esc = 0;
@@ -3515,28 +3051,26 @@ scinit(void)
scr_map[i] = scr_rmap[i] = i;
}
- /* Save font and palette if VGA */
- if (crtc_type == KD_VGA) {
- if (!VESA_MODE(bios_video_mode)) {
- if (fonts_loaded & FONT_16) {
- copy_font(LOAD, FONT_16, font_16);
- } else {
- copy_font(SAVE, FONT_16, font_16);
- fonts_loaded = FONT_16;
- }
- set_destructive_cursor(console[0]);
+ /* Save font and palette */
+ if (ISFONTAVAIL(get_adapter(cur_console)->va_flags)) {
+ if (fonts_loaded & FONT_16) {
+ copy_font(cur_console, LOAD, 16, font_16);
+ } else {
+ copy_font(cur_console, SAVE, 16, font_16);
+ fonts_loaded = FONT_16;
+ set_destructive_cursor(cur_console);
}
- save_palette();
+ /*
+ * FONT KLUDGE
+ * Always use the font page #0. XXX
+ */
+ (*biosvidsw.show_font)(cur_console->adp, 0);
}
+ save_palette(cur_console, palette);
#ifdef SC_SPLASH_SCREEN
- /*
- * If not booting verbosely, put up the splash.
- * Note that the splash screen is not currently supported in
- * the VESA mode.
- */
- if (!(boothowto & RB_VERBOSE) && !VESA_MODE(bios_video_mode))
- scsplash_init();
+ /* put up the splash. */
+ scsplash_init(cur_console);
#endif
}
@@ -3551,52 +3085,79 @@ scshutdown(int howto, void *arg)
shutdown_in_progress = TRUE;
}
-static void
-map_mode_table(char *map[], char *table, int max)
+int
+sc_clean_up(scr_stat *scp)
{
- int i;
+ int error;
- for(i = 0; i < max; ++i)
- map[i] = table + i*MODE_PARAM_SIZE;
- for(; i < MODE_MAP_SIZE; ++i)
- map[i] = NULL;
+ if ((error = wait_scrn_saver_stop()))
+ return error;
+ scp->status &= ~MOUSE_VISIBLE;
+ remove_cutmarking(scp);
+ return 0;
}
-static int
-map_mode_num(int mode)
+void
+sc_alloc_scr_buffer(scr_stat *scp, int wait, int clear)
{
- static struct {
- int from;
- int to;
- } mode_map[] = {
- { M_ENH_B80x43, M_ENH_B80x25 },
- { M_ENH_C80x43, M_ENH_C80x25 },
- { M_VGA_M80x30, M_VGA_M80x25 },
- { M_VGA_C80x30, M_VGA_C80x25 },
- { M_VGA_M80x50, M_VGA_M80x25 },
- { M_VGA_C80x50, M_VGA_C80x25 },
- { M_VGA_M80x60, M_VGA_M80x25 },
- { M_VGA_C80x60, M_VGA_C80x25 },
- { M_VGA_MODEX, M_VGA_CG320 },
- };
- int i;
+ if (scp->scr_buf)
+ free(scp->scr_buf, M_DEVBUF);
+ scp->scr_buf = (u_short *)malloc(scp->xsize*scp->ysize*sizeof(u_short),
+ M_DEVBUF, (wait) ? M_WAITOK : M_NOWAIT);
- for (i = 0; i < sizeof(mode_map)/sizeof(mode_map[0]); ++i) {
- if (mode_map[i].from == mode)
- return mode_map[i].to;
+ if (clear) {
+ /* clear the screen and move the text cursor to the top-left position */
+ sc_clear_screen(scp);
+ } else {
+ /* retain the current cursor position, but adjust pointers */
+ move_crsr(scp, scp->xpos, scp->ypos);
+ scp->cursor_oldpos = scp->cursor_pos;
}
- return mode;
+
+ /* move the mouse cursor at the center of the screen */
+ sc_move_mouse(scp, scp->xpixel / 2, scp->ypixel / 2);
}
-static char
-*get_mode_param(scr_stat *scp, int mode)
+void
+sc_alloc_cut_buffer(scr_stat *scp, int wait)
{
- if (mode >= MODE_MAP_SIZE)
- mode = map_mode_num(mode);
- if (mode < MODE_MAP_SIZE)
- return mode_map[mode];
- else
- return NULL;
+ if ((cut_buffer == NULL)
+ || (cut_buffer_size < scp->xsize * scp->ysize + 1)) {
+ if (cut_buffer != NULL)
+ free(cut_buffer, M_DEVBUF);
+ cut_buffer_size = scp->xsize * scp->ysize + 1;
+ cut_buffer = (u_char *)malloc(cut_buffer_size,
+ M_DEVBUF, (wait) ? M_WAITOK : M_NOWAIT);
+ if (cut_buffer != NULL)
+ cut_buffer[0] = '\0';
+ }
+}
+
+void
+sc_alloc_history_buffer(scr_stat *scp, int lines, int extra, int wait)
+{
+ u_short *usp;
+
+ if (lines < scp->ysize)
+ lines = scp->ysize;
+
+ usp = scp->history;
+ scp->history = NULL;
+ if (usp != NULL) {
+ free(usp, M_DEVBUF);
+ if (extra > 0)
+ extra_history_size += extra;
+ }
+
+ scp->history_size = lines * scp->xsize;
+ if (lines > imax(sc_history_size, scp->ysize))
+ extra_history_size -= lines - imax(sc_history_size, scp->ysize);
+ usp = (u_short *)malloc(scp->history_size * sizeof(u_short),
+ M_DEVBUF, (wait) ? M_WAITOK : M_NOWAIT);
+ if (usp != NULL)
+ bzero(usp, scp->history_size * sizeof(u_short));
+ scp->history_head = scp->history_pos = usp;
+ scp->history = usp;
}
static scr_stat
@@ -3606,22 +3167,15 @@ static scr_stat
scp = (scr_stat *)malloc(sizeof(scr_stat), M_DEVBUF, M_WAITOK);
init_scp(scp);
- scp->scr_buf = scp->cursor_pos = scp->cursor_oldpos =
- (u_short *)malloc(scp->xsize*scp->ysize*sizeof(u_short),
- M_DEVBUF, M_WAITOK);
- scp->mouse_pos = scp->mouse_oldpos =
- scp->scr_buf + ((scp->mouse_ypos/scp->font_size)*scp->xsize +
- scp->mouse_xpos/8);
- scp->history_head = scp->history_pos =
- (u_short *)malloc(scp->history_size*sizeof(u_short),
- M_DEVBUF, M_WAITOK);
- bzero(scp->history_head, scp->history_size*sizeof(u_short));
- scp->history = scp->history_head;
+ sc_alloc_scr_buffer(scp, TRUE, TRUE);
+ if (ISMOUSEAVAIL(get_adapter(scp)->va_flags))
+ sc_alloc_cut_buffer(scp, TRUE);
+ sc_alloc_history_buffer(scp, sc_history_size, 0, TRUE);
/* SOS
- if (crtc_type == KD_VGA && video_mode_ptr)
+ if (get_adapter(scp)->va_flags & V_ADP_MODECHANGE)
set_mode(scp);
*/
- clear_screen(scp);
+ sc_clear_screen(scp);
scp->cursor_saveunder = *scp->cursor_pos;
return scp;
}
@@ -3629,43 +3183,29 @@ static scr_stat
static void
init_scp(scr_stat *scp)
{
- switch(crtc_type) {
- case KD_VGA:
- if (VESA_MODE(bios_video_mode))
- scp->mode = bios_video_mode;
- else if (crtc_addr == MONO_BASE)
- scp->mode = M_VGA_M80x25;
- else
- scp->mode = M_VGA_C80x25;
- scp->font_size = 16;
- break;
- case KD_CGA:
- if (crtc_addr == MONO_BASE)
- scp->mode = M_B80x25;
- else
- scp->mode = M_C80x25;
- scp->font_size = 8;
- break;
- case KD_EGA:
- if (crtc_addr == MONO_BASE)
- scp->mode = M_B80x25;
- else
- scp->mode = M_C80x25;
- scp->font_size = 14;
- break;
- case KD_MONO:
- case KD_HERCULES:
- default:
- scp->mode = M_EGAMONO80x25;
- scp->font_size = 14;
- break;
+ video_info_t info;
+
+ scp->adp = V_ADP_PRIMARY;
+ (*biosvidsw.get_info)(scp->adp, initial_video_mode, &info);
+
+ scp->status = 0;
+ scp->mode = scp->initial_mode = initial_video_mode;
+ scp->scr_buf = NULL;
+ if (info.vi_flags & V_INFO_GRAPHICS) {
+ scp->status |= GRAPHICS_MODE;
+ scp->xpixel = info.vi_width;
+ scp->ypixel = info.vi_height;
+ scp->xsize = info.vi_width/8;
+ scp->ysize = info.vi_height/info.vi_cheight;
+ scp->font_size = FONT_NONE;
+ } else {
+ scp->xsize = info.vi_width;
+ scp->ysize = info.vi_height;
+ scp->xpixel = scp->xsize*8;
+ scp->ypixel = scp->ysize*info.vi_cheight;
+ scp->font_size = info.vi_cheight;
}
- scp->initial_mode = scp->mode;
-
- scp->xsize = COL;
- scp->ysize = ROW;
- scp->xpixel = scp->xsize * 8;
- scp->ypixel = scp->ysize * scp->font_size;
+ scp->xoff = scp->yoff = 0;
scp->xpos = scp->ypos = 0;
scp->saved_xpos = scp->saved_ypos = -1;
scp->start = scp->xsize * scp->ysize;
@@ -3677,8 +3217,8 @@ init_scp(scr_stat *scp)
current_default->std_color;
scp->term.rev_color = current_default->rev_color;
scp->border = BG_BLACK;
- scp->cursor_start = *(char *)pa_to_va(0x461);
- scp->cursor_end = *(char *)pa_to_va(0x460);
+ scp->cursor_start = *(u_int8_t *)pa_to_va(0x461);
+ scp->cursor_end = *(u_int8_t *)pa_to_va(0x460);
scp->mouse_xpos = scp->xsize*8/2;
scp->mouse_ypos = scp->ysize*scp->font_size/2;
scp->mouse_cut_start = scp->mouse_cut_end = NULL;
@@ -3687,13 +3227,13 @@ init_scp(scr_stat *scp)
scp->mouse_proc = NULL;
scp->bell_pitch = BELL_PITCH;
scp->bell_duration = BELL_DURATION;
- scp->status = (*(char *)pa_to_va(0x417) & 0x20) ? NLKED : 0;
+ scp->status |= (*(u_int8_t *)pa_to_va(0x417) & 0x20) ? NLKED : 0;
scp->status |= CURSOR_ENABLED;
scp->pid = 0;
scp->proc = NULL;
scp->smode.mode = VT_AUTO;
scp->history_head = scp->history_pos = scp->history = NULL;
- scp->history_size = imax(SC_HISTORY_SIZE, scp->ysize) * scp->xsize;
+ scp->history_size = imax(sc_history_size, scp->ysize) * scp->xsize;
}
static u_char
@@ -4140,9 +3680,9 @@ next_code:
scsplash_stick(FALSE);
stop_scrn_saver(current_saver);
} else {
- if ((cur_console->status & UNKNOWN_MODE) == 0) {
+ if (!ISGRAPHSC(cur_console)) {
scsplash_stick(TRUE);
- (*current_saver)(TRUE);
+ scrn_saver(current_saver, TRUE);
}
}
}
@@ -4409,475 +3949,100 @@ update_leds(int which)
set_keyboard(KBDC_SET_LEDS, xlate_leds[which & LED_MASK]);
}
-void
+int
set_mode(scr_stat *scp)
{
- char special_modetable[MODE_PARAM_SIZE];
- char *mp;
- int s;
- int i;
+ video_info_t info;
+ video_adapter_t *adp;
- if (scp != cur_console)
- return;
+ /* reject unsupported mode */
+ if ((*biosvidsw.get_info)(scp->adp, scp->mode, &info))
+ return 1;
- /*
- * even if mode switching is disabled, we can change back
- * to the initial mode or the custom mode based on the initial
- * mode if we have saved register values upon start-up.
- */
- mp = get_mode_param(scp, scp->mode);
- if (mp == NULL)
- return;
- bcopy(mp, &special_modetable, sizeof(special_modetable));
+ /* if this vty is not currently showing, do nothing */
+ if (scp != cur_console)
+ return 0;
/* setup video hardware for the given mode */
- switch (scp->mode) {
- case M_VGA_C80x60: case M_VGA_M80x60:
- special_modetable[2] = 0x08;
- special_modetable[19] = 0x47;
- goto special_480l;
-
- case M_VGA_C80x30: case M_VGA_M80x30:
- special_modetable[19] = 0x4f;
-special_480l:
- special_modetable[9] |= 0xc0;
- special_modetable[16] = 0x08;
- special_modetable[17] = 0x3e;
- special_modetable[26] = 0xea;
- special_modetable[28] = 0xdf;
- special_modetable[31] = 0xe7;
- special_modetable[32] = 0x04;
- goto setup_mode;
-
- case M_ENH_C80x43: case M_ENH_B80x43:
- special_modetable[28] = 87;
- goto special_80x50;
-
- case M_VGA_C80x50: case M_VGA_M80x50:
-special_80x50:
- special_modetable[2] = 8;
- special_modetable[19] = 7;
- goto setup_mode;
-
- case M_VGA_C40x25: case M_VGA_C80x25:
- case M_VGA_M80x25:
- case M_B40x25: case M_C40x25:
- case M_B80x25: case M_C80x25:
- case M_ENH_B40x25: case M_ENH_C40x25:
- case M_ENH_B80x25: case M_ENH_C80x25:
- case M_EGAMONO80x25:
-
-setup_mode:
- set_vgaregs(special_modetable);
- scp->font_size = special_modetable[2];
-
- /* set font type (size) */
- if (scp->font_size < 14) {
- if (fonts_loaded & FONT_8)
- copy_font(LOAD, FONT_8, font_8);
- i = 0x0a; /* font 2 */
- } else if (scp->font_size >= 16) {
- if (fonts_loaded & FONT_16)
- copy_font(LOAD, FONT_16, font_16);
- i = 0x00; /* font 0 */
- } else {
- if (fonts_loaded & FONT_14)
- copy_font(LOAD, FONT_14, font_14);
- i = 0x05; /* font 1 */
+ adp = get_adapter(scp);
+ (*biosvidsw.set_mode)(scp->adp, scp->mode);
+ Crtat = (u_short *)adp->va_window;
+
+ if (!(scp->status & GRAPHICS_MODE)) {
+ /* load appropriate font */
+ if (!(scp->status & PIXEL_MODE)
+ && ISFONTAVAIL(get_adapter(scp)->va_flags)) {
+ if (scp->font_size < 14) {
+ if (fonts_loaded & FONT_8)
+ copy_font(scp, LOAD, 8, font_8);
+ } else if (scp->font_size >= 16) {
+ if (fonts_loaded & FONT_16)
+ copy_font(scp, LOAD, 16, font_16);
+ } else {
+ if (fonts_loaded & FONT_14)
+ copy_font(scp, LOAD, 14, font_14);
+ }
+ /*
+ * FONT KLUDGE:
+ * This is an interim kludge to display correct font.
+ * Always use the font page #0 on the video plane 2.
+ * Somehow we cannot show the font in other font pages on
+ * some video cards... XXX
+ */
+ (*biosvidsw.show_font)(scp->adp, 0);
}
- /*
- * FONT KLUDGE:
- * This is an interim kludge to display correct font.
- * Always use the font page #0 on the video plane 2.
- * Somehow we cannot show the font in other font pages on
- * some video cards... XXX
- */
- i = 0x00;
- s = splhigh();
- outb(TSIDX, 0x00); outb(TSREG, 0x01);
- outb(TSIDX, 0x03); outb(TSREG, i);
- outb(TSIDX, 0x00); outb(TSREG, 0x03);
- splx(s);
- if (flags & CHAR_CURSOR)
- set_destructive_cursor(scp);
mark_all(scp);
- break;
-
- case M_VGA_MODEX:
- /* "unchain" the VGA mode */
- special_modetable[5-1+0x04] &= 0xf7;
- special_modetable[5-1+0x04] |= 0x04;
- /* turn off doubleword mode */
- special_modetable[10+0x14] &= 0xbf;
- /* turn off word adressing */
- special_modetable[10+0x17] |= 0x40;
- /* set logical screen width */
- special_modetable[10+0x13] = 80;
- /* set 240 lines */
- special_modetable[10+0x11] = 0x2c;
- special_modetable[10+0x06] = 0x0d;
- special_modetable[10+0x07] = 0x3e;
- special_modetable[10+0x10] = 0xea;
- special_modetable[10+0x11] = 0xac;
- special_modetable[10+0x12] = 0xdf;
- special_modetable[10+0x15] = 0xe7;
- special_modetable[10+0x16] = 0x06;
- /* set vertical sync polarity to reflect aspect ratio */
- special_modetable[9] = 0xe3;
- goto setup_grmode;
-
- case M_BG320: case M_CG320: case M_BG640:
- case M_CG320_D: case M_CG640_E:
- case M_CG640x350: case M_ENH_CG640:
- case M_BG640x480: case M_CG640x480: case M_VGA_CG320:
-
-setup_grmode:
- set_vgaregs(special_modetable);
- scp->font_size = FONT_NONE;
- break;
-
- default:
- /* call user defined function XXX */
- break;
- }
-
- /* set border color for this (virtual) console */
- set_border(scp->border);
- return;
-}
-
-void
-set_border(u_char color)
-{
- switch (crtc_type) {
- case KD_EGA:
- case KD_VGA:
- inb(crtc_addr + 6); /* reset flip-flop */
- outb(ATC, 0x31); outb(ATC, color);
- break;
- case KD_CGA:
- outb(crtc_addr + 5, color & 0x0f); /* color select register */
- break;
- case KD_MONO:
- case KD_HERCULES:
- default:
- break;
}
-}
-
-static void
-set_vgaregs(char *modetable)
-{
- int i, s = splhigh();
-
- outb(TSIDX, 0x00); outb(TSREG, 0x01); /* stop sequencer */
- for (i=0; i<4; i++) { /* program sequencer */
- outb(TSIDX, i+1);
- outb(TSREG, modetable[i+5]);
- }
- outb(MISC, modetable[9]); /* set dot-clock */
- outb(TSIDX, 0x00); outb(TSREG, 0x03); /* start sequencer */
- outb(crtc_addr, 0x11);
- outb(crtc_addr+1, inb(crtc_addr+1) & 0x7F);
- for (i=0; i<25; i++) { /* program crtc */
- outb(crtc_addr, i);
- if (i == 14 || i == 15) /* no hardware cursor */
- outb(crtc_addr+1, 0xff);
- else
- outb(crtc_addr+1, modetable[i+10]);
- }
- inb(crtc_addr+6); /* reset flip-flop */
- for (i=0; i<20; i++) { /* program attribute ctrl */
- outb(ATC, i);
- outb(ATC, modetable[i+35]);
- }
- for (i=0; i<9; i++) { /* program graph data ctrl */
- outb(GDCIDX, i);
- outb(GDCREG, modetable[i+55]);
- }
- inb(crtc_addr+6); /* reset flip-flop */
- outb(ATC, 0x20); /* enable palette */
- splx(s);
-}
-
-static void
-read_vgaregs(char *buf)
-{
- int i, j;
- int s;
+ set_border(scp, scp->border);
- bzero(buf, MODE_PARAM_SIZE);
-
- s = splhigh();
-
- outb(TSIDX, 0x00); outb(TSREG, 0x01); /* stop sequencer */
- for (i=0, j=5; i<4; i++) {
- outb(TSIDX, i+1);
- buf[j++] = inb(TSREG);
- }
- buf[9] = inb(MISC + 10); /* dot-clock */
- outb(TSIDX, 0x00); outb(TSREG, 0x03); /* start sequencer */
-
- for (i=0, j=10; i<25; i++) { /* crtc */
- outb(crtc_addr, i);
- buf[j++] = inb(crtc_addr+1);
- }
- for (i=0, j=35; i<20; i++) { /* attribute ctrl */
- inb(crtc_addr+6); /* reset flip-flop */
- outb(ATC, i);
- buf[j++] = inb(ATC + 1);
- }
- for (i=0, j=55; i<9; i++) { /* graph data ctrl */
- outb(GDCIDX, i);
- buf[j++] = inb(GDCREG);
- }
- inb(crtc_addr+6); /* reset flip-flop */
- outb(ATC, 0x20); /* enable palette */
-
- buf[0] = *(char *)pa_to_va(0x44a); /* COLS */
- buf[1] = *(char *)pa_to_va(0x484); /* ROWS */
- buf[2] = *(char *)pa_to_va(0x485); /* POINTS */
- buf[3] = *(char *)pa_to_va(0x44c);
- buf[4] = *(char *)pa_to_va(0x44d);
-
- splx(s);
-}
-
-static int
-comp_vgaregs(u_char *buf1, u_char *buf2)
-{
- static struct {
- u_char mask;
- } params[MODE_PARAM_SIZE] = {
- 0xff, 0x00, 0xff, /* COLS, ROWS, POINTS */
- 0xff, 0xff, /* page length */
- 0xfe, 0xff, 0xff, 0xff, /* sequencer registers */
- 0xf3, /* misc register */
- 0xff, 0xff, 0xff, 0x7f, 0xff, /* CRTC */
- 0xff, 0xff, 0xff, 0x7f, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0x7f, 0xff, 0xff,
- 0x7f, 0xff, 0xff, 0xef, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, /* attribute controller registers */
- 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xf0,
- 0xff, 0xff, 0xff, 0xff, 0xff, /* GDC register */
- 0xff, 0xff, 0xff, 0xff,
- };
- int identical = TRUE;
- int i;
-
- for (i = 0; i < sizeof(params)/sizeof(params[0]); ++i) {
- if (params[i].mask == 0) /* don't care */
- continue;
- if ((buf1[i] & params[i].mask) != (buf2[i] & params[i].mask))
- return COMP_DIFFERENT;
- if (buf1[i] != buf2[i])
- identical = FALSE;
- }
- return (identical) ? COMP_IDENTICAL : COMP_SIMILAR;
-
-#if 0
- for(i = 0; i < 20; ++i) {
- if (*buf1++ != *buf2++)
- return COMP_DIFFERENT;
- }
- buf1 += 2; /* skip the cursor shape */
- buf2 += 2;
- for(i = 22; i < 24; ++i) {
- if (*buf1++ != *buf2++)
- return COMP_DIFFERENT;
- }
- buf1 += 2; /* skip the cursor position */
- buf2 += 2;
- for(i = 26; i < MODE_PARAM_SIZE; ++i) {
- if (*buf1++ != *buf2++)
- return COMP_DIFFERENT;
- }
- return COMP_IDENTICAL;
-#endif
-}
-
-static void
-dump_vgaregs(u_char *buf)
-{
- int i;
+ /* move hardware cursor out of the way */
+ (*biosvidsw.set_hw_cursor)(scp->adp, -1, -1);
- for(i = 0; i < MODE_PARAM_SIZE;) {
- printf("%02x ", buf[i]);
- if ((++i % 16) == 0)
- printf("\n");
- }
+ return 0;
}
-static void
-set_font_mode(u_char *buf)
+void
+copy_font(scr_stat *scp, int operation, int font_size, u_char *buf)
{
- int s = splhigh();
-
+ /*
+ * FONT KLUDGE:
+ * This is an interim kludge to display correct font.
+ * Always use the font page #0 on the video plane 2.
+ * Somehow we cannot show the font in other font pages on
+ * some video cards... XXX
+ */
font_loading_in_progress = TRUE;
-
- /* save register values */
- outb(TSIDX, 0x02); buf[0] = inb(TSREG);
- outb(TSIDX, 0x04); buf[1] = inb(TSREG);
- outb(GDCIDX, 0x04); buf[2] = inb(GDCREG);
- outb(GDCIDX, 0x05); buf[3] = inb(GDCREG);
- outb(GDCIDX, 0x06); buf[4] = inb(GDCREG);
- inb(crtc_addr + 6);
- outb(ATC, 0x10); buf[5] = inb(ATC + 1);
-
- /* setup vga for loading fonts */
- inb(crtc_addr+6); /* reset flip-flop */
- outb(ATC, 0x10); outb(ATC, buf[5] & ~0x01);
- inb(crtc_addr+6); /* reset flip-flop */
- outb(ATC, 0x20); /* enable palette */
-
-#if SLOW_VGA
-#ifndef SC_BAD_FLICKER
- outb(TSIDX, 0x00); outb(TSREG, 0x01);
-#endif
- outb(TSIDX, 0x02); outb(TSREG, 0x04);
- outb(TSIDX, 0x04); outb(TSREG, 0x07);
-#ifndef SC_BAD_FLICKER
- outb(TSIDX, 0x00); outb(TSREG, 0x03);
-#endif
- outb(GDCIDX, 0x04); outb(GDCREG, 0x02);
- outb(GDCIDX, 0x05); outb(GDCREG, 0x00);
- outb(GDCIDX, 0x06); outb(GDCREG, 0x04);
-#else
-#ifndef SC_BAD_FLICKER
- outw(TSIDX, 0x0100);
-#endif
- outw(TSIDX, 0x0402);
- outw(TSIDX, 0x0704);
-#ifndef SC_BAD_FLICKER
- outw(TSIDX, 0x0300);
-#endif
- outw(GDCIDX, 0x0204);
- outw(GDCIDX, 0x0005);
- outw(GDCIDX, 0x0406); /* addr = a0000, 64kb */
-#endif
- splx(s);
-}
-
-static void
-set_normal_mode(u_char *buf)
-{
- char *modetable;
- int s = splhigh();
-
- /* setup vga for normal operation mode again */
- inb(crtc_addr+6); /* reset flip-flop */
- outb(ATC, 0x10); outb(ATC, buf[5]);
- inb(crtc_addr+6); /* reset flip-flop */
- outb(ATC, 0x20); /* enable palette */
-
-#if SLOW_VGA
-#ifndef SC_BAD_FLICKER
- outb(TSIDX, 0x00); outb(TSREG, 0x01);
-#endif
- outb(TSIDX, 0x02); outb(TSREG, buf[0]);
- outb(TSIDX, 0x04); outb(TSREG, buf[1]);
-#ifndef SC_BAD_FLICKER
- outb(TSIDX, 0x00); outb(TSREG, 0x03);
-#endif
- outb(GDCIDX, 0x04); outb(GDCREG, buf[2]);
- outb(GDCIDX, 0x05); outb(GDCREG, buf[3]);
- if (crtc_addr == MONO_BASE) {
- outb(GDCIDX, 0x06); outb(GDCREG,(buf[4] & 0x03) | 0x08);
- } else {
- outb(GDCIDX, 0x06); outb(GDCREG,(buf[4] & 0x03) | 0x0c);
+ if (operation == LOAD) {
+ (*biosvidsw.load_font)(scp->adp, 0, font_size, buf, 0, 256);
+ if (flags & CHAR_CURSOR)
+ set_destructive_cursor(scp);
+ } else if (operation == SAVE) {
+ (*biosvidsw.save_font)(scp->adp, 0, font_size, buf, 0, 256);
}
-#else
-#ifndef SC_BAD_FLICKER
- outw(TSIDX, 0x0100);
-#endif
- outw(TSIDX, 0x0002 | (buf[0] << 8));
- outw(TSIDX, 0x0004 | (buf[1] << 8));
-#ifndef SC_BAD_FLICKER
- outw(TSIDX, 0x0300);
-#endif
- outw(GDCIDX, 0x0004 | (buf[2] << 8));
- outw(GDCIDX, 0x0005 | (buf[3] << 8));
- if (crtc_addr == MONO_BASE)
- outw(GDCIDX, 0x0006 | (((buf[4] & 0x03) | 0x08)<<8));
- else
- outw(GDCIDX, 0x0006 | (((buf[4] & 0x03) | 0x0c)<<8));
-#endif
-
font_loading_in_progress = FALSE;
- splx(s);
-}
-
-void
-copy_font(int operation, int font_type, char* font_image)
-{
- int ch, line, segment, fontsize;
- u_char buf[PARAM_BUFSIZE];
- u_char val;
-
- switch (font_type) {
- default:
- case FONT_8:
- segment = 0x8000;
- fontsize = 8;
- break;
- case FONT_14:
- segment = 0x4000;
- fontsize = 14;
- break;
- case FONT_16:
- segment = 0x0000;
- fontsize = 16;
- break;
- }
- /*
- * FONT KLUDGE
- * Always use the font page #0. XXX
- */
- segment = 0x0000;
- outb(TSIDX, 0x01); val = inb(TSREG); /* disable screen */
- outb(TSIDX, 0x01); outb(TSREG, val | 0x20);
- set_font_mode(buf);
- for (ch=0; ch < 256; ch++)
- for (line=0; line < fontsize; line++)
- if (operation)
- *(char *)pa_to_va(VIDEOMEM+(segment)+(ch*32)+line) =
- font_image[(ch*fontsize)+line];
- else
- font_image[(ch*fontsize)+line] =
- *(char *)pa_to_va(VIDEOMEM+(segment)+(ch*32)+line);
- set_normal_mode(buf);
- outb(TSIDX, 0x01); outb(TSREG, val & 0xDF); /* enable screen */
}
static void
set_destructive_cursor(scr_stat *scp)
{
- u_char buf[PARAM_BUFSIZE];
u_char cursor[32];
- caddr_t address;
+ u_char *font_buffer;
+ int font_size;
int i;
- char *font_buffer;
+
+ if (!ISFONTAVAIL(get_adapter(scp)->va_flags) || !ISTEXTSC(scp))
+ return;
if (scp->font_size < 14) {
font_buffer = font_8;
- address = (caddr_t)VIDEOMEM + 0x8000;
- }
- else if (scp->font_size >= 16) {
+ font_size = 8;
+ } else if (scp->font_size >= 16) {
font_buffer = font_16;
- address = (caddr_t)VIDEOMEM;
- }
- else {
+ font_size = 16;
+ } else {
font_buffer = font_14;
- address = (caddr_t)VIDEOMEM + 0x4000;
+ font_size = 14;
}
- /*
- * FONT KLUDGE
- * Always use the font page #0. XXX
- */
- address = (caddr_t)VIDEOMEM;
if (scp->status & MOUSE_VISIBLE) {
if ((scp->cursor_saveunder & 0xff) == SC_MOUSE_CHAR)
@@ -4902,9 +4067,18 @@ set_destructive_cursor(scr_stat *scp)
#if 1
while (!(inb(crtc_addr+6) & 0x08)) /* wait for vertical retrace */ ;
#endif
- set_font_mode(buf);
- generic_bcopy(cursor, (char *)pa_to_va(address) + DEAD_CHAR * 32, 32);
- set_normal_mode(buf);
+ font_loading_in_progress = TRUE;
+ (*biosvidsw.load_font)(scp->adp, 0, font_size, cursor, DEAD_CHAR, 1);
+ font_loading_in_progress = FALSE;
+}
+
+void
+sc_move_mouse(scr_stat *scp, int x, int y)
+{
+ scp->mouse_xpos = x;
+ scp->mouse_ypos = y;
+ scp->mouse_pos = scp->mouse_oldpos =
+ scp->scr_buf + (y / scp->font_size) * scp->xsize + x / 8;
}
static void
@@ -4916,7 +4090,7 @@ set_mouse_pos(scr_stat *scp)
scp->mouse_xpos = 0;
if (scp->mouse_ypos < 0)
scp->mouse_ypos = 0;
- if (scp->status & UNKNOWN_MODE) {
+ if (!ISTEXTSC(scp)) {
if (scp->mouse_xpos > scp->xpixel-1)
scp->mouse_xpos = scp->xpixel-1;
if (scp->mouse_ypos > scp->ypixel-1)
@@ -5146,35 +4320,26 @@ mouse_paste(scr_stat *scp)
static void
draw_mouse_image(scr_stat *scp)
{
- caddr_t address;
- int i;
- char *font_buffer;
- u_char buf[PARAM_BUFSIZE];
u_short buffer[32];
u_short xoffset, yoffset;
u_short *crt_pos = Crtat + (scp->mouse_pos - scp->scr_buf);
- int font_size = scp->font_size;
+ u_char *font_buffer;
+ int font_size;
+ int i;
- if (font_size < 14) {
+ if (scp->font_size < 14) {
font_buffer = font_8;
- address = (caddr_t)VIDEOMEM + 0x8000;
- }
- else if (font_size >= 16) {
+ font_size = 8;
+ } else if (scp->font_size >= 16) {
font_buffer = font_16;
- address = (caddr_t)VIDEOMEM;
- }
- else {
+ font_size = 16;
+ } else {
font_buffer = font_14;
- address = (caddr_t)VIDEOMEM + 0x4000;
+ font_size = 14;
}
- /*
- * FONT KLUDGE
- * Always use the font page #0. XXX
- */
- address = (caddr_t)VIDEOMEM;
xoffset = scp->mouse_xpos % 8;
- yoffset = scp->mouse_ypos % font_size;
+ yoffset = scp->mouse_ypos % scp->font_size;
/* prepare mousepointer char's bitmaps */
bcopy(font_buffer + ((*(scp->mouse_pos) & 0xff) * font_size),
@@ -5209,9 +4374,11 @@ draw_mouse_image(scr_stat *scp)
/* wait for vertical retrace to avoid jitter on some videocards */
while (!(inb(crtc_addr+6) & 0x08)) /* idle */ ;
#endif
- set_font_mode(buf);
- generic_bcopy(scp->mouse_cursor, (char *)pa_to_va(address) + SC_MOUSE_CHAR * 32, 128);
- set_normal_mode(buf);
+ font_loading_in_progress = TRUE;
+ (*biosvidsw.load_font)(scp->adp, 0, 32, scp->mouse_cursor,
+ SC_MOUSE_CHAR, 4);
+ font_loading_in_progress = FALSE;
+
*(crt_pos) = (*(scp->mouse_pos) & 0xff00) | SC_MOUSE_CHAR;
*(crt_pos+scp->xsize) =
(*(scp->mouse_pos + scp->xsize) & 0xff00) | (SC_MOUSE_CHAR + 2);
@@ -5229,6 +4396,8 @@ remove_mouse_image(scr_stat *scp)
{
u_short *crt_pos = Crtat + (scp->mouse_oldpos - scp->scr_buf);
+ if (!ISTEXTSC(scp))
+ return;
*(crt_pos) = *(scp->mouse_oldpos);
*(crt_pos+1) = *(scp->mouse_oldpos+1);
*(crt_pos+scp->xsize) = *(scp->mouse_oldpos+scp->xsize);
@@ -5279,30 +4448,6 @@ remove_cutmarking(scr_stat *scp)
}
static void
-save_palette(void)
-{
- int i;
-
- outb(PALRADR, 0x00);
- for (i=0x00; i<0x300; i++)
- palette[i] = inb(PALDATA);
- inb(crtc_addr+6); /* reset flip/flop */
-}
-
-void
-load_palette(char *palette)
-{
- int i;
-
- outb(PIXMASK, 0xFF); /* no pixelmask */
- outb(PALWADR, 0x00);
- for (i=0x00; i<0x300; i++)
- outb(PALDATA, palette[i]);
- inb(crtc_addr+6); /* reset flip/flop */
- outb(ATC, 0x20); /* enable palette */
-}
-
-static void
do_bell(scr_stat *scp, int pitch, int duration)
{
if (cold || shutdown_in_progress)
@@ -5330,7 +4475,7 @@ blink_screen(void *arg)
{
scr_stat *scp = arg;
- if ((scp->status & UNKNOWN_MODE) || (blink_in_progress <= 1)) {
+ if (!ISTEXTSC(scp) || (blink_in_progress <= 1)) {
blink_in_progress = FALSE;
mark_all(scp);
if (delayed_next_scr)
@@ -5351,25 +4496,41 @@ blink_screen(void *arg)
void
sc_bcopy(scr_stat *scp, u_short *p, int from, int to, int mark)
{
- if (!VESA_MODE(scp->mode)) {
- generic_bcopy(p+from, Crtat+from, (to-from+1)*sizeof (u_short));
- } else if (scp->mode == 0x102) {
- u_char *d, *e;
- int i,j;
+ u_char *font;
+ u_char *d, *e;
+ u_char *f;
+ int font_size;
+ int line_length;
+ int xsize;
+ int i, j;
+ if (ISTEXTSC(scp)) {
+ generic_bcopy(p+from, Crtat+from, (to-from+1)*sizeof (u_short));
+ } else /* if ISPIXELSC(scp) */ {
if (mark)
- mark = 255;
- d = (u_char *)Crtat;
- d += 10 + 6*16*100 + (from%80) + 16*100*(from/80);
+ mark = 255;
+ font_size = scp->font_size;
+ if (font_size < 14)
+ font = font_8;
+ else if (font_size >= 16)
+ font = font_16;
+ else
+ font = font_14;
+ line_length = scp->xpixel/8;
+ xsize = scp->xsize;
+ d = (u_char *)Crtat
+ + scp->xoff + scp->yoff*font_size*line_length
+ + (from%xsize) + font_size*line_length*(from/xsize);
for (i = from ; i <= to ; i++) {
e = d;
- for (j = 0 ; j < 16; j++) {
- *e = mark^font_16[(p[i]&0xff)*16+j];
- e+=100;
+ f = &font[(p[i] & 0x00ff)*font_size];
+ for (j = 0 ; j < font_size; j++, f++) {
+ *e = mark^*f;
+ e += line_length;
}
d++;
- if ((i % 80) == 79)
- d += 20 + 15*100;
+ if ((i % xsize) == xsize - 1)
+ d += scp->xoff*2 + (font_size - 1)*line_length;
}
}
}
@@ -5377,34 +4538,36 @@ sc_bcopy(scr_stat *scp, u_short *p, int from, int to, int mark)
#ifdef SC_SPLASH_SCREEN
static void
-scsplash_init(void)
+scsplash_init(scr_stat *scp)
{
+ video_info_t info;
+
/*
* We currently assume the splash screen always use
* VGA_CG320 mode and abort installation if this mode is not
* supported with this video card. XXX
*/
- if (crtc_type != KD_VGA || get_mode_param(cur_console, M_VGA_CG320) == NULL)
+ if ((*biosvidsw.get_info)(scp->adp, M_VGA_CG320, &info))
return;
- if (splash_load() == 0 && add_scrn_saver(scsplash) == 0) {
- default_saver = scsplash;
+ if (scsplash_load(scp) == 0 && add_scrn_saver(scsplash_saver) == 0) {
+ default_saver = scsplash_saver;
scrn_blank_time = DEFAULT_BLANKTIME;
run_scrn_saver = TRUE;
- if (!(boothowto & RB_CONFIG)) {
+ if (!(boothowto & (RB_VERBOSE | RB_CONFIG))) {
scsplash_stick(TRUE);
- scsplash(TRUE);
+ scsplash_saver(TRUE);
}
}
}
static void
-scsplash(int show)
+scsplash_saver(int show)
{
if (show)
- splash(TRUE);
+ scsplash(TRUE);
else if (!sticky_splash)
- splash(FALSE);
+ scsplash(FALSE);
}
#endif /* SC_SPLASH_SCREEN */
diff --git a/sys/i386/isa/syscons.h b/sys/i386/isa/syscons.h
index b23a2ae..315946b 100644
--- a/sys/i386/isa/syscons.h
+++ b/sys/i386/isa/syscons.h
@@ -1,18 +1,18 @@
/*-
- * Copyright (c) 1995-1997 Søren Schmidt
+ * Copyright (c) 1995-1998 Søren Schmidt
* 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
- * in this position and unchanged.
+ * notice, this list of conditions and the following disclaimer,
+ * without modification, immediately at the beginning of the file.
* 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. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission
+ * derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: syscons.h,v 1.38 1998/08/03 09:09:35 yokota Exp $
+ * $Id$
*/
#ifndef _I386_ISA_SYSCONS_H_
@@ -65,6 +65,9 @@
#define MOUSE_MOVED 0x01000
#define MOUSE_CUTTING 0x02000
#define MOUSE_VISIBLE 0x04000
+#define GRAPHICS_MODE 0x08000
+#define PIXEL_MODE 0x10000
+#define SAVER_RUNNING 0x20000
/* configuration flags */
#define VISUAL_BELL 0x00001
@@ -74,6 +77,7 @@
#define XT_KEYBD 0x00010
#define KBD_NORESET 0x00020
#define QUIET_BELL 0x00040
+#define VESA800X600 0x00080
/* attribute flags */
#define NORMAL_ATTR 0x00
@@ -84,9 +88,6 @@
#define FOREGROUND_CHANGED 0x10
#define BACKGROUND_CHANGED 0x20
-/* video hardware memory addresses */
-#define VIDEOMEM 0x000A0000
-
/* misc defines */
#define FALSE 0
#define TRUE 1
@@ -104,20 +105,6 @@
#define FONT_14 4
#define FONT_16 8
-/* defines related to hardware addresses */
-#define MONO_BASE 0x3B4 /* crt controller base mono */
-#define COLOR_BASE 0x3D4 /* crt controller base color */
-#define MISC 0x3C2 /* misc output register */
-#define ATC IO_VGA+0x00 /* attribute controller */
-#define TSIDX IO_VGA+0x04 /* timing sequencer idx */
-#define TSREG IO_VGA+0x05 /* timing sequencer data */
-#define PIXMASK IO_VGA+0x06 /* pixel write mask */
-#define PALRADR IO_VGA+0x07 /* palette read address */
-#define PALWADR IO_VGA+0x08 /* palette write address */
-#define PALDATA IO_VGA+0x09 /* palette data register */
-#define GDCIDX IO_VGA+0x0E /* graph data controller idx */
-#define GDCREG IO_VGA+0x0F /* graph data controller data */
-
/* special characters */
#define cntlc 0x03
#define cntld 0x04
@@ -141,6 +128,7 @@ typedef struct term_stat {
} term_stat;
typedef struct scr_stat {
+ int adp; /* video adapter index */
u_short *scr_buf; /* buffer when off screen */
int xpos; /* current X position */
int ypos; /* current Y position */
@@ -150,6 +138,8 @@ typedef struct scr_stat {
int ysize; /* Y text size */
int xpixel; /* X graphics size */
int ypixel; /* Y graphics size */
+ int xoff; /* X offset in pixel mode */
+ int yoff; /* Y offset in pixel mode */
int font_size; /* fontsize in Y direction */
int start; /* modified area start */
int end; /* modified area end */
@@ -186,7 +176,8 @@ typedef struct scr_stat {
int history_size; /* size of history buffer */
struct apmhook r_hook; /* reconfiguration support */
#ifdef SC_SPLASH_SCREEN
- u_char splash_save_mode; /* saved mode for splash screen */
+ int splash_save_mode; /* saved mode for splash screen */
+ int splash_save_status; /* saved status for splash screen */
#endif
} scr_stat;
@@ -195,18 +186,59 @@ typedef struct default_attr {
int rev_color; /* reverse hardware color */
} default_attr;
+
+#define ISTEXTSC(scp) (!((scp)->status \
+ & (UNKNOWN_MODE | GRAPHICS_MODE | PIXEL_MODE)))
+#define ISGRAPHSC(scp) (((scp)->status \
+ & (UNKNOWN_MODE | GRAPHICS_MODE)))
+#define ISPIXELSC(scp) (((scp)->status \
+ & (UNKNOWN_MODE | GRAPHICS_MODE | PIXEL_MODE))\
+ == PIXEL_MODE)
+#define ISUNKNOWNSC(scp) ((scp)->status & UNKNOWN_MODE)
+
+#define ISFONTAVAIL(af) ((af) & V_ADP_FONT)
+#define ISMOUSEAVAIL(af) ((af) & V_ADP_FONT)
+#define ISPALAVAIL(af) ((af) & V_ADP_PALETTE)
+
/* misc prototypes used by different syscons related LKM's */
-void set_border(u_char color);
-void set_mode(scr_stat *scp);
-void copy_font(int operation, int font_type, char* font_image);
-void load_palette(char *palette);
+
+/* syscons.c */
+extern int (*sc_user_ioctl)(dev_t dev, int cmd, caddr_t data, int flag,
+ struct proc *p);
+
+int set_mode(scr_stat *scp);
+scr_stat *sc_get_scr_stat(dev_t dev);
+
+void copy_font(scr_stat *scp, int operation, int font_size, u_char *font_image);
+#define save_palette(scp, pal) (*biosvidsw.save_palette)((scp)->adp, pal)
+#define load_palette(scp, pal) (*biosvidsw.load_palette)((scp)->adp, pal)
+#define set_border(scp, col) (*biosvidsw.set_border)((scp)->adp, col)
+#define get_adapter(scp) (*biosvidsw.adapter)((scp)->adp)
+
int add_scrn_saver(void (*this)(int));
int remove_scrn_saver(void (*this)(int));
+void sc_clear_screen(scr_stat *scp);
+void sc_move_mouse(scr_stat *scp, int x, int y);
+int sc_clean_up(scr_stat *scp);
+void sc_alloc_scr_buffer(scr_stat *scp, int wait, int clear);
+void sc_alloc_cut_buffer(scr_stat *scp, int wait);
+void sc_alloc_history_buffer(scr_stat *scp, int lines, int extra, int wait);
+
+/* scvidctl.c */
+int sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode,
+ int xsize, int ysize, int fontsize);
+int sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode);
+int sc_set_pixel_mode(scr_stat *scp, struct tty *tp,
+ int xsize, int ysize, int fontsize);
+int sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag,
+ struct proc *p);
+
#ifdef SC_SPLASH_SCREEN
-void splash(int);
-int splash_load(void);
-int splash_unload(void);
+/* splash.c */
+void scsplash(int);
+int scsplash_load(scr_stat *scp);
+int scsplash_unload(scr_stat *scp);
#endif
#endif /* !_I386_ISA_SYSCONS_H_ */
diff --git a/sys/i386/isa/vesa.c b/sys/i386/isa/vesa.c
new file mode 100644
index 0000000..768b647
--- /dev/null
+++ b/sys/i386/isa/vesa.c
@@ -0,0 +1,868 @@
+/*-
+ * Copyright (c) 1998 Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp)
+ * 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. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#include "sc.h"
+#include "opt_vesa.h"
+#include "opt_vm86.h"
+
+#if (NSC > 0 && defined(VESA) && defined(VM86)) || defined(VESA_MODULE)
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <machine/console.h>
+#include <machine/md_var.h>
+#include <machine/vm86.h>
+#include <machine/pc/bios.h>
+#include <machine/pc/vesa.h>
+
+#include <i386/isa/videoio.h>
+
+#ifdef VESA_MODULE
+#include <sys/exec.h>
+#include <sys/sysent.h>
+#include <sys/lkm.h>
+
+MOD_MISC(vesa);
+#endif
+
+/* VESA video adapter state buffer stub */
+struct adp_state {
+ int sig;
+#define V_STATE_SIG 0x61736576
+ u_char regs[1];
+};
+typedef struct adp_state adp_state_t;
+
+/* VESA video adapter */
+static video_adapter_t *vesa_adp = NULL;
+static int vesa_state_buf_size = 0;
+static void *vesa_state_buf = NULL;
+
+/* VESA functions */
+static vi_init_t vesa_init;
+static vi_adapter_t vesa_adapter;
+static vi_get_info_t vesa_get_info;
+static vi_query_mode_t vesa_query_mode;
+static vi_set_mode_t vesa_set_mode;
+static vi_save_font_t vesa_save_font;
+static vi_load_font_t vesa_load_font;
+static vi_show_font_t vesa_show_font;
+static vi_save_palette_t vesa_save_palette;
+static vi_load_palette_t vesa_load_palette;
+static vi_set_border_t vesa_set_border;
+static vi_save_state_t vesa_save_state;
+static vi_load_state_t vesa_load_state;
+static vi_set_win_org_t vesa_set_origin;
+static vi_read_hw_cursor_t vesa_read_hw_cursor;
+static vi_set_hw_cursor_t vesa_set_hw_cursor;
+static vi_diag_t vesa_diag;
+
+static struct vidsw vesavidsw = {
+ vesa_init, vesa_adapter, vesa_get_info, vesa_query_mode,
+ vesa_set_mode, vesa_save_font, vesa_load_font, vesa_show_font,
+ vesa_save_palette,vesa_load_palette,vesa_set_border,vesa_save_state,
+ vesa_load_state,vesa_set_origin,vesa_read_hw_cursor,vesa_set_hw_cursor,
+ vesa_diag,
+};
+
+static struct vidsw prevvidsw;
+
+/* VESA BIOS video modes */
+#define VESA_MAXMODES 64
+#define EOT (-1)
+#define NA (-2)
+
+static video_info_t vesa_vmode[VESA_MAXMODES + 1] = {
+ { EOT, },
+};
+
+static int vesa_init_done = FALSE;
+static int has_vesa_bios = FALSE;
+static struct vesa_info *vesa_adp_info = NULL;
+static u_int16_t *vesa_vmodetab = NULL;
+
+/* local macros and functions */
+#define BIOS_SADDRTOLADDR(p) ((((p) & 0xffff0000) >> 12) + ((p) & 0x0000ffff))
+
+static int vesa_bios_get_mode(int mode, struct vesa_mode *vmode);
+static int vesa_bios_set_mode(int mode);
+static int vesa_bios_set_dac(int bits);
+static int vesa_bios_save_palette(int start, int colors, u_char *palette);
+static int vesa_bios_load_palette(int start, int colors, u_char *palette);
+#define STATE_SIZE 0
+#define STATE_SAVE 1
+#define STATE_LOAD 2
+#define STATE_HW (1<<0)
+#define STATE_DATA (1<<1)
+#define STATE_DAC (1<<2)
+#define STATE_REG (1<<3)
+#define STATE_MOST (STATE_HW | STATE_DATA | STATE_REG)
+#define STATE_ALL (STATE_HW | STATE_DATA | STATE_DAC | STATE_REG)
+static int vesa_bios_state_buf_size(void);
+static int vesa_bios_save_restore(int code, void *p, size_t size);
+static int translate_flags(u_int16_t vflags);
+static int vesa_bios_init(void);
+static void clear_modes(video_info_t *info, int color);
+
+static void
+dump_buffer(u_char *buf, size_t len)
+{
+ int i;
+
+ for(i = 0; i < len;) {
+ printf("%02x ", buf[i]);
+ if ((++i % 16) == 0)
+ printf("\n");
+ }
+}
+
+/* VESA BIOS calls */
+static int
+vesa_bios_get_mode(int mode, struct vesa_mode *vmode)
+{
+ struct vm86frame vmf;
+ u_char buf[256];
+ int err;
+
+ bzero(&vmf, sizeof(vmf));
+ bzero(buf, sizeof(buf));
+ vmf.vmf_eax = 0x4f01;
+ vmf.vmf_ecx = mode;
+ err = vm86_datacall(0x10, &vmf, (char *)buf, sizeof(buf),
+ &vmf.vmf_es, &vmf.vmf_di);
+ if ((err != 0) || (vmf.vmf_eax != 0x4f))
+ return 1;
+ bcopy(buf, vmode, sizeof(*vmode));
+ return 0;
+}
+
+static int
+vesa_bios_set_mode(int mode)
+{
+ struct vm86frame vmf;
+ int err;
+
+ bzero(&vmf, sizeof(vmf));
+ vmf.vmf_eax = 0x4f02;
+ vmf.vmf_ebx = mode;
+ err = vm86_intcall(0x10, &vmf);
+ return ((err != 0) || (vmf.vmf_eax != 0x4f));
+}
+
+static int
+vesa_bios_set_dac(int bits)
+{
+ struct vm86frame vmf;
+ int err;
+
+ bzero(&vmf, sizeof(vmf));
+ vmf.vmf_eax = 0x4f08;
+ vmf.vmf_ebx = (bits << 8);
+ err = vm86_intcall(0x10, &vmf);
+ return ((err != 0) || (vmf.vmf_eax != 0x4f));
+}
+
+static int
+vesa_bios_save_palette(int start, int colors, u_char *palette)
+{
+ struct vm86frame vmf;
+ u_char *p;
+ int err;
+ int i;
+
+ p = malloc(colors*4, M_DEVBUF, M_WAITOK);
+
+ bzero(&vmf, sizeof(vmf));
+ vmf.vmf_eax = 0x4f09;
+ vmf.vmf_ebx = 1; /* get primary palette data */
+ vmf.vmf_ecx = colors;
+ vmf.vmf_edx = start;
+ err = vm86_datacall(0x10, &vmf, p, colors*4, &vmf.vmf_es, &vmf.vmf_di);
+ if ((err != 0) || (vmf.vmf_eax != 0x4f)) {
+ free(p, M_DEVBUF);
+ return 1;
+ }
+
+ for (i = 0; i < colors; ++i) {
+ palette[i*3] = p[i*4 + 1];
+ palette[i*3 + 1] = p[i*4 + 2];
+ palette[i*3 + 2] = p[i*4 + 3];
+ }
+ free(p, M_DEVBUF);
+ return 0;
+}
+
+static int
+vesa_bios_load_palette(int start, int colors, u_char *palette)
+{
+ struct vm86frame vmf;
+ u_char *p;
+ int err;
+ int i;
+
+ p = malloc(colors*4, M_DEVBUF, M_WAITOK);
+ for (i = 0; i < colors; ++i) {
+ p[i*4] = 0;
+ p[i*4 + 1] = palette[i*3];
+ p[i*4 + 2] = palette[i*3 + 1];
+ p[i*4 + 3] = palette[i*3 + 2];
+ }
+
+ bzero(&vmf, sizeof(vmf));
+ vmf.vmf_eax = 0x4f09;
+ vmf.vmf_ebx = 0; /* set primary palette data */
+ vmf.vmf_ecx = colors;
+ vmf.vmf_edx = start;
+ err = vm86_datacall(0x10, &vmf, p, colors*4, &vmf.vmf_es, &vmf.vmf_di);
+ free(p, M_DEVBUF);
+ return ((err != 0) || (vmf.vmf_eax != 0x4f));
+}
+
+static int
+vesa_bios_state_buf_size(void)
+{
+ struct vm86frame vmf;
+ int err;
+
+ bzero(&vmf, sizeof(vmf));
+ vmf.vmf_eax = 0x4f04;
+ vmf.vmf_ecx = STATE_MOST;
+ vmf.vmf_edx = STATE_SIZE;
+ err = vm86_intcall(0x10, &vmf);
+ if ((err != 0) || (vmf.vmf_eax != 0x4f))
+ return 0;
+ return vmf.vmf_ebx*64;
+}
+
+static int
+vesa_bios_save_restore(int code, void *p, size_t size)
+{
+ struct vm86frame vmf;
+ int err;
+
+ bzero(&vmf, sizeof(vmf));
+ vmf.vmf_eax = 0x4f04;
+ vmf.vmf_ecx = STATE_MOST;
+ vmf.vmf_edx = code; /* STATE_SAVE/STATE_LOAD */
+ err = vm86_datacall(0x10, &vmf, (char *)p, size,
+ &vmf.vmf_es, &vmf.vmf_bx);
+ return ((err != 0) || (vmf.vmf_eax != 0x4f));
+}
+
+static int
+translate_flags(u_int16_t vflags)
+{
+ static struct {
+ u_int16_t mask;
+ int set;
+ int reset;
+ } ftable[] = {
+ { V_MODECOLOR, V_INFO_COLOR, 0 },
+ { V_MODEGRAPHICS, V_INFO_GRAPHICS, 0 },
+ { V_MODELFB, V_INFO_LENEAR, 0 },
+ };
+ int flags;
+ int i;
+
+ for (flags = 0, i = 0; i < sizeof(ftable)/sizeof(ftable[0]); ++i) {
+ flags |= (vflags & ftable[i].mask) ?
+ ftable[i].set : ftable[i].reset;
+ }
+ return flags;
+}
+
+static int
+vesa_bios_init(void)
+{
+ static u_char buf[512];
+ struct vm86frame vmf;
+ struct vesa_mode vmode;
+ u_int32_t p;
+ int modes;
+ int err;
+ int i;
+
+ if (vesa_init_done)
+ return 0;
+
+ has_vesa_bios = FALSE;
+ vesa_adp_info = NULL;
+ vesa_vmode[0].vi_mode = EOT;
+
+ bzero(&vmf, sizeof(vmf)); /* paranoia */
+ bzero(buf, sizeof(buf));
+ bcopy("VBE2", buf, 4); /* try for VBE2 data */
+ vmf.vmf_eax = 0x4f00;
+ err = vm86_datacall(0x10, &vmf, (char *)buf, sizeof(buf),
+ &vmf.vmf_es, &vmf.vmf_di);
+ if ((err != 0) || (vmf.vmf_eax != 0x4f) || bcmp("VESA", buf, 4))
+ return 1;
+ vesa_adp_info = (struct vesa_info *)buf;
+ if (bootverbose)
+ dump_buffer(buf, 64);
+ if (vesa_adp_info->v_flags & V_NONVGA)
+ return 1;
+
+ /* obtain video mode information */
+ p = BIOS_SADDRTOLADDR(vesa_adp_info->v_modetable);
+ vesa_vmodetab = (u_int16_t *)BIOS_PADDRTOVADDR(p);
+ for (i = 0, modes = 0; vesa_vmodetab[i] != 0xffff; ++i) {
+ if (modes >= VESA_MAXMODES)
+ break;
+ if (vesa_bios_get_mode(vesa_vmodetab[i], &vmode))
+ continue;
+
+ /* reject unsupported modes */
+#if 0
+ if ((vmode.v_modeattr & (V_MODESUPP | V_MODEOPTINFO
+ | V_MODENONVGA))
+ != (V_MODESUPP | V_MODEOPTINFO))
+ continue;
+#else
+ if ((vmode.v_modeattr & (V_MODEOPTINFO | V_MODENONVGA))
+ != (V_MODEOPTINFO))
+ continue;
+#endif
+
+ /* copy some fields */
+ bzero(&vesa_vmode[modes], sizeof(vesa_vmode[modes]));
+ vesa_vmode[modes].vi_mode = vesa_vmodetab[i];
+ vesa_vmode[modes].vi_width = vmode.v_width;
+ vesa_vmode[modes].vi_height = vmode.v_height;
+ vesa_vmode[modes].vi_depth = vmode.v_bpp;
+ vesa_vmode[modes].vi_planes = vmode.v_planes;
+ vesa_vmode[modes].vi_cwidth = vmode.v_cwidth;
+ vesa_vmode[modes].vi_cheight = vmode.v_cheight;
+ vesa_vmode[modes].vi_window = (u_int)vmode.v_waseg << 4;
+ /* XXX window B */
+ vesa_vmode[modes].vi_window_size = vmode.v_wsize;
+ vesa_vmode[modes].vi_window_gran = vmode.v_wgran;
+ vesa_vmode[modes].vi_buffer = vmode.v_lfb;
+ vesa_vmode[modes].vi_buffer_size = vmode.v_offscreen;
+ /* pixel format, memory model... */
+ vesa_vmode[modes].vi_flags = translate_flags(vmode.v_modeattr)
+ | V_INFO_VESA;
+ ++modes;
+ }
+ vesa_vmode[modes].vi_mode = EOT;
+ if (bootverbose)
+ printf("VESA: %d mode(s) found\n", modes);
+
+ has_vesa_bios = TRUE;
+ return 0;
+}
+
+static void
+clear_modes(video_info_t *info, int color)
+{
+ while (info->vi_mode != EOT) {
+ if ((info->vi_flags & V_INFO_COLOR) != color)
+ info->vi_mode = NA;
+ ++info;
+ }
+}
+
+/* exported functions */
+
+static int
+vesa_init(void)
+{
+ int adapters;
+ int i;
+
+ adapters = (*prevvidsw.init)();
+ for (i = 0; i < adapters; ++i) {
+ if ((vesa_adp = (*prevvidsw.adapter)(i)) == NULL)
+ continue;
+ if (vesa_adp->va_type == KD_VGA) {
+ vesa_adp->va_flags |= V_ADP_VESA;
+ return adapters;
+ }
+ }
+ vesa_adp = NULL;
+ return adapters;
+}
+
+static video_adapter_t
+*vesa_adapter(int ad)
+{
+ return (*prevvidsw.adapter)(ad);
+}
+
+static int
+vesa_get_info(int ad, int mode, video_info_t *info)
+{
+ int i;
+
+ if ((*prevvidsw.get_info)(ad, mode, info) == 0)
+ return 0;
+
+ if (ad != vesa_adp->va_index)
+ return 1;
+ for (i = 0; vesa_vmode[i].vi_mode != EOT; ++i) {
+ if (vesa_vmode[i].vi_mode == NA)
+ continue;
+ if (vesa_vmode[i].vi_mode == mode) {
+ *info = vesa_vmode[i];
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static int
+vesa_query_mode(int ad, video_info_t *info)
+{
+ int i;
+
+ if ((i = (*prevvidsw.query_mode)(ad, info)) != -1)
+ return i;
+ if (ad != vesa_adp->va_index)
+ return -1;
+
+ for (i = 0; vesa_vmode[i].vi_mode != EOT; ++i) {
+ if ((info->vi_width != 0)
+ && (info->vi_width != vesa_vmode[i].vi_width))
+ continue;
+ if ((info->vi_height != 0)
+ && (info->vi_height != vesa_vmode[i].vi_height))
+ continue;
+ if ((info->vi_cwidth != 0)
+ && (info->vi_cwidth != vesa_vmode[i].vi_cwidth))
+ continue;
+ if ((info->vi_cheight != 0)
+ && (info->vi_cheight != vesa_vmode[i].vi_cheight))
+ continue;
+ if ((info->vi_depth != 0)
+ && (info->vi_depth != vesa_vmode[i].vi_depth))
+ continue;
+ if ((info->vi_planes != 0)
+ && (info->vi_planes != vesa_vmode[i].vi_planes))
+ continue;
+ /* pixel format, memory model */
+ if ((info->vi_flags != 0)
+ && (info->vi_flags != vesa_vmode[i].vi_flags))
+ continue;
+ return vesa_vmode[i].vi_mode;
+ }
+ return -1;
+}
+
+static int
+vesa_set_mode(int ad, int mode)
+{
+ video_info_t info;
+ size_t len;
+
+ if (ad != vesa_adp->va_index)
+ return (*prevvidsw.set_mode)(ad, mode);
+
+#ifdef SC_VIDEO_DEBUG
+ printf("VESA: set_mode(): %d(%x) -> %d(%x)\n",
+ vesa_adp->va_mode, vesa_adp->va_mode, mode, mode);
+#endif
+ /*
+ * If the current mode is a VESA mode and the new mode is not,
+ * restore the state of the adapter first, so that non-standard,
+ * extended SVGA registers are set to the state compatible with
+ * the standard VGA modes. Otherwise (*prevvidsw.set_mode)()
+ * may not be able to set up the new mode correctly.
+ */
+ if (VESA_MODE(vesa_adp->va_mode)) {
+ if ((*prevvidsw.get_info)(ad, mode, &info) == 0) {
+ /* assert(vesa_state_buf != NULL); */
+ if ((vesa_state_buf == NULL)
+ || vesa_load_state(ad, vesa_state_buf))
+ return 1;
+ free(vesa_state_buf, M_DEVBUF);
+ vesa_state_buf = NULL;
+#ifdef SC_VIDEO_DEBUG
+ printf("VESA: restored\n");
+#endif
+ }
+ /*
+ * once (*prevvidsw.get_info)() succeeded,
+ * (*prevvidsw.set_mode)() below won't fail...
+ */
+ }
+
+ /* we may not need to handle this mode after all... */
+ if ((*prevvidsw.set_mode)(ad, mode) == 0)
+ return 0;
+
+ /* is the new mode supported? */
+ if (vesa_get_info(ad, mode, &info))
+ return 1;
+ /* assert(VESA_MODE(mode)); */
+
+#ifdef SC_VIDEO_DEBUG
+ printf("VESA: about to set a VESA mode...\n");
+#endif
+ /*
+ * If the current mode is not a VESA mode, save the current state
+ * so that the adapter state can be restored later when a non-VESA
+ * mode is to be set up. See above.
+ */
+ if (!VESA_MODE(vesa_adp->va_mode) && (vesa_state_buf == NULL)) {
+ len = vesa_save_state(ad, NULL, 0);
+ vesa_state_buf = malloc(len, M_DEVBUF, M_WAITOK);
+ if (vesa_save_state(ad, vesa_state_buf, len)) {
+#ifdef SC_VIDEO_DEBUG
+ printf("VESA: state save failed! (len=%d)\n", len);
+#endif
+ free(vesa_state_buf, M_DEVBUF);
+ vesa_state_buf = NULL;
+ return 1;
+ }
+#ifdef SC_VIDEO_DEBUG
+ printf("VESA: saved (len=%d)\n", len);
+ dump_buffer(vesa_state_buf, len);
+#endif
+ }
+
+ if (vesa_bios_set_mode(mode))
+ return 1;
+
+#ifdef SC_VIDEO_DEBUG
+ printf("VESA: mode set!\n");
+#endif
+ vesa_adp->va_mode = mode;
+ vesa_adp->va_flags &= ~V_ADP_COLOR;
+ vesa_adp->va_flags |=
+ (info.vi_flags & V_INFO_COLOR) ? V_ADP_COLOR : 0;
+ vesa_adp->va_crtc_addr =
+ (vesa_adp->va_flags & V_ADP_COLOR) ? COLOR_BASE : MONO_BASE;
+ vesa_adp->va_window = BIOS_PADDRTOVADDR(info.vi_window);
+ vesa_adp->va_window_size = info.vi_window_size;
+ vesa_adp->va_window_gran = info.vi_window_gran;
+ if (info.vi_buffer_size == 0) {
+ vesa_adp->va_buffer = 0;
+ vesa_adp->va_buffer_size = 0;
+ } else {
+ vesa_adp->va_buffer = BIOS_PADDRTOVADDR(info.vi_buffer);
+ vesa_adp->va_buffer_size = info.vi_buffer_size;
+ }
+
+ return 0;
+}
+
+static int
+vesa_save_font(int ad, int page, int fontsize, u_char *data, int ch, int count)
+{
+ return (*prevvidsw.save_font)(ad, page, fontsize, data, ch, count);
+}
+
+static int
+vesa_load_font(int ad, int page, int fontsize, u_char *data, int ch, int count)
+{
+ return (*prevvidsw.load_font)(ad, page, fontsize, data, ch, count);
+}
+
+static int
+vesa_show_font(int ad, int page)
+{
+ return (*prevvidsw.show_font)(ad, page);
+}
+
+static int
+vesa_save_palette(int ad, u_char *palette)
+{
+ if ((ad != vesa_adp->va_index) || !(vesa_adp_info->v_flags & V_DAC8)
+ || vesa_bios_set_dac(8))
+ return (*prevvidsw.save_palette)(ad, palette);
+
+ return vesa_bios_save_palette(0, 256, palette);
+}
+
+static int
+vesa_load_palette(int ad, u_char *palette)
+{
+ if ((ad != vesa_adp->va_index) || !(vesa_adp_info->v_flags & V_DAC8)
+ || vesa_bios_set_dac(8))
+ return (*prevvidsw.load_palette)(ad, palette);
+
+ return vesa_bios_load_palette(0, 256, palette);
+}
+
+static int
+vesa_set_border(int ad, int color)
+{
+ return (*prevvidsw.set_border)(ad, color);
+}
+
+static int
+vesa_save_state(int ad, void *p, size_t size)
+{
+ if (ad != vesa_adp->va_index)
+ return (*prevvidsw.save_state)(ad, p, size);
+
+ if (vesa_state_buf_size == 0)
+ vesa_state_buf_size = vesa_bios_state_buf_size();
+ if (size == 0)
+ return (sizeof(int) + vesa_state_buf_size);
+ else if (size < (sizeof(int) + vesa_state_buf_size))
+ return 1;
+
+ ((adp_state_t *)p)->sig = V_STATE_SIG;
+ bzero(((adp_state_t *)p)->regs, vesa_state_buf_size);
+ return vesa_bios_save_restore(STATE_SAVE, ((adp_state_t *)p)->regs,
+ vesa_state_buf_size);
+}
+
+static int
+vesa_load_state(int ad, void *p)
+{
+ if ((ad != vesa_adp->va_index)
+ || (((adp_state_t *)p)->sig != V_STATE_SIG))
+ return (*prevvidsw.load_state)(ad, p);
+
+ return vesa_bios_save_restore(STATE_LOAD, ((adp_state_t *)p)->regs,
+ vesa_state_buf_size);
+}
+
+static int
+vesa_set_origin(int ad, off_t offset)
+{
+ struct vm86frame vmf;
+ int err;
+
+ /*
+ * This function should return as quickly as possible to
+ * maintain good performance of the system. For this reason,
+ * error checking is kept minimal and let the VESA BIOS to
+ * detect error.
+ */
+ if (ad != vesa_adp->va_index)
+ return (*prevvidsw.set_win_org)(ad, offset);
+
+ if (vesa_adp->va_window_gran == 0)
+ return 1;
+ bzero(&vmf, sizeof(vmf));
+ vmf.vmf_eax = 0x4f05;
+ vmf.vmf_ebx = 0; /* WINDOW_A, XXX */
+ vmf.vmf_edx = offset/vesa_adp->va_window_gran;
+ err = vm86_intcall(0x10, &vmf);
+ return ((err != 0) || (vmf.vmf_eax != 0x4f));
+}
+
+static int
+vesa_read_hw_cursor(int ad, int *col, int *row)
+{
+ return (*prevvidsw.read_hw_cursor)(ad, col, row);
+}
+
+static int
+vesa_set_hw_cursor(int ad, int col, int row)
+{
+ return (*prevvidsw.set_hw_cursor)(ad, col, row);
+}
+
+static int
+vesa_diag(int level)
+{
+ struct vesa_mode vmode;
+ u_int32_t p;
+ int i;
+
+ /* general adapter information */
+ printf("VESA: v%d.%d, %dk memory, flags:0x%x, mode table:%p (%x)\n",
+ ((vesa_adp_info->v_version & 0xf000) >> 12) * 10
+ + ((vesa_adp_info->v_version & 0x0f00) >> 8),
+ ((vesa_adp_info->v_version & 0x00f0) >> 4) * 10
+ + (vesa_adp_info->v_version & 0x000f),
+ vesa_adp_info->v_memsize * 64, vesa_adp_info->v_flags,
+ vesa_vmodetab, vesa_adp_info->v_modetable);
+ /* OEM string */
+ p = BIOS_SADDRTOLADDR(vesa_adp_info->v_oemstr);
+ if (p != 0)
+ printf("VESA: %s\n", (char *)BIOS_PADDRTOVADDR(p));
+
+ if (level <= 0)
+ return 0;
+
+ if (vesa_adp_info->v_version >= 0x0200) {
+ /* vendor name */
+ p = BIOS_SADDRTOLADDR(vesa_adp_info->v_venderstr);
+ if (p != 0)
+ printf("VESA: %s, ", (char *)BIOS_PADDRTOVADDR(p));
+ /* product name */
+ p = BIOS_SADDRTOLADDR(vesa_adp_info->v_prodstr);
+ if (p != 0)
+ printf("%s, ", (char *)BIOS_PADDRTOVADDR(p));
+ /* product revision */
+ p = BIOS_SADDRTOLADDR(vesa_adp_info->v_revstr);
+ if (p != 0)
+ printf("%s\n", (char *)BIOS_PADDRTOVADDR(p));
+ }
+
+ /* mode information */
+ for (i = 0; vesa_vmodetab[i] != 0xffff; ++i) {
+ if (vesa_bios_get_mode(vesa_vmodetab[i], &vmode))
+ continue;
+
+ /* print something for diagnostic purpose */
+ printf("VESA: mode:0x%03x, flags:0x%04x",
+ vesa_vmodetab[i], vmode.v_modeattr);
+ if (vmode.v_modeattr & V_MODEOPTINFO) {
+ if (vmode.v_modeattr & V_MODEGRAPHICS) {
+ printf(", G %dx%dx%d %d, ",
+ vmode.v_width, vmode.v_height,
+ vmode.v_bpp, vmode.v_planes);
+ } else {
+ printf(", T %dx%d, ",
+ vmode.v_width, vmode.v_height);
+ }
+ printf("font:%dx%d",
+ vmode.v_cwidth, vmode.v_cheight);
+ }
+ if (vmode.v_modeattr & V_MODELFB) {
+ printf(", mem:%d, LFB:0x%x, off:0x%x",
+ vmode.v_memmodel, vmode.v_lfb,
+ vmode.v_offscreen);
+ }
+ printf("\n");
+ printf("VESA: window A:0x%x (%x), window B:0x%x (%x), ",
+ vmode.v_waseg, vmode.v_waattr,
+ vmode.v_wbseg, vmode.v_wbattr);
+ printf("size:%dk, gran:%dk\n",
+ vmode.v_wsize, vmode.v_wgran);
+ }
+
+ return 0;
+}
+
+/* module loading */
+
+#ifdef VESA_MODULE
+static int
+vesa_load(struct lkm_table *lkmtp, int cmd)
+#else
+int
+vesa_load(void)
+#endif
+{
+ int adapters;
+ int error;
+ int s;
+ int i;
+
+ if (vesa_init_done)
+ return 0;
+
+ /*
+ * If the VESA module is statically linked to the kernel, or
+ * it has already been loaded, abort loading this module this time.
+ */
+ vesa_adp = NULL;
+ adapters = (*biosvidsw.init)();
+ for (i = 0; i < adapters; ++i) {
+ if ((vesa_adp = (*biosvidsw.adapter)(i)) == NULL)
+ continue;
+ if (vesa_adp->va_flags & V_ADP_VESA)
+ return ENXIO;
+ if (vesa_adp->va_type == KD_VGA)
+ break;
+ }
+ /* if a VGA adapter is not found, abort */
+ if (i >= adapters)
+ return ENXIO;
+
+ if (vesa_bios_init())
+ return ENXIO;
+ vesa_adp->va_flags |= V_ADP_VESA;
+
+ /* remove conflicting modes if we have more than one adapter */
+ if (adapters > 1) {
+ clear_modes(vesa_vmode,
+ (vesa_adp->va_flags & V_ADP_COLOR) ?
+ V_INFO_COLOR : 0);
+ }
+
+#ifdef VESA_MODULE
+ s = spltty();
+#endif
+ if ((error = vesa_load_ioctl()) == 0) {
+ bcopy(&biosvidsw, &prevvidsw, sizeof(prevvidsw));
+ bcopy(&vesavidsw, &biosvidsw, sizeof(vesavidsw));
+ vesa_init_done = TRUE;
+ }
+#ifdef VESA_MODULE
+ splx(s);
+
+ if (error == 0)
+ vesa_diag(bootverbose);
+#endif
+
+ return error;
+}
+
+#ifdef VESA_MODULE
+
+static int
+vesa_unload(struct lkm_table *lkmtp, int cmd)
+{
+ int error;
+ int s;
+
+ /* if the adapter is currently in a VESA mode, don't unload */
+ if ((vesa_adp != NULL) && VESA_MODE(vesa_adp->va_mode))
+ return EBUSY;
+ /*
+ * FIXME: if there is at least one vty which is in a VESA mode,
+ * we shouldn't be unloading! XXX
+ */
+
+ s = spltty();
+ if ((error = vesa_unload_ioctl()) == 0) {
+ if (vesa_adp)
+ vesa_adp->va_flags &= ~V_ADP_VESA;
+ bcopy(&prevvidsw, &biosvidsw, sizeof(biosvidsw));
+ }
+ splx(s);
+
+ return error;
+}
+
+int
+vesa_mod(struct lkm_table *lkmtp, int cmd, int ver)
+{
+ MOD_DISPATCH(vesa, lkmtp, cmd, ver,
+ vesa_load, vesa_unload, lkm_nullcmd);
+}
+
+#endif /* VESA_MODULE */
+
+#endif /* (NSC > 0 && VESA && VM86) || VESA_MODULE */
diff --git a/sys/i386/isa/videoio.c b/sys/i386/isa/videoio.c
new file mode 100644
index 0000000..85c8f8d
--- /dev/null
+++ b/sys/i386/isa/videoio.c
@@ -0,0 +1,1612 @@
+/*-
+ * Copyright (c) 1998 Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp)
+ * 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. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#include "sc.h"
+#include "opt_syscons.h"
+
+#if NSC > 0
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <machine/clock.h>
+#include <machine/console.h>
+#include <machine/md_var.h>
+#include <machine/pc/bios.h>
+
+#include <i386/isa/isa.h>
+#include <i386/isa/videoio.h>
+
+/* this should really be in `rtc.h' */
+#define RTC_EQUIPMENT 0x14
+
+/* video adapter state buffer */
+struct adp_state {
+ int sig;
+#define V_STATE_SIG 0x736f6962
+ u_char regs[V_MODE_PARAM_SIZE];
+};
+typedef struct adp_state adp_state_t;
+
+/* video adapter information */
+#define DCC_MONO 0
+#define DCC_CGA40 1
+#define DCC_CGA80 2
+#define DCC_EGAMONO 3
+#define DCC_EGA40 4
+#define DCC_EGA80 5
+
+/*
+ * NOTE: `va_window' should have a virtual address, but is initialized
+ * with a physical address in the following table, as verify_adapter()
+ * will perform address conversion at run-time.
+ */
+static video_adapter_t adapter_init_value[] = {
+ { 0, KD_MONO, 0, MONO_BASE, 0xb0000, 32, 32, 0, 0, 0, 7, 0 },
+ { 0, KD_CGA, V_ADP_COLOR, COLOR_BASE, 0xb8000, 32, 32, 0, 0, 0, 3, 0 },
+ { 0, KD_CGA, V_ADP_COLOR, COLOR_BASE, 0xb8000, 32, 32, 0, 0, 0, 3, 0 },
+ { 0, KD_EGA, 0, MONO_BASE, 0xb0000, 32, 32, 0, 0, 0, 7, 0 },
+ { 0, KD_EGA, V_ADP_COLOR, COLOR_BASE, 0xb8000, 32, 32, 0, 0, 0, 3, 0 },
+ { 0, KD_EGA, V_ADP_COLOR, COLOR_BASE, 0xb8000, 32, 32, 0, 0, 0, 3, 0 },
+};
+
+static video_adapter_t adapter[V_MAX_ADAPTERS];
+static int adapters = 0;
+
+/* VGA function entries */
+static vi_init_t vid_init;
+static vi_adapter_t vid_adapter;
+static vi_get_info_t vid_get_info;
+static vi_query_mode_t vid_query_mode;
+static vi_set_mode_t vid_set_mode;
+static vi_save_font_t vid_save_font;
+static vi_load_font_t vid_load_font;
+static vi_show_font_t vid_show_font;
+static vi_save_palette_t vid_save_palette;
+static vi_load_palette_t vid_load_palette;
+static vi_set_border_t vid_set_border;
+static vi_save_state_t vid_save_state;
+static vi_load_state_t vid_load_state;
+static vi_set_win_org_t vid_set_origin;
+static vi_read_hw_cursor_t vid_read_hw_cursor;
+static vi_set_hw_cursor_t vid_set_hw_cursor;
+static vi_diag_t vid_diag;
+
+struct vidsw biosvidsw = {
+ vid_init, vid_adapter, vid_get_info, vid_query_mode,
+ vid_set_mode, vid_save_font, vid_load_font, vid_show_font,
+ vid_save_palette,vid_load_palette,vid_set_border,vid_save_state,
+ vid_load_state, vid_set_origin, vid_read_hw_cursor, vid_set_hw_cursor,
+ vid_diag,
+};
+
+/* VGA BIOS standard video modes */
+#define EOT (-1)
+#define NA (-2)
+
+static video_info_t bios_vmode[] = {
+ /* CGA */
+ { M_B40x25, V_INFO_COLOR, 40, 25, 8, 8, 2, 1, 0xb8000, 32, 32, 0, 32 },
+ { M_C40x25, V_INFO_COLOR, 40, 25, 8, 8, 4, 1, 0xb8000, 32, 32, 0, 32 },
+ { M_B80x25, V_INFO_COLOR, 80, 25, 8, 8, 2, 1, 0xb8000, 32, 32, 0, 32 },
+ { M_C80x25, V_INFO_COLOR, 80, 25, 8, 8, 4, 1, 0xb8000, 32, 32, 0, 32 },
+ /* EGA */
+ { M_ENH_B40x25, V_INFO_COLOR, 40, 25, 8, 14, 2, 1, 0xb8000, 32, 32, 0, 32 },
+ { M_ENH_C40x25, V_INFO_COLOR, 40, 25, 8, 14, 4, 1, 0xb8000, 32, 32, 0, 32 },
+ { M_ENH_B80x25, V_INFO_COLOR, 80, 25, 8, 14, 2, 1, 0xb8000, 32, 32, 0, 32 },
+ { M_ENH_C80x25, V_INFO_COLOR, 80, 25, 8, 14, 4, 1, 0xb8000, 32, 32, 0, 32 },
+ /* VGA */
+ { M_VGA_C40x25, V_INFO_COLOR, 40, 25, 8, 16, 4, 1, 0xb8000, 32, 32, 0, 32 },
+ { M_VGA_M80x25, 0, 80, 25, 8, 16, 2, 1, 0xb0000, 32, 32, 0, 32 },
+ { M_VGA_C80x25, V_INFO_COLOR, 80, 25, 8, 16, 4, 1, 0xb8000, 32, 32, 0, 32 },
+ /* MDA */
+ { M_EGAMONO80x25, 0, 80, 25, 8, 14, 2, 1, 0xb0000, 32, 32, 0, 32 },
+ /* EGA */
+ { M_ENH_B80x43, V_INFO_COLOR, 80, 43, 8, 8, 2, 1, 0xb8000, 32, 32, 0, 32 },
+ { M_ENH_C80x43, V_INFO_COLOR, 80, 43, 8, 8, 4, 1, 0xb8000, 32, 32, 0, 32 },
+ /* VGA */
+ { M_VGA_M80x30, 0, 80, 30, 8, 16, 2, 1, 0xb0000, 32, 32, 0, 32 },
+ { M_VGA_C80x30, V_INFO_COLOR, 80, 30, 8, 16, 4, 1, 0xb8000, 32, 32, 0, 32 },
+ { M_VGA_M80x50, 0, 80, 50, 8, 8, 2, 1, 0xb0000, 32, 32, 0, 32 },
+ { M_VGA_C80x50, V_INFO_COLOR, 80, 50, 8, 8, 4, 1, 0xb8000, 32, 32, 0, 32 },
+ { M_VGA_M80x60, 0, 80, 60, 8, 8, 2, 1, 0xb0000, 32, 32, 0, 32 },
+ { M_VGA_C80x60, V_INFO_COLOR, 80, 60, 8, 8, 4, 1, 0xb8000, 32, 32, 0, 32 },
+ /* CGA */
+ { M_BG320, V_INFO_COLOR | V_INFO_GRAPHICS,
+ 320, 200, 8, 8, 2, 1, 0xb8000, 32, 32, 0, 32 },
+ { M_CG320, V_INFO_COLOR | V_INFO_GRAPHICS,
+ 320, 200, 8, 8, 2, 1, 0xb8000, 32, 32, 0, 32 },
+ { M_BG640, V_INFO_COLOR | V_INFO_GRAPHICS,
+ 640, 200, 8, 8, 1, 1, 0xb8000, 32, 32, 0, 32 },
+ /* EGA */
+ { M_CG320_D, V_INFO_COLOR | V_INFO_GRAPHICS,
+ 320, 200, 8, 8, 4, 4, 0xa0000, 64, 64, 0, 64 },
+ { M_CG640_E, V_INFO_COLOR | V_INFO_GRAPHICS,
+ 640, 200, 8, 8, 4, 4, 0xa0000, 64, 64, 0, 64 },
+ { M_EGAMONOAPA, V_INFO_GRAPHICS,
+ 640, 350, 8, 14, 4, 4, 0xa0000, 64, 64, 0, 64 },
+ { M_ENHMONOAPA2,V_INFO_GRAPHICS,
+ 640, 350, 8, 14, 4, 4, 0xa0000, 64, 64, 0, 64 },
+ { M_CG640x350, V_INFO_COLOR | V_INFO_GRAPHICS,
+ 640, 350, 8, 14, 2, 2, 0xa0000, 64, 64, 0, 64 },
+ { M_ENH_CG640, V_INFO_COLOR | V_INFO_GRAPHICS,
+ 640, 350, 8, 14, 4, 4, 0xa0000, 64, 64, 0, 64 },
+ /* VGA */
+ { M_BG640x480, V_INFO_COLOR | V_INFO_GRAPHICS,
+ 640, 480, 8, 16, 4, 4, 0xa0000, 64, 64, 0, 64 },
+ { M_CG640x480, V_INFO_COLOR | V_INFO_GRAPHICS,
+ 640, 480, 8, 16, 4, 4, 0xa0000, 64, 64, 0, 64 },
+ { M_VGA_CG320, V_INFO_COLOR | V_INFO_GRAPHICS,
+ 320, 200, 8, 8, 8, 1, 0xa0000, 64, 64, 0, 64 },
+ { M_VGA_MODEX, V_INFO_COLOR | V_INFO_GRAPHICS,
+ 320, 240, 8, 8, 8, 1, 0xa0000, 64, 64, 0, 64 },
+
+ { EOT },
+};
+
+static int init_done = FALSE;
+static u_char *video_mode_ptr = NULL; /* EGA/VGA */
+static u_char *video_mode_ptr2 = NULL; /* CGA/MDA */
+static u_char *mode_map[V_MODE_MAP_SIZE];
+static adp_state_t adpstate;
+static adp_state_t adpstate2;
+static int rows_offset = 1;
+
+/* local macros and functions */
+#define BIOS_SADDRTOLADDR(p) ((((p) & 0xffff0000) >> 12) + ((p) & 0x0000ffff))
+
+static void map_mode_table(u_char *map[], u_char *table, int max);
+static void clear_mode_map(int ad, u_char *map[], int max, int color);
+static int map_mode_num(int mode);
+static int map_bios_mode_num(int type, int color, int bios_mode);
+static u_char *get_mode_param(int mode);
+static void fill_adapter_param(int code, video_adapter_t *adp);
+static int verify_adapter(video_adapter_t *adp);
+#define COMP_IDENTICAL 0
+#define COMP_SIMILAR 1
+#define COMP_DIFFERENT 2
+static int comp_adpregs(u_char *buf1, u_char *buf2);
+
+#define PARAM_BUFSIZE 6
+static void set_font_mode(video_adapter_t *adp, u_char *buf);
+static void set_normal_mode(video_adapter_t *adp, u_char *buf);
+
+static char *adapter_name(int type);
+static void dump_adp_info(int ad, video_adapter_t *adp, int level);
+static void dump_mode_info(int ad, video_info_t *info, int level);
+static void dump_buffer(u_char *buf, size_t len);
+
+extern void generic_bcopy(const void *, void *, size_t);
+
+#define ISMAPPED(pa, width) \
+ (((pa) <= (u_long)0x1000 - (width)) \
+ || ((pa) >= ISA_HOLE_START && (pa) <= 0x100000 - (width)))
+
+#define prologue(ad, flag, err) \
+ if (!init_done \
+ || ((ad) < 0) || ((ad) >= adapters) \
+ || !(adapter[(ad)].va_flags & (flag))) \
+ return (err)
+
+/* construct the mode parameter map */
+static void
+map_mode_table(u_char *map[], u_char *table, int max)
+{
+ int i;
+
+ for(i = 0; i < max; ++i)
+ map[i] = table + i*V_MODE_PARAM_SIZE;
+ for(; i < V_MODE_MAP_SIZE; ++i)
+ map[i] = NULL;
+}
+
+static void
+clear_mode_map(int ad, u_char *map[], int max, int color)
+{
+ video_info_t info;
+ int i;
+
+ /*
+ * NOTE: we don't touch `bios_vmode[]' because it is shared
+ * by all adapters.
+ */
+ for(i = 0; i < max; ++i) {
+ if (vid_get_info(ad, i, &info))
+ continue;
+ if ((info.vi_flags & V_INFO_COLOR) != color)
+ map[i] = NULL;
+ }
+}
+
+/* the non-standard video mode is based on a standard mode... */
+static int
+map_mode_num(int mode)
+{
+ static struct {
+ int from;
+ int to;
+ } mode_map[] = {
+ { M_ENH_B80x43, M_ENH_B80x25 },
+ { M_ENH_C80x43, M_ENH_C80x25 },
+ { M_VGA_M80x30, M_VGA_M80x25 },
+ { M_VGA_C80x30, M_VGA_C80x25 },
+ { M_VGA_M80x50, M_VGA_M80x25 },
+ { M_VGA_C80x50, M_VGA_C80x25 },
+ { M_VGA_M80x60, M_VGA_M80x25 },
+ { M_VGA_C80x60, M_VGA_C80x25 },
+ { M_VGA_MODEX, M_VGA_CG320 },
+ };
+ int i;
+
+ for (i = 0; i < sizeof(mode_map)/sizeof(mode_map[0]); ++i) {
+ if (mode_map[i].from == mode)
+ return mode_map[i].to;
+ }
+ return mode;
+}
+
+/* turn the BIOS video number into our video mode number */
+static int
+map_bios_mode_num(int type, int color, int bios_mode)
+{
+ static int cga_modes[7] = {
+ M_B40x25, M_C40x25, /* 0, 1 */
+ M_B80x25, M_C80x25, /* 2, 3 */
+ M_BG320, M_CG320,
+ M_BG640,
+ };
+ static int ega_modes[17] = {
+ M_ENH_B40x25, M_ENH_C40x25, /* 0, 1 */
+ M_ENH_B80x25, M_ENH_C80x25, /* 2, 3 */
+ M_BG320, M_CG320,
+ M_BG640,
+ M_EGAMONO80x25, /* 7 */
+ 8, 9, 10, 11, 12,
+ M_CG320_D,
+ M_CG640_E,
+ M_ENHMONOAPA2, /* XXX: video momery > 64K */
+ M_ENH_CG640, /* XXX: video momery > 64K */
+ };
+ static int vga_modes[20] = {
+ M_VGA_C40x25, M_VGA_C40x25, /* 0, 1 */
+ M_VGA_C80x25, M_VGA_C80x25, /* 2, 3 */
+ M_BG320, M_CG320,
+ M_BG640,
+ M_VGA_M80x25, /* 7 */
+ 8, 9, 10, 11, 12,
+ M_CG320_D,
+ M_CG640_E,
+ M_ENHMONOAPA2,
+ M_ENH_CG640,
+ M_BG640x480, M_CG640x480,
+ M_VGA_CG320,
+ };
+
+ switch (type) {
+
+ case KD_VGA:
+ if (bios_mode < sizeof(vga_modes)/sizeof(vga_modes[0]))
+ return vga_modes[bios_mode];
+ else if (color)
+ return M_VGA_C80x25;
+ else
+ return M_VGA_M80x25;
+ break;
+
+ case KD_EGA:
+ if (bios_mode < sizeof(ega_modes)/sizeof(ega_modes[0]))
+ return ega_modes[bios_mode];
+ else if (color)
+ return M_ENH_C80x25;
+ else
+ return M_EGAMONO80x25;
+ break;
+
+ case KD_CGA:
+ if (bios_mode < sizeof(cga_modes)/sizeof(cga_modes[0]))
+ return cga_modes[bios_mode];
+ else
+ return M_C80x25;
+ break;
+
+ case KD_MONO:
+ case KD_HERCULES:
+ return M_EGAMONO80x25; /* XXX: this name is confusing */
+
+ default:
+ break;
+ }
+ return -1;
+}
+
+/* look up a parameter table entry */
+static u_char
+*get_mode_param(int mode)
+{
+ if (mode >= V_MODE_MAP_SIZE)
+ mode = map_mode_num(mode);
+ if (mode < V_MODE_MAP_SIZE)
+ return mode_map[mode];
+ else
+ return NULL;
+}
+
+static void
+fill_adapter_param(int code, video_adapter_t *adp)
+{
+ static struct {
+ int primary;
+ int secondary;
+ } dcc[] = {
+ { DCC_MONO, DCC_EGA40 /* CGA monitor */ },
+ { DCC_MONO, DCC_EGA80 /* CGA monitor */ },
+ { DCC_MONO, DCC_EGA80 /* CGA emulation */ },
+ { DCC_MONO, DCC_EGA80 },
+ { DCC_CGA40, DCC_EGAMONO },
+ { DCC_CGA80, DCC_EGAMONO },
+ { DCC_EGA40 /* CGA monitor */, DCC_MONO},
+ { DCC_EGA80 /* CGA monitor */, DCC_MONO},
+ { DCC_EGA80 /* CGA emulation */,DCC_MONO },
+ { DCC_EGA80, DCC_MONO },
+ { DCC_EGAMONO, DCC_CGA40 },
+ { DCC_EGAMONO, DCC_CGA40 },
+ };
+
+ if ((code < 0) || (code >= sizeof(dcc)/sizeof(dcc[0]))) {
+ adp[V_ADP_PRIMARY] = adapter_init_value[DCC_MONO];
+ adp[V_ADP_SECONDARY] = adapter_init_value[DCC_CGA80];
+ } else {
+ adp[V_ADP_PRIMARY] = adapter_init_value[dcc[code].primary];
+ adp[V_ADP_SECONDARY] = adapter_init_value[dcc[code].secondary];
+ }
+}
+
+static int
+verify_adapter(video_adapter_t *adp)
+{
+ u_short volatile *buf;
+ u_short v;
+ u_int32_t p;
+
+ buf = (u_short *)BIOS_PADDRTOVADDR(adp->va_window);
+ v = *buf;
+ *buf = (u_short) 0xA55A;
+ if (*buf != 0xA55A)
+ return 1;
+ *buf = v;
+
+ switch (adp->va_type) {
+
+ case KD_EGA:
+ outb(adp->va_crtc_addr, 7);
+ if (inb(adp->va_crtc_addr) == 7) {
+ adp->va_type = KD_VGA;
+ adp->va_flags |= V_ADP_STATESAVE | V_ADP_PALETTE;
+ }
+ adp->va_flags |= V_ADP_STATELOAD | V_ADP_FONT | V_ADP_BORDER;
+ /* the color adapter may be in the 40x25 mode... XXX */
+
+ /* get the BIOS video mode pointer */
+ p = *(u_int32_t *)BIOS_PADDRTOVADDR(0x4a8);
+ p = BIOS_SADDRTOLADDR(p);
+ if (ISMAPPED(p, sizeof(u_int32_t))) {
+ p = *(u_int32_t *)BIOS_PADDRTOVADDR(p);
+ p = BIOS_SADDRTOLADDR(p);
+ if (ISMAPPED(p, V_MODE_PARAM_SIZE))
+ video_mode_ptr = (u_char *)BIOS_PADDRTOVADDR(p);
+ }
+ break;
+
+ case KD_CGA:
+ adp->va_flags |= V_ADP_COLOR | V_ADP_BORDER;
+ /* may be in the 40x25 mode... XXX */
+ break;
+
+ case KD_MONO:
+ break;
+ }
+
+ return 0;
+}
+
+/* compare two parameter table entries */
+static int
+comp_adpregs(u_char *buf1, u_char *buf2)
+{
+ static struct {
+ u_char mask;
+ } params[V_MODE_PARAM_SIZE] = {
+ 0xff, 0x00, 0xff, /* COLS, ROWS, POINTS */
+ 0x00, 0x00, /* page length */
+ 0xfe, 0xff, 0xff, 0xff, /* sequencer registers */
+ 0xf3, /* misc register */
+ 0xff, 0xff, 0xff, 0x7f, 0xff, /* CRTC */
+ 0xff, 0xff, 0xff, 0x7f, 0xff,
+ 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xff, 0x7f, 0xff, 0xff,
+ 0x7f, 0xff, 0xff, 0xef, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, /* attribute controller registers */
+ 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xf0,
+ 0xff, 0xff, 0xff, 0xff, 0xff, /* GDC register */
+ 0xff, 0xff, 0xff, 0xff,
+ };
+ int identical = TRUE;
+ int i;
+
+ if ((buf1 == NULL) || (buf2 == NULL))
+ return COMP_DIFFERENT;
+
+ for (i = 0; i < sizeof(params)/sizeof(params[0]); ++i) {
+ if (params[i].mask == 0) /* don't care */
+ continue;
+ if ((buf1[i] & params[i].mask) != (buf2[i] & params[i].mask))
+ return COMP_DIFFERENT;
+ if (buf1[i] != buf2[i])
+ identical = FALSE;
+ }
+ return (identical) ? COMP_IDENTICAL : COMP_SIMILAR;
+}
+
+/* exported functions */
+
+/* all adapters */
+static int
+vid_init(void)
+{
+ video_adapter_t *adp;
+ video_info_t info;
+ u_char *mp;
+ int i;
+
+ /* do this test only once */
+ if (init_done)
+ return adapters;
+ init_done = TRUE;
+
+ /*
+ * Locate display adapters.
+ * The AT architecture supports upto two adapters. `syscons' allows
+ * the following combinations of adapters:
+ * 1) MDA + CGA
+ * 2) MDA + EGA/VGA color
+ * 3) CGA + EGA/VGA mono
+ * Note that `syscons' doesn't bother with MCGA as it is only
+ * avaiable for low end PS/2 models which has 80286 or earlier CPUs,
+ * thus, they are not running FreeBSD!
+ * When there are two adapaters in the system, one becomes `primary'
+ * and the other `secondary'. The EGA adapter has a set of DIP
+ * switches on board for this information and the EGA BIOS copies
+ * it in the BIOS data area BIOSDATA_VIDEOSWITCH (40:88).
+ * The VGA BIOS has more sophisticated mechanism and has this
+ * information in BIOSDATA_DCCINDEX (40:8a), but it also maintains
+ * compatibility with the EGA BIOS by updating BIOSDATA_VIDEOSWITCH.
+ */
+
+ /* check rtc and BIOS date area */
+ /*
+ * XXX: don't use BIOSDATA_EQUIPMENT, it is not a dead copy
+ * of RTC_EQUIPMENT. The bit 4 and 5 of the ETC_EQUIPMENT are
+ * zeros for EGA and VGA. However, the EGA/VGA BIOS will set
+ * these bits in BIOSDATA_EQUIPMENT according to the monitor
+ * type detected.
+ */
+ switch ((rtcin(RTC_EQUIPMENT) >> 4) & 3) { /* bit 4 and 5 */
+ case 0:
+ /* EGA/VGA */
+ fill_adapter_param(*(u_int8_t *)BIOS_PADDRTOVADDR(0x488) & 0x0f,
+ adapter);
+ break;
+ case 1:
+ /* CGA 40x25 */
+ /* FIXME: switch to the 80x25 mode? XXX */
+ adapter[V_ADP_PRIMARY] = adapter_init_value[DCC_CGA40];
+ adapter[V_ADP_SECONDARY] = adapter_init_value[DCC_MONO];
+ break;
+ case 2:
+ /* CGA 80x25 */
+ adapter[V_ADP_PRIMARY] = adapter_init_value[DCC_CGA80];
+ adapter[V_ADP_SECONDARY] = adapter_init_value[DCC_MONO];
+ break;
+ case 3:
+ /* MDA */
+ adapter[V_ADP_PRIMARY] = adapter_init_value[DCC_MONO];
+ adapter[V_ADP_SECONDARY] = adapter_init_value[DCC_CGA80];
+ break;
+ }
+
+ adapters = 0;
+ if (verify_adapter(&adapter[V_ADP_SECONDARY]) == 0) {
+ ++adapters;
+ adapter[V_ADP_SECONDARY].va_mode =
+ adapter[V_ADP_SECONDARY].va_initial_mode =
+ map_bios_mode_num(adapter[V_ADP_SECONDARY].va_type,
+ adapter[V_ADP_SECONDARY].va_flags & V_ADP_COLOR,
+ adapter[V_ADP_SECONDARY].va_initial_bios_mode);
+ } else {
+ adapter[V_ADP_SECONDARY].va_type = -1;
+ }
+ if (verify_adapter(&adapter[V_ADP_PRIMARY]) == 0) {
+ ++adapters;
+ adapter[V_ADP_PRIMARY].va_initial_bios_mode =
+ *(u_int8_t *)BIOS_PADDRTOVADDR(0x449);
+ adapter[V_ADP_PRIMARY].va_mode =
+ adapter[V_ADP_PRIMARY].va_initial_mode =
+ map_bios_mode_num(adapter[V_ADP_PRIMARY].va_type,
+ adapter[V_ADP_PRIMARY].va_flags & V_ADP_COLOR,
+ adapter[V_ADP_PRIMARY].va_initial_bios_mode);
+ } else {
+ adapter[V_ADP_PRIMARY] = adapter[V_ADP_SECONDARY];
+ adapter[V_ADP_SECONDARY].va_type = -1;
+ }
+ if (adapters == 0)
+ return adapters;
+ adapter[V_ADP_PRIMARY].va_index = V_ADP_PRIMARY;
+ adapter[V_ADP_SECONDARY].va_index = V_ADP_SECONDARY;
+
+#if 0
+ /*
+ * We cannot have two video adapter of the same type; there must be
+ * only one of color or mono adapter, or one each of them.
+ */
+ if (adapters > 1) {
+ if (!((adapter[0].va_flags ^ adapter[1].va_flags) & V_ADP_COLOR))
+ /* we have two mono or color adapters!! */
+ return (adapters = 0);
+ }
+#endif
+
+ /*
+ * Ensure a zero start address. This is mainly to recover after
+ * switching from pcvt using userconfig(). The registers are w/o
+ * for old hardware so it's too hard to relocate the active screen
+ * memory.
+ * This must be done before vid_save_state() for VGA.
+ */
+ outb(adapter[V_ADP_PRIMARY].va_crtc_addr, 12);
+ outb(adapter[V_ADP_PRIMARY].va_crtc_addr + 1, 0);
+ outb(adapter[V_ADP_PRIMARY].va_crtc_addr, 13);
+ outb(adapter[V_ADP_PRIMARY].va_crtc_addr + 1, 0);
+
+ /* the video mode parameter table in EGA/VGA BIOS */
+ /* NOTE: there can be only one EGA/VGA, wheather color or mono,
+ * recognized by the video BIOS.
+ */
+ if ((adapter[V_ADP_PRIMARY].va_type == KD_EGA) ||
+ (adapter[V_ADP_PRIMARY].va_type == KD_VGA)) {
+ adp = &adapter[V_ADP_PRIMARY];
+ } else if ((adapter[V_ADP_SECONDARY].va_type == KD_EGA) ||
+ (adapter[V_ADP_SECONDARY].va_type == KD_VGA)) {
+ adp = &adapter[V_ADP_SECONDARY];
+ } else {
+ adp = NULL;
+ }
+ bzero(mode_map, sizeof(mode_map));
+ if (adp != NULL) {
+ if (adp->va_type == KD_VGA) {
+ vid_save_state(adp - adapter, &adpstate, sizeof(adpstate));
+ if (video_mode_ptr == NULL) {
+ mode_map[map_mode_num(adp->va_initial_mode)] = adpstate.regs;
+ rows_offset = 1;
+ } else {
+ /* discard the table if we are not familiar with it... */
+ map_mode_table(mode_map, video_mode_ptr, M_VGA_CG320 + 1);
+ mp = get_mode_param(adp->va_initial_mode);
+ if (mp != NULL)
+ bcopy(mp, adpstate2.regs, sizeof(adpstate2.regs));
+ switch (comp_adpregs(adpstate.regs, mp)) {
+ case COMP_IDENTICAL:
+ /*
+ * OK, this parameter table looks reasonably familiar
+ * to us...
+ */
+ /*
+ * This is a kludge for Toshiba DynaBook SS433
+ * whose BIOS video mode table entry has the actual #
+ * of rows at the offset 1; BIOSes from other
+ * manufacturers store the # of rows - 1 there. XXX
+ */
+ rows_offset = adpstate.regs[1] + 1 - mp[1];
+ break;
+
+ case COMP_SIMILAR:
+ /*
+ * Not exactly the same, but similar enough to be
+ * trusted. However, use the saved register values
+ * for the initial mode and other modes which are
+ * based on the initial mode.
+ */
+ mode_map[map_mode_num(adp->va_initial_mode)] =
+ adpstate.regs;
+ rows_offset = adpstate.regs[1] + 1 - mp[1];
+ adpstate.regs[1] -= rows_offset - 1;
+ break;
+
+ case COMP_DIFFERENT:
+ default:
+ /*
+ * Don't use the paramter table in BIOS. It doesn't
+ * look familiar to us. Video mode switching is allowed
+ * only if the new mode is the same as or based on
+ * the initial mode.
+ */
+ video_mode_ptr = NULL;
+ bzero(mode_map, sizeof(mode_map));
+ mode_map[map_mode_num(adp->va_initial_mode)] =
+ adpstate.regs;
+ rows_offset = 1;
+ break;
+ }
+ }
+ adp->va_flags |= V_ADP_MODECHANGE;
+ } else if (adp->va_type == KD_EGA) {
+ if (video_mode_ptr == NULL) {
+ adp->va_flags &= ~V_ADP_FONT;
+ rows_offset = 1;
+ } else {
+ map_mode_table(mode_map, video_mode_ptr, M_ENH_C80x25 + 1);
+ /* XXX how can one validate the EGA table... */
+ mp = get_mode_param(adp->va_initial_mode);
+ if (mp != NULL) {
+ adp->va_flags |= V_ADP_MODECHANGE;
+ rows_offset = 1;
+ } else {
+ /*
+ * This is serious. We will not be able to switch video
+ * modes at all...
+ */
+ adp->va_flags &= ~V_ADP_FONT;
+ video_mode_ptr = NULL;
+ bzero(mode_map, sizeof(mode_map));
+ rows_offset = 1;
+ }
+ }
+ }
+ }
+
+ /* remove conflicting modes if we have more than one adapter */
+ if (adapters > 1) {
+ for (i = 0; i < adapters; ++i) {
+ if (!(adapter[i].va_flags & V_ADP_MODECHANGE))
+ continue;
+ clear_mode_map(i, mode_map, M_VGA_CG320 + 1,
+ (adapter[i].va_flags & V_ADP_COLOR) ?
+ V_INFO_COLOR : 0);
+ }
+ }
+
+ /* buffer address */
+ vid_get_info(V_ADP_PRIMARY,
+ adapter[V_ADP_PRIMARY].va_initial_mode, &info);
+ adapter[V_ADP_PRIMARY].va_window = BIOS_PADDRTOVADDR(info.vi_window);
+ adapter[V_ADP_PRIMARY].va_window_size = info.vi_window_size;
+ adapter[V_ADP_PRIMARY].va_window_gran = info.vi_window_gran;
+ adapter[V_ADP_PRIMARY].va_buffer = BIOS_PADDRTOVADDR(info.vi_buffer);
+ adapter[V_ADP_PRIMARY].va_buffer_size = info.vi_buffer_size;
+ if (adapters > 1) {
+ vid_get_info(V_ADP_SECONDARY,
+ adapter[V_ADP_SECONDARY].va_initial_mode, &info);
+ adapter[V_ADP_SECONDARY].va_window = BIOS_PADDRTOVADDR(info.vi_window);
+ adapter[V_ADP_SECONDARY].va_window_size = info.vi_window_size;
+ adapter[V_ADP_SECONDARY].va_window_gran = info.vi_window_gran;
+ adapter[V_ADP_SECONDARY].va_buffer = BIOS_PADDRTOVADDR(info.vi_buffer);
+ adapter[V_ADP_SECONDARY].va_buffer_size = info.vi_buffer_size;
+ }
+
+ /*
+ * XXX: we should verify the following values for the primary adapter...
+ * crtc I/O port address: *(u_int16_t *)BIOS_PADDRTOVADDR(0x463);
+ * color/mono display: (*(u_int8_t *)BIOS_PADDRTOVADDR(0x487) & 0x02)
+ * ? 0 : V_ADP_COLOR;
+ * columns: *(u_int8_t *)BIOS_PADDRTOVADDR(0x44a);
+ * rows: *(u_int8_t *)BIOS_PADDRTOVADDR(0x484);
+ * font size: *(u_int8_t *)BIOS_PADDRTOVADDR(0x485);
+ * buffer size: *(u_int16_t *)BIOS_PADDRTOVADDR(0x44c);
+ */
+
+ return adapters;
+}
+
+/* all adapters */
+static video_adapter_t
+*vid_adapter(int ad)
+{
+ if (!init_done)
+ return NULL;
+ if ((ad < 0) || (ad >= adapters))
+ return NULL;
+ return &adapter[ad];
+}
+
+/* all adapters */
+static int
+vid_get_info(int ad, int mode, video_info_t *info)
+{
+ int i;
+
+ if (!init_done)
+ return 1;
+ if ((ad < 0) || (ad >= adapters))
+ return 1;
+
+ if (adapter[ad].va_flags & V_ADP_MODECHANGE) {
+ /*
+ * If the parameter table entry for this mode is not found,
+ * the mode is not supported...
+ */
+ if (get_mode_param(mode) == NULL)
+ return 1;
+ } else {
+ /*
+ * Even if we don't support video mode switching on this adapter,
+ * the information on the initial (thus current) video mode
+ * should be made available.
+ */
+ if (mode != adapter[ad].va_initial_mode)
+ return 1;
+ }
+
+ for (i = 0; bios_vmode[i].vi_mode != EOT; ++i) {
+ if (bios_vmode[i].vi_mode == NA)
+ continue;
+ if (mode == bios_vmode[i].vi_mode) {
+ *info = bios_vmode[i];
+ return 0;
+ }
+ }
+ return 1;
+}
+
+/* all adapters */
+static int
+vid_query_mode(int ad, video_info_t *info)
+{
+ video_info_t buf;
+ int i;
+
+ if (!init_done)
+ return -1;
+ if ((ad < 0) || (ad >= adapters))
+ return -1;
+
+ for (i = 0; bios_vmode[i].vi_mode != EOT; ++i) {
+ if (bios_vmode[i].vi_mode == NA)
+ continue;
+
+ if ((info->vi_width != 0)
+ && (info->vi_width != bios_vmode[i].vi_width))
+ continue;
+ if ((info->vi_height != 0)
+ && (info->vi_height != bios_vmode[i].vi_height))
+ continue;
+ if ((info->vi_cwidth != 0)
+ && (info->vi_cwidth != bios_vmode[i].vi_cwidth))
+ continue;
+ if ((info->vi_cheight != 0)
+ && (info->vi_cheight != bios_vmode[i].vi_cheight))
+ continue;
+ if ((info->vi_depth != 0)
+ && (info->vi_depth != bios_vmode[i].vi_depth))
+ continue;
+ if ((info->vi_planes != 0)
+ && (info->vi_planes != bios_vmode[i].vi_planes))
+ continue;
+ /* XXX: should check pixel format, memory model */
+ if ((info->vi_flags != 0)
+ && (info->vi_flags != bios_vmode[i].vi_flags))
+ continue;
+
+ /* verify if this mode is supported on this adapter */
+ if (vid_get_info(ad, bios_vmode[i].vi_mode, &buf))
+ continue;
+ return bios_vmode[i].vi_mode;
+ }
+ return -1;
+}
+
+/* EGA/VGA */
+static int
+vid_set_mode(int ad, int mode)
+{
+ video_info_t info;
+ adp_state_t params;
+
+ prologue(ad, V_ADP_MODECHANGE, 1);
+
+ if (vid_get_info(ad, mode, &info))
+ return 1;
+ params.sig = V_STATE_SIG;
+ bcopy(get_mode_param(mode), params.regs, sizeof(params.regs));
+
+ switch (mode) {
+ case M_VGA_C80x60: case M_VGA_M80x60:
+ params.regs[2] = 0x08;
+ params.regs[19] = 0x47;
+ goto special_480l;
+
+ case M_VGA_C80x30: case M_VGA_M80x30:
+ params.regs[19] = 0x4f;
+special_480l:
+ params.regs[9] |= 0xc0;
+ params.regs[16] = 0x08;
+ params.regs[17] = 0x3e;
+ params.regs[26] = 0xea;
+ params.regs[28] = 0xdf;
+ params.regs[31] = 0xe7;
+ params.regs[32] = 0x04;
+ goto setup_mode;
+
+ case M_ENH_C80x43: case M_ENH_B80x43:
+ params.regs[28] = 87;
+ goto special_80x50;
+
+ case M_VGA_C80x50: case M_VGA_M80x50:
+special_80x50:
+ params.regs[2] = 8;
+ params.regs[19] = 7;
+ goto setup_mode;
+
+ case M_VGA_C40x25: case M_VGA_C80x25:
+ case M_VGA_M80x25:
+ case M_B40x25: case M_C40x25:
+ case M_B80x25: case M_C80x25:
+ case M_ENH_B40x25: case M_ENH_C40x25:
+ case M_ENH_B80x25: case M_ENH_C80x25:
+ case M_EGAMONO80x25:
+
+setup_mode:
+ vid_load_state(ad, &params);
+ break;
+
+ case M_VGA_MODEX:
+ /* "unchain" the VGA mode */
+ params.regs[5-1+0x04] &= 0xf7;
+ params.regs[5-1+0x04] |= 0x04;
+ /* turn off doubleword mode */
+ params.regs[10+0x14] &= 0xbf;
+ /* turn off word adressing */
+ params.regs[10+0x17] |= 0x40;
+ /* set logical screen width */
+ params.regs[10+0x13] = 80;
+ /* set 240 lines */
+ params.regs[10+0x11] = 0x2c;
+ params.regs[10+0x06] = 0x0d;
+ params.regs[10+0x07] = 0x3e;
+ params.regs[10+0x10] = 0xea;
+ params.regs[10+0x11] = 0xac;
+ params.regs[10+0x12] = 0xdf;
+ params.regs[10+0x15] = 0xe7;
+ params.regs[10+0x16] = 0x06;
+ /* set vertical sync polarity to reflect aspect ratio */
+ params.regs[9] = 0xe3;
+ goto setup_grmode;
+
+ case M_BG320: case M_CG320: case M_BG640:
+ case M_CG320_D: case M_CG640_E:
+ case M_CG640x350: case M_ENH_CG640:
+ case M_BG640x480: case M_CG640x480: case M_VGA_CG320:
+
+setup_grmode:
+ vid_load_state(ad, &params);
+ break;
+
+ default:
+ return 1;
+ }
+
+ adapter[ad].va_mode = mode;
+ adapter[ad].va_flags &= ~V_ADP_COLOR;
+ adapter[ad].va_flags |=
+ (info.vi_flags & V_INFO_COLOR) ? V_ADP_COLOR : 0;
+ adapter[ad].va_crtc_addr =
+ (adapter[ad].va_flags & V_ADP_COLOR) ? COLOR_BASE : MONO_BASE;
+ adapter[ad].va_window = BIOS_PADDRTOVADDR(info.vi_window);
+ adapter[ad].va_window_size = info.vi_window_size;
+ adapter[ad].va_window_gran = info.vi_window_gran;
+ if (info.vi_buffer_size == 0) {
+ adapter[ad].va_buffer = 0;
+ adapter[ad].va_buffer_size = 0;
+ } else {
+ adapter[ad].va_buffer = BIOS_PADDRTOVADDR(info.vi_buffer);
+ adapter[ad].va_buffer_size = info.vi_buffer_size;
+ }
+
+ return 0;
+}
+
+static void
+set_font_mode(video_adapter_t *adp, u_char *buf)
+{
+ u_char *mp;
+ int s;
+
+ s = splhigh();
+
+ /* save register values */
+ if (adp->va_type == KD_VGA) {
+ outb(TSIDX, 0x02); buf[0] = inb(TSREG);
+ outb(TSIDX, 0x04); buf[1] = inb(TSREG);
+ outb(GDCIDX, 0x04); buf[2] = inb(GDCREG);
+ outb(GDCIDX, 0x05); buf[3] = inb(GDCREG);
+ outb(GDCIDX, 0x06); buf[4] = inb(GDCREG);
+ inb(adp->va_crtc_addr + 6);
+ outb(ATC, 0x10); buf[5] = inb(ATC + 1);
+ } else /* if (adp->va_type == KD_EGA) */ {
+ /*
+ * EGA cannot be read; copy parameters from the mode parameter
+ * table.
+ */
+ mp = get_mode_param(adp->va_mode);
+ buf[0] = mp[5 + 0x02 - 1];
+ buf[1] = mp[5 + 0x04 - 1];
+ buf[2] = mp[55 + 0x04];
+ buf[3] = mp[55 + 0x05];
+ buf[4] = mp[55 + 0x06];
+ buf[5] = mp[35 + 0x10];
+ }
+
+ /* setup vga for loading fonts */
+ inb(adp->va_crtc_addr + 6); /* reset flip-flop */
+ outb(ATC, 0x10); outb(ATC, buf[5] & ~0x01);
+ inb(adp->va_crtc_addr + 6); /* reset flip-flop */
+ outb(ATC, 0x20); /* enable palette */
+
+#if SLOW_VGA
+#ifndef SC_BAD_FLICKER
+ outb(TSIDX, 0x00); outb(TSREG, 0x01);
+#endif
+ outb(TSIDX, 0x02); outb(TSREG, 0x04);
+ outb(TSIDX, 0x04); outb(TSREG, 0x07);
+#ifndef SC_BAD_FLICKER
+ outb(TSIDX, 0x00); outb(TSREG, 0x03);
+#endif
+ outb(GDCIDX, 0x04); outb(GDCREG, 0x02);
+ outb(GDCIDX, 0x05); outb(GDCREG, 0x00);
+ outb(GDCIDX, 0x06); outb(GDCREG, 0x04);
+#else
+#ifndef SC_BAD_FLICKER
+ outw(TSIDX, 0x0100);
+#endif
+ outw(TSIDX, 0x0402);
+ outw(TSIDX, 0x0704);
+#ifndef SC_BAD_FLICKER
+ outw(TSIDX, 0x0300);
+#endif
+ outw(GDCIDX, 0x0204);
+ outw(GDCIDX, 0x0005);
+ outw(GDCIDX, 0x0406); /* addr = a0000, 64kb */
+#endif
+
+ splx(s);
+}
+
+static void
+set_normal_mode(video_adapter_t *adp, u_char *buf)
+{
+ int s;
+
+ s = splhigh();
+
+ /* setup vga for normal operation mode again */
+ inb(adp->va_crtc_addr + 6); /* reset flip-flop */
+ outb(ATC, 0x10); outb(ATC, buf[5]);
+ inb(adp->va_crtc_addr + 6); /* reset flip-flop */
+ outb(ATC, 0x20); /* enable palette */
+
+#if SLOW_VGA
+#ifndef SC_BAD_FLICKER
+ outb(TSIDX, 0x00); outb(TSREG, 0x01);
+#endif
+ outb(TSIDX, 0x02); outb(TSREG, buf[0]);
+ outb(TSIDX, 0x04); outb(TSREG, buf[1]);
+#ifndef SC_BAD_FLICKER
+ outb(TSIDX, 0x00); outb(TSREG, 0x03);
+#endif
+ outb(GDCIDX, 0x04); outb(GDCREG, buf[2]);
+ outb(GDCIDX, 0x05); outb(GDCREG, buf[3]);
+ if (adp->va_crtc_addr == MONO_BASE) {
+ outb(GDCIDX, 0x06); outb(GDCREG,(buf[4] & 0x03) | 0x08);
+ } else {
+ outb(GDCIDX, 0x06); outb(GDCREG,(buf[4] & 0x03) | 0x0c);
+ }
+#else
+#ifndef SC_BAD_FLICKER
+ outw(TSIDX, 0x0100);
+#endif
+ outw(TSIDX, 0x0002 | (buf[0] << 8));
+ outw(TSIDX, 0x0004 | (buf[1] << 8));
+#ifndef SC_BAD_FLICKER
+ outw(TSIDX, 0x0300);
+#endif
+ outw(GDCIDX, 0x0004 | (buf[2] << 8));
+ outw(GDCIDX, 0x0005 | (buf[3] << 8));
+ if (adp->va_crtc_addr == MONO_BASE)
+ outw(GDCIDX, 0x0006 | (((buf[4] & 0x03) | 0x08)<<8));
+ else
+ outw(GDCIDX, 0x0006 | (((buf[4] & 0x03) | 0x0c)<<8));
+#endif
+
+ splx(s);
+}
+
+/* EGA/VGA */
+static int
+vid_save_font(int ad, int page, int fontsize, u_char *data, int ch, int count)
+{
+ u_char buf[PARAM_BUFSIZE];
+ u_char val = 0;
+ u_int32_t segment;
+ int c;
+ int s;
+
+ prologue(ad, V_ADP_FONT, 1);
+
+ if (fontsize < 14) {
+ /* FONT_8 */
+ fontsize = 8;
+ } else if (fontsize >= 32) {
+ fontsize = 32;
+ } else if (fontsize >= 16) {
+ /* FONT_16 */
+ fontsize = 16;
+ } else {
+ /* FONT_14 */
+ fontsize = 14;
+ }
+
+ if (page < 0 || page >= 8)
+ return 1;
+ segment = VIDEOMEM + 0x4000*page;
+ if (page > 3)
+ segment -= 0xe000;
+
+ if (adapter[ad].va_type == KD_VGA) { /* what about EGA? XXX */
+ s = splhigh();
+ outb(TSIDX, 0x00); outb(TSREG, 0x01);
+ outb(TSIDX, 0x01); val = inb(TSREG); /* disable screen */
+ outb(TSIDX, 0x01); outb(TSREG, val | 0x20);
+ outb(TSIDX, 0x00); outb(TSREG, 0x03);
+ splx(s);
+ }
+
+ set_font_mode(&adapter[ad], buf);
+ if (fontsize == 32) {
+ generic_bcopy((void *)BIOS_PADDRTOVADDR(segment + ch*32), data,
+ fontsize*count);
+ } else {
+ for (c = ch; count > 0; ++c, --count) {
+ generic_bcopy((void *)BIOS_PADDRTOVADDR(segment + c*32), data,
+ fontsize);
+ data += fontsize;
+ }
+ }
+ set_normal_mode(&adapter[ad], buf);
+
+ if (adapter[ad].va_type == KD_VGA) {
+ s = splhigh();
+ outb(TSIDX, 0x00); outb(TSREG, 0x01);
+ outb(TSIDX, 0x01); outb(TSREG, val & 0xdf); /* enable screen */
+ outb(TSIDX, 0x00); outb(TSREG, 0x03);
+ splx(s);
+ }
+
+ return 0;
+}
+
+/* EGA/VGA */
+static int
+vid_load_font(int ad, int page, int fontsize, u_char *data, int ch, int count)
+{
+ u_char buf[PARAM_BUFSIZE];
+ u_char val = 0;
+ u_int32_t segment;
+ int c;
+ int s;
+
+ prologue(ad, V_ADP_FONT, 1);
+
+ if (fontsize < 14) {
+ /* FONT_8 */
+ fontsize = 8;
+ } else if (fontsize >= 32) {
+ fontsize = 32;
+ } else if (fontsize >= 16) {
+ /* FONT_16 */
+ fontsize = 16;
+ } else {
+ /* FONT_14 */
+ fontsize = 14;
+ }
+
+ if (page < 0 || page >= 8)
+ return 1;
+ segment = VIDEOMEM + 0x4000*page;
+ if (page > 3)
+ segment -= 0xe000;
+
+ if (adapter[ad].va_type == KD_VGA) { /* what about EGA? XXX */
+ s = splhigh();
+ outb(TSIDX, 0x00); outb(TSREG, 0x01);
+ outb(TSIDX, 0x01); val = inb(TSREG); /* disable screen */
+ outb(TSIDX, 0x01); outb(TSREG, val | 0x20);
+ outb(TSIDX, 0x00); outb(TSREG, 0x03);
+ splx(s);
+ }
+
+ set_font_mode(&adapter[ad], buf);
+ if (fontsize == 32) {
+ generic_bcopy(data, (void *)BIOS_PADDRTOVADDR(segment + ch*32),
+ fontsize*count);
+ } else {
+ for (c = ch; count > 0; ++c, --count) {
+ generic_bcopy(data, (void *)BIOS_PADDRTOVADDR(segment + c*32),
+ fontsize);
+ data += fontsize;
+ }
+ }
+ set_normal_mode(&adapter[ad], buf);
+
+ if (adapter[ad].va_type == KD_VGA) {
+ s = splhigh();
+ outb(TSIDX, 0x00); outb(TSREG, 0x01);
+ outb(TSIDX, 0x01); outb(TSREG, val & 0xdf); /* enable screen */
+ outb(TSIDX, 0x00); outb(TSREG, 0x03);
+ splx(s);
+ }
+
+ return 0;
+}
+
+/* EGA/VGA */
+static int
+vid_show_font(int ad, int page)
+{
+ static u_char cg[] = { 0x00, 0x05, 0x0a, 0x0f, 0x30, 0x35, 0x3a, 0x3f };
+ int s;
+
+ prologue(ad, V_ADP_FONT, 1);
+ if (page < 0 || page >= 8)
+ return 1;
+
+ s = splhigh();
+ outb(TSIDX, 0x03); outb(TSREG, cg[page]);
+ splx(s);
+
+ return 0;
+}
+
+/* VGA */
+static int
+vid_save_palette(int ad, u_char *palette)
+{
+ int i;
+
+ prologue(ad, V_ADP_PALETTE, 1);
+
+ /*
+ * We store 8 bit values in the palette buffer, while the standard
+ * VGA has 6 bit DAC .
+ */
+ outb(PALRADR, 0x00);
+ for (i = 0; i < 256*3; ++i)
+ palette[i] = inb(PALDATA) << 2;
+ inb(adapter[ad].va_crtc_addr + 6); /* reset flip/flop */
+ return 0;
+}
+
+/* VGA */
+static int
+vid_load_palette(int ad, u_char *palette)
+{
+ int i;
+
+ prologue(ad, V_ADP_PALETTE, 1);
+
+ outb(PIXMASK, 0xff); /* no pixelmask */
+ outb(PALWADR, 0x00);
+ for (i = 0; i < 256*3; ++i)
+ outb(PALDATA, palette[i] >> 2);
+ inb(adapter[ad].va_crtc_addr + 6); /* reset flip/flop */
+ outb(ATC, 0x20); /* enable palette */
+ return 0;
+}
+
+/* CGA/EGA/VGA */
+static int
+vid_set_border(int ad, int color)
+{
+ prologue(ad, V_ADP_BORDER, 1);
+
+ switch (adapter[ad].va_type) {
+ case KD_EGA:
+ case KD_VGA:
+ inb(adapter[ad].va_crtc_addr + 6); /* reset flip-flop */
+ outb(ATC, 0x31); outb(ATC, color & 0xff);
+ break;
+ case KD_CGA:
+ outb(adapter[ad].va_crtc_addr + 5, color & 0x0f); /* color select register */
+ break;
+ case KD_MONO:
+ case KD_HERCULES:
+ default:
+ break;
+ }
+ return 0;
+}
+
+/* VGA */
+static int
+vid_save_state(int ad, void *p, size_t size)
+{
+ video_info_t info;
+ u_char *buf;
+ int crtc_addr;
+ int i, j;
+ int s;
+
+ if (size == 0) {
+ /* return the required buffer size */
+ prologue(ad, V_ADP_STATESAVE, 0);
+ return sizeof(adp_state_t);
+ } else {
+ prologue(ad, V_ADP_STATESAVE, 1);
+ if (size < sizeof(adp_state_t))
+ return 1;
+ }
+
+ ((adp_state_t *)p)->sig = V_STATE_SIG;
+ buf = ((adp_state_t *)p)->regs;
+ bzero(buf, V_MODE_PARAM_SIZE);
+ crtc_addr = adapter[ad].va_crtc_addr;
+
+ s = splhigh();
+
+ outb(TSIDX, 0x00); outb(TSREG, 0x01); /* stop sequencer */
+ for (i = 0, j = 5; i < 4; i++) {
+ outb(TSIDX, i + 1);
+ buf[j++] = inb(TSREG);
+ }
+ buf[9] = inb(MISC + 10); /* dot-clock */
+ outb(TSIDX, 0x00); outb(TSREG, 0x03); /* start sequencer */
+
+ for (i = 0, j = 10; i < 25; i++) { /* crtc */
+ outb(crtc_addr, i);
+ buf[j++] = inb(crtc_addr + 1);
+ }
+ for (i = 0, j = 35; i < 20; i++) { /* attribute ctrl */
+ inb(crtc_addr + 6); /* reset flip-flop */
+ outb(ATC, i);
+ buf[j++] = inb(ATC + 1);
+ }
+ for (i = 0, j = 55; i < 9; i++) { /* graph data ctrl */
+ outb(GDCIDX, i);
+ buf[j++] = inb(GDCREG);
+ }
+ inb(crtc_addr + 6); /* reset flip-flop */
+ outb(ATC, 0x20); /* enable palette */
+
+ splx(s);
+
+#if 1
+ if (vid_get_info(ad, adapter[ad].va_mode, &info) == 0) {
+ if (info.vi_flags & V_INFO_GRAPHICS) {
+ buf[0] = info.vi_width/info.vi_cwidth; /* COLS */
+ buf[1] = info.vi_height/info.vi_cheight - 1; /* ROWS */
+ } else {
+ buf[0] = info.vi_width; /* COLS */
+ buf[1] = info.vi_height - 1; /* ROWS */
+ }
+ buf[2] = info.vi_cheight; /* POINTS */
+ } else {
+ /* XXX: shouldn't be happening... */
+ printf("video#%d: failed to obtain mode info. (vid_save_state())\n",
+ ad);
+ }
+#else
+ buf[0] = *(u_int8_t *)BIOS_PADDRTOVADDR(0x44a); /* COLS */
+ buf[1] = *(u_int8_t *)BIOS_PADDRTOVADDR(0x484); /* ROWS */
+ buf[2] = *(u_int8_t *)BIOS_PADDRTOVADDR(0x485); /* POINTS */
+ buf[3] = *(u_int8_t *)BIOS_PADDRTOVADDR(0x44c);
+ buf[4] = *(u_int8_t *)BIOS_PADDRTOVADDR(0x44d);
+#endif
+
+ return 0;
+}
+
+/* EGA/VGA */
+static int
+vid_load_state(int ad, void *p)
+{
+ u_char *buf;
+ int crtc_addr;
+ int s;
+ int i;
+
+ prologue(ad, V_ADP_STATELOAD, 1);
+ if (((adp_state_t *)p)->sig != V_STATE_SIG)
+ return 1;
+
+ buf = ((adp_state_t *)p)->regs;
+ crtc_addr = adapter[ad].va_crtc_addr;
+
+ s = splhigh();
+
+ outb(TSIDX, 0x00); outb(TSREG, 0x01); /* stop sequencer */
+ for (i = 0; i < 4; ++i) { /* program sequencer */
+ outb(TSIDX, i + 1);
+ outb(TSREG, buf[i + 5]);
+ }
+ outb(MISC, buf[9]); /* set dot-clock */
+ outb(TSIDX, 0x00); outb(TSREG, 0x03); /* start sequencer */
+ outb(crtc_addr, 0x11);
+ outb(crtc_addr + 1, inb(crtc_addr + 1) & 0x7F);
+ for (i = 0; i < 25; ++i) { /* program crtc */
+ outb(crtc_addr, i);
+ outb(crtc_addr + 1, buf[i + 10]);
+ }
+ inb(crtc_addr+6); /* reset flip-flop */
+ for (i = 0; i < 20; ++i) { /* program attribute ctrl */
+ outb(ATC, i);
+ outb(ATC, buf[i + 35]);
+ }
+ for (i = 0; i < 9; ++i) { /* program graph data ctrl */
+ outb(GDCIDX, i);
+ outb(GDCREG, buf[i + 55]);
+ }
+ inb(crtc_addr + 6); /* reset flip-flop */
+ outb(ATC, 0x20); /* enable palette */
+
+ if (ad == V_ADP_PRIMARY) {
+ *(u_int8_t *)BIOS_PADDRTOVADDR(0x44a) = buf[0]; /* COLS */
+ *(u_int8_t *)BIOS_PADDRTOVADDR(0x484) = buf[1] + rows_offset - 1; /* ROWS */
+ *(u_int8_t *)BIOS_PADDRTOVADDR(0x485) = buf[2]; /* POINTS */
+#if 0
+ *(u_int8_t *)BIOS_PADDRTOVADDR(0x44c) = buf[3];
+ *(u_int8_t *)BIOS_PADDRTOVADDR(0x44d) = buf[4];
+#endif
+ }
+
+ splx(s);
+ return 0;
+}
+
+/* all */
+static int
+vid_set_origin(int ad, off_t offset)
+{
+ /*
+ * The standard video modes do not require window mapping;
+ * always return error.
+ */
+ return 1;
+}
+
+/* all */
+static int
+vid_read_hw_cursor(int ad, int *col, int *row)
+{
+ video_info_t info;
+ u_int16_t off;
+
+ if (!init_done)
+ return 1;
+ if ((ad < 0) || (ad >= adapters))
+ return 1;
+
+ (*biosvidsw.get_info)(ad, adapter[ad].va_mode, &info);
+ if (info.vi_flags & V_INFO_GRAPHICS)
+ return 1;
+
+ outb(adapter[ad].va_crtc_addr, 14);
+ off = inb(adapter[ad].va_crtc_addr + 1);
+ outb(adapter[ad].va_crtc_addr, 15);
+ off = (off << 8) | inb(adapter[ad].va_crtc_addr + 1);
+
+ *row = off / info.vi_width;
+ *col = off % info.vi_width;
+
+ return 0;
+}
+
+/* all */
+static int
+vid_set_hw_cursor(int ad, int col, int row)
+{
+ video_info_t info;
+ u_int16_t off;
+
+ if (!init_done)
+ return 1;
+ if ((ad < 0) || (ad >= adapters))
+ return 1;
+
+ (*biosvidsw.get_info)(ad, adapter[ad].va_mode, &info);
+ if (info.vi_flags & V_INFO_GRAPHICS)
+ return 1;
+
+ if ((col == -1) || (row == -1))
+ off = 0xffff;
+ else
+ off = row*info.vi_width + col;
+ outb(adapter[ad].va_crtc_addr, 14);
+ outb(adapter[ad].va_crtc_addr + 1, off >> 8);
+ outb(adapter[ad].va_crtc_addr, 15);
+ outb(adapter[ad].va_crtc_addr + 1, off & 0x00ff);
+
+ return 0;
+}
+
+static char
+*adapter_name(int type)
+{
+ static struct {
+ int type;
+ char *name;
+ } names[] = {
+ { KD_MONO, "MDA" },
+ { KD_HERCULES, "Hercules" },
+ { KD_CGA, "CGA" },
+ { KD_EGA, "EGA" },
+ { KD_VGA, "VGA" },
+ { KD_PC98, "PC-98xx" },
+ { -1, "Unknown" },
+ };
+ int i;
+
+ for (i = 0; names[i].type != -1; ++i)
+ if (names[i].type == type)
+ break;
+ return names[i].name;
+}
+
+static void
+dump_adp_info(int ad, video_adapter_t *adp, int level)
+{
+ if (level <= 0)
+ return;
+
+ printf("video#%d: adapter type:%s (%d), flags:0x%x, CRTC:0x%x\n",
+ ad, adapter_name(adp->va_type), adp->va_type,
+ adp->va_flags, adp->va_crtc_addr);
+ printf("video#%d: init mode:%d, bios mode:%d, current mode:%d\n",
+ ad, adp->va_initial_mode, adp->va_initial_bios_mode, adp->va_mode);
+ printf("video#%d: window:0x%x size:%dk gran:%dk, buf:0x%x size:%dk\n",
+ ad,
+ adp->va_window, adp->va_window_size, adp->va_window_gran,
+ adp->va_buffer, adp->va_buffer_size);
+}
+
+static void
+dump_mode_info(int ad, video_info_t *info, int level)
+{
+ if (level <= 0)
+ return;
+
+ printf("video#%d: mode:%d, flags:0x%x ",
+ ad, info->vi_mode, info->vi_flags);
+ if (info->vi_flags & V_INFO_GRAPHICS)
+ printf("G %dx%dx%d, %d plane(s), font:%dx%d, ",
+ info->vi_width, info->vi_height,
+ info->vi_depth, info->vi_planes,
+ info->vi_cwidth, info->vi_cheight);
+ else
+ printf("T %dx%d, font:%dx%d, ",
+ info->vi_width, info->vi_height,
+ info->vi_cwidth, info->vi_cheight);
+ printf("win:0x%x\n", info->vi_window);
+}
+
+static void
+dump_buffer(u_char *buf, size_t len)
+{
+ int i;
+
+ for(i = 0; i < len;) {
+ printf("%02x ", buf[i]);
+ if ((++i % 16) == 0)
+ printf("\n");
+ }
+}
+
+static int
+vid_diag(int level)
+{
+ video_info_t info;
+ u_char *mp;
+ int ad;
+ int i;
+
+ if (!init_done)
+ return 1;
+
+ if (level > 0) {
+ printf("video: RTC equip. code:0x%02x, DCC code:0x%02x\n",
+ rtcin(RTC_EQUIPMENT), *(u_int8_t *)BIOS_PADDRTOVADDR(0x488));
+ printf("video: CRTC:0x%x, video option:0x%02x, ",
+ *(u_int16_t *)BIOS_PADDRTOVADDR(0x463),
+ *(u_int8_t *)BIOS_PADDRTOVADDR(0x487));
+ printf("rows:%d, cols:%d, font height:%d\n",
+ *(u_int8_t *)BIOS_PADDRTOVADDR(0x44a),
+ *(u_int8_t *)BIOS_PADDRTOVADDR(0x484) + 1,
+ *(u_int8_t *)BIOS_PADDRTOVADDR(0x485));
+ printf("video: param table EGA/VGA:%p, CGA/MDA:%p\n",
+ video_mode_ptr, video_mode_ptr2);
+ printf("video: rows_offset:%d\n", rows_offset);
+ }
+
+ for (ad = 0; ad < adapters; ++ad) {
+ dump_adp_info(ad, &adapter[ad], level);
+
+ if (!(adapter[ad].va_flags & V_ADP_MODECHANGE)) {
+ vid_get_info(ad, adapter[ad].va_initial_mode, &info);
+ dump_mode_info(ad, &info, level);
+ } else {
+ for (i = 0; bios_vmode[i].vi_mode != EOT; ++i) {
+ if (bios_vmode[i].vi_mode == NA)
+ continue;
+ if (get_mode_param(bios_vmode[i].vi_mode) == NULL)
+ continue;
+ dump_mode_info(ad, &bios_vmode[i], level);
+ }
+ }
+ if ((adapter[ad].va_type != KD_EGA) && (adapter[ad].va_type != KD_VGA))
+ continue;
+
+ if (video_mode_ptr == NULL)
+ printf("video#%d: WARNING: video mode switching is not fully supported on this adapter\n", ad);
+
+ if (level <= 0)
+ continue;
+
+ if (adapter[ad].va_type == KD_VGA) {
+ printf("VGA parameters upon power-up\n");
+ dump_buffer(adpstate.regs, sizeof(adpstate.regs));
+ printf("VGA parameters in BIOS for mode %d\n",
+ adapter[ad].va_initial_mode);
+ dump_buffer(adpstate2.regs, sizeof(adpstate2.regs));
+ }
+
+ mp = get_mode_param(adapter[ad].va_initial_mode);
+ if (mp == NULL) /* this shouldn't be happening */
+ continue;
+ printf("EGA/VGA parameters to be used for mode %d\n",
+ adapter[ad].va_initial_mode);
+ dump_buffer(mp, V_MODE_PARAM_SIZE);
+ }
+
+ return 0;
+}
+
+#endif /* NSC > 0 */
diff --git a/sys/i386/isa/videoio.h b/sys/i386/isa/videoio.h
new file mode 100644
index 0000000..74d17d0
--- /dev/null
+++ b/sys/i386/isa/videoio.h
@@ -0,0 +1,107 @@
+/*-
+ * Copyright (c) 1998 Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp)
+ * 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. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#ifndef _I386_ISA_VIDEOIO_H_
+#define _I386_ISA_VIDEOIO_H_
+
+#ifdef KERNEL
+
+#define V_MAX_ADAPTERS 2
+
+#define V_MODE_MAP_SIZE (M_VGA_CG320 + 1)
+#define V_MODE_PARAM_SIZE 64
+
+/* physical addresses */
+#define MONO_BUF BIOS_PADDRTOVADDR(0xb0000)
+#define CGA_BUF BIOS_PADDRTOVADDR(0xb8000)
+#define GRAPHICS_BUF BIOS_PADDRTOVADDR(0xa0000)
+#define VIDEOMEM 0x000A0000
+
+/* I/O port addresses */
+#define MONO_BASE 0x3B4 /* crt controller base mono */
+#define COLOR_BASE 0x3D4 /* crt controller base color */
+#define MISC 0x3C2 /* misc output register */
+#define ATC IO_VGA+0x00 /* attribute controller */
+#define TSIDX IO_VGA+0x04 /* timing sequencer idx */
+#define TSREG IO_VGA+0x05 /* timing sequencer data */
+#define PIXMASK IO_VGA+0x06 /* pixel write mask */
+#define PALRADR IO_VGA+0x07 /* palette read address */
+#define PALWADR IO_VGA+0x08 /* palette write address */
+#define PALDATA IO_VGA+0x09 /* palette data register */
+#define GDCIDX IO_VGA+0x0E /* graph data controller idx */
+#define GDCREG IO_VGA+0x0F /* graph data controller data */
+
+/* video function table */
+typedef int vi_init_t(void);
+typedef video_adapter_t *vi_adapter_t(int ad);
+typedef int vi_get_info_t(int ad, int mode, video_info_t *info);
+typedef int vi_query_mode_t(int ad, video_info_t *info);
+typedef int vi_set_mode_t(int ad, int mode);
+typedef int vi_save_font_t(int ad, int page, int size, u_char *data,
+ int c, int count);
+typedef int vi_load_font_t(int ad, int page, int size, u_char *data,
+ int c, int count);
+typedef int vi_show_font_t(int ad, int page);
+typedef int vi_save_palette_t(int ad, u_char *palette);
+typedef int vi_load_palette_t(int ad, u_char *palette);
+typedef int vi_set_border_t(int ad, int border);
+typedef int vi_save_state_t(int ad, void *p, size_t size);
+typedef int vi_load_state_t(int ad, void *p);
+typedef int vi_set_win_org_t(int ad, off_t offset);
+typedef int vi_read_hw_cursor_t(int ad, int *col, int *row);
+typedef int vi_set_hw_cursor_t(int ad, int col, int row);
+typedef int vi_diag_t(int level);
+
+struct vidsw {
+ vi_init_t *init; /* all */
+ vi_adapter_t *adapter; /* all */
+ vi_get_info_t *get_info; /* all */
+ vi_query_mode_t *query_mode; /* all */
+ vi_set_mode_t *set_mode; /* EGA/VGA */
+ vi_save_font_t *save_font; /* EGA/VGA */
+ vi_load_font_t *load_font; /* EGA/VGA */
+ vi_show_font_t *show_font; /* EGA/VGA */
+ vi_save_palette_t *save_palette; /* VGA */
+ vi_load_palette_t *load_palette; /* VGA */
+ vi_set_border_t *set_border; /* CGA/EGA/VGA */
+ vi_save_state_t *save_state; /* VGA */
+ vi_load_state_t *load_state; /* EGA/VGA */
+ vi_set_win_org_t *set_win_org; /* all */
+ vi_read_hw_cursor_t *read_hw_cursor; /* all */
+ vi_set_hw_cursor_t *set_hw_cursor; /* all */
+ vi_diag_t *diag; /* all */
+};
+
+extern struct vidsw biosvidsw;
+
+#endif /* KERNEL */
+
+#endif /* !_I386_ISA_VIDEOIO_H_ */
diff --git a/sys/i386/isa/wst.c b/sys/i386/isa/wst.c
index 390eb2c..ff5f543 100644
--- a/sys/i386/isa/wst.c
+++ b/sys/i386/isa/wst.c
@@ -6,13 +6,13 @@
* 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
- * in this position and unchanged.
+ * notice, this list of conditions and the following disclaimer,
+ * without modification, immediately at the beginning of the file.
* 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. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission
+ * derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: wst.c,v 1.10 1998/08/24 02:28:16 bde Exp $
+ * $Id$
*/
#include "wdc.h"
diff --git a/sys/modules/syscons/blank/blank_saver.c b/sys/modules/syscons/blank/blank_saver.c
index 451dc9a..d5f4cf0 100644
--- a/sys/modules/syscons/blank/blank_saver.c
+++ b/sys/modules/syscons/blank/blank_saver.c
@@ -1,18 +1,18 @@
/*-
- * Copyright (c) 1995 Søren Schmidt
+ * Copyright (c) 1995-1998 Søren Schmidt
* 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
- * in this position and unchanged.
+ * notice, this list of conditions and the following disclaimer,
+ * without modification, immediately at the beginning of the file.
* 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. The name of the author may not be used to endorse or promote products
- * derived from this software withough specific prior written permission
+ * derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: blank_saver.c,v 1.10 1997/07/15 14:49:09 yokota Exp $
+ * $Id$
*/
#include <sys/param.h>
diff --git a/sys/modules/syscons/daemon/daemon_saver.c b/sys/modules/syscons/daemon/daemon_saver.c
index f3cf3dc..688df41 100644
--- a/sys/modules/syscons/daemon/daemon_saver.c
+++ b/sys/modules/syscons/daemon/daemon_saver.c
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: daemon_saver.c,v 1.8 1998/01/16 17:58:43 bde Exp $
+ * $Id: daemon_saver.c,v 1.9 1998/08/06 09:14:20 yokota Exp $
*/
#include <sys/param.h>
@@ -205,7 +205,7 @@ daemon_saver(int blank)
/* clear the screen and set the border color */
fillw(((FG_LIGHTGREY|BG_BLACK) << 8) | scr_map[0x20],
Crtat, scp->xsize * scp->ysize);
- set_border(0);
+ set_border(scp, 0);
xlen = ylen = tlen = 0;
}
if (scrn_blanked++ < 2)
@@ -322,7 +322,7 @@ daemon_saver(int blank)
draw_string(txpos, typos, toff, (char *)message, tlen);
} else {
if (scrn_blanked > 0) {
- set_border(scp->border);
+ set_border(scp, scp->border);
scrn_blanked = 0;
}
}
diff --git a/sys/modules/syscons/fade/fade_saver.c b/sys/modules/syscons/fade/fade_saver.c
index 341f7e8..41176e7 100644
--- a/sys/modules/syscons/fade/fade_saver.c
+++ b/sys/modules/syscons/fade/fade_saver.c
@@ -1,18 +1,18 @@
/*-
- * Copyright (c) 1995-1997 Søren Schmidt
+ * Copyright (c) 1995-1998 Søren Schmidt
* 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
- * in this position and unchanged.
+ * notice, this list of conditions and the following disclaimer,
+ * without modification, immediately at the beginning of the file.
* 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. The name of the author may not be used to endorse or promote products
- * derived from this software withough specific prior written permission
+ * derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: fade_saver.c,v 1.11 1997/07/15 14:49:25 yokota Exp $
+ * $Id$
*/
#include <sys/param.h>
@@ -84,7 +84,7 @@ fade_saver(int blank)
else {
switch (crtc_type) {
case KD_VGA:
- load_palette(palette);
+ load_palette(cur_console, palette);
count = 0;
break;
case KD_EGA:
diff --git a/sys/modules/syscons/green/green_saver.c b/sys/modules/syscons/green/green_saver.c
index b8c8295..6678662 100644
--- a/sys/modules/syscons/green/green_saver.c
+++ b/sys/modules/syscons/green/green_saver.c
@@ -1,18 +1,18 @@
/*-
- * Copyright (c) 1995 Søren Schmidt
+ * Copyright (c) 1995-1998 Søren Schmidt
* 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
- * in this position and unchanged.
+ * notice, this list of conditions and the following disclaimer,
+ * without modification, immediately at the beginning of the file.
* 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. The name of the author may not be used to endorse or promote products
- * derived from this software withough specific prior written permission
+ * derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: green_saver.c,v 1.10 1997/07/15 14:49:29 yokota Exp $
+ * $Id$
*/
#include <sys/param.h>
diff --git a/sys/modules/syscons/saver.h b/sys/modules/syscons/saver.h
index 7118e45..96cc010 100644
--- a/sys/modules/syscons/saver.h
+++ b/sys/modules/syscons/saver.h
@@ -1,18 +1,18 @@
/*-
- * Copyright (c) 1995-1997 Søren Schmidt
+ * Copyright (c) 1995-1998 Søren Schmidt
* 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
- * in this position and unchanged.
+ * notice, this list of conditions and the following disclaimer,
+ * without modification, immediately at the beginning of the file.
* 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. The name of the author may not be used to endorse or promote products
- * derived from this software withough specific prior written permission
+ * derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@@ -25,12 +25,12 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: saver.h,v 1.9 1997/07/15 14:48:11 yokota Exp $
+ * $Id$
*/
-
#include <machine/apm_bios.h>
#include <machine/console.h>
+#include <i386/isa/videoio.h>
#include <i386/isa/syscons.h>
extern scr_stat *cur_console;
diff --git a/sys/modules/syscons/snake/snake_saver.c b/sys/modules/syscons/snake/snake_saver.c
index c3fa1fe..c5011d0 100644
--- a/sys/modules/syscons/snake/snake_saver.c
+++ b/sys/modules/syscons/snake/snake_saver.c
@@ -1,18 +1,18 @@
/*-
- * Copyright (c) 1995 Søren Schmidt
+ * Copyright (c) 1995-1998 Søren Schmidt
* 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
- * in this position and unchanged.
+ * notice, this list of conditions and the following disclaimer,
+ * without modification, immediately at the beginning of the file.
* 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. The name of the author may not be used to endorse or promote products
- * derived from this software withough specific prior written permission
+ * derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: snake_saver.c,v 1.16 1998/01/16 17:58:50 bde Exp $
+ * $Id$
*/
#include <sys/param.h>
@@ -63,7 +63,7 @@ snake_saver(int blank)
if (scrn_blanked <= 0) {
fillw((FG_LIGHTGREY|BG_BLACK)<<8 | scr_map[0x20],
Crtat, scp->xsize * scp->ysize);
- set_border(0);
+ set_border(scp, 0);
dirx = (scp->xpos ? 1 : -1);
diry = (scp->ypos ?
scp->xsize : -scp->xsize);
@@ -99,7 +99,7 @@ snake_saver(int blank)
}
else {
if (scrn_blanked > 0) {
- set_border(scp->border);
+ set_border(scp, scp->border);
scrn_blanked = 0;
}
}
diff --git a/sys/modules/syscons/star/star_saver.c b/sys/modules/syscons/star/star_saver.c
index 517a557..8ac65bd 100644
--- a/sys/modules/syscons/star/star_saver.c
+++ b/sys/modules/syscons/star/star_saver.c
@@ -1,18 +1,18 @@
/*-
- * Copyright (c) 1995 Søren Schmidt
+ * Copyright (c) 1995-1998 Søren Schmidt
* 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
- * in this position and unchanged.
+ * notice, this list of conditions and the following disclaimer,
+ * without modification, immediately at the beginning of the file.
* 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. The name of the author may not be used to endorse or promote products
- * derived from this software withough specific prior written permission
+ * derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: star_saver.c,v 1.13 1998/01/16 17:58:55 bde Exp $
+ * $Id$
*/
#include <sys/param.h>
@@ -62,7 +62,7 @@ star_saver(int blank)
scrn_blanked = 1;
fillw((FG_LIGHTGREY|BG_BLACK)<<8|scr_map[0x20], Crtat,
scp->xsize * scp->ysize);
- set_border(0);
+ set_border(scp, 0);
for(i=0; i<NUM_STARS; i++) {
stars[i][0] =
random() % (scp->xsize*scp->ysize);
@@ -80,7 +80,7 @@ star_saver(int blank)
}
else {
if (scrn_blanked > 0) {
- set_border(scp->border);
+ set_border(scp, scp->border);
scrn_blanked = 0;
}
}
diff --git a/sys/pc98/pc98/wst.c b/sys/pc98/pc98/wst.c
index 390eb2c..ff5f543 100644
--- a/sys/pc98/pc98/wst.c
+++ b/sys/pc98/pc98/wst.c
@@ -6,13 +6,13 @@
* 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
- * in this position and unchanged.
+ * notice, this list of conditions and the following disclaimer,
+ * without modification, immediately at the beginning of the file.
* 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. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission
+ * derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: wst.c,v 1.10 1998/08/24 02:28:16 bde Exp $
+ * $Id$
*/
#include "wdc.h"
OpenPOWER on IntegriCloud