summaryrefslogtreecommitdiffstats
path: root/sys/isa
diff options
context:
space:
mode:
authordfr <dfr@FreeBSD.org>1998-09-17 09:38:36 +0000
committerdfr <dfr@FreeBSD.org>1998-09-17 09:38:36 +0000
commita1160c985757fb579a45c139d8649181ffde94dc (patch)
treeb3226346dfbf2849b25075e16560d6d27ed46ae0 /sys/isa
parent271727741c72633cfbf750b45b4cb8ba1b7a9aae (diff)
downloadFreeBSD-src-a1160c985757fb579a45c139d8649181ffde94dc.zip
FreeBSD-src-a1160c985757fb579a45c139d8649181ffde94dc.tar.gz
Merge with the latest i386 syscons.
Diffstat (limited to 'sys/isa')
-rw-r--r--sys/isa/scvidctl.c489
-rw-r--r--sys/isa/syscons.c1841
-rw-r--r--sys/isa/syscons.h94
-rw-r--r--sys/isa/videoio.c1628
-rw-r--r--sys/isa/videoio.h108
5 files changed, 2795 insertions, 1365 deletions
diff --git a/sys/isa/scvidctl.c b/sys/isa/scvidctl.c
new file mode 100644
index 0000000..5934bdf
--- /dev/null
+++ b/sys/isa/scvidctl.c
@@ -0,0 +1,489 @@
+/*-
+ * 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$
+ * from: i386/isa scvidctl.c,v 1.1
+ */
+
+#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>
+
+#ifdef __i386__
+#include <machine/apm_bios.h>
+#endif
+#include <machine/console.h>
+
+#include <isa/videoio.h>
+#include <isa/syscons.h>
+
+/* video ioctl */
+
+extern scr_stat *cur_console;
+extern u_int32_t 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)
+ memset_io(Crtat, 0, 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)
+ memset_io(Crtat, 0, 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 */
+ memset_io(Crtat, 0, 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/isa/syscons.c b/sys/isa/syscons.c
index 311a63c..6d9f7c9 100644
--- a/sys/isa/syscons.c
+++ b/sys/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,8 +25,8 @@
* (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$
- * from: i386/isa syscons.c,v 1.272
+ * $Id: syscons.c,v 1.273 1998/08/06 09:15:53 dfr Exp $
+ * from: i386/isa syscons.c,v 1.278
*/
#include "sc.h"
@@ -35,6 +35,10 @@
#include "opt_ddb.h"
#include "opt_devfs.h"
+#ifdef __i386__
+#include "opt_vesa.h"
+#include "opt_vm86.h"
+#endif
#include "opt_syscons.h"
#if NSC > 0
@@ -54,7 +58,6 @@
#include <sys/devfsext.h>
#endif
-#include <machine/bootinfo.h>
#include <machine/clock.h>
#include <machine/cons.h>
#include <machine/console.h>
@@ -63,6 +66,7 @@
#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> */
@@ -75,6 +79,7 @@
#include <isa/timerreg.h>
#include <isa/kbdtables.h>
#include <isa/kbdio.h>
+#include <isa/videoio.h>
#include <isa/syscons.h>
#if !defined(MAXCONS)
@@ -101,11 +106,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!? */
@@ -143,7 +143,6 @@ static scr_stat main_console;
static scr_stat *console[MAXCONS];
#ifdef DEVFS
static void *sc_devfs_token[MAXCONS];
-static void *sc_vga_devfs_token;
static void *sc_mouse_devfs_token;
static void *sc_console_devfs_token;
#endif
@@ -165,6 +164,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;
@@ -178,7 +178,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
@@ -186,19 +186,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] = {
@@ -214,13 +210,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;
@@ -239,8 +236,6 @@ static struct tty sccons[MAXCONS+2];
#endif
#define SC_MOUSE 128
#define SC_CONSOLE 255
-#define MONO_BUF 0xB0000
-#define CGA_BUF 0xB8000
u_int32_t Crtat;
static const int nsccons = MAXCONS+2;
@@ -249,9 +244,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(device_t dev);
static int scparam(struct tty *tp, struct termios *t);
@@ -263,30 +255,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);
@@ -294,16 +282,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);
@@ -319,12 +297,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)
@@ -352,14 +329,17 @@ 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
-static struct cdevsw scdevsw = {
+#define CDEV_MAJOR 12
+static struct cdevsw sc_cdevsw = {
scopen, scclose, scread, scwrite,
scioctl, nullstop, noreset, scdevtotty,
- ttpoll, scmmap, nostrategy, "sc", NULL, -1 };
+ ttpoll, scmmap, nostrategy, "sc",
+ NULL, -1, nodump, nopsize,
+ D_TTY,
+};
/*
* These functions need to be before calls to them so they can be inlined.
@@ -391,7 +371,7 @@ draw_cursor_image(scr_stat *scp)
u_int32_t ptr = Crtat + 2*(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;
@@ -443,7 +423,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
@@ -474,6 +454,12 @@ scprobe(device_t dev)
printf("sc%d: no video adapter is found.\n", device_get_unit(dev));
return (0);
}
+ (*biosvidsw.diag)(bootverbose);
+#if defined(VESA) && defined(VM86)
+ if (vesa_load())
+ return FALSE;
+ (*biosvidsw.diag)(bootverbose);
+#endif
sc_port = isa_get_port(dev);
isa_set_portsize(dev, IO_KBDSIZE);
@@ -487,106 +473,24 @@ scprobe(device_t 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_int32_t 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 = MONO_BUF;
- crtc_type = KD_MONO;
- /* If CGA memory seems to work, switch to color. */
- cp = CGA_BUF;
- was = readw(cp);
- writew(cp, 0xA55A);
-#ifdef __i386__
- bios_video_mode = *(u_char *)pa_to_va(0x449);
- if (bootinfo.bi_vesa == 0x102) {
- bios_video_mode = bootinfo.bi_vesa;
- Crtat = 0xA0000;
- crtc_addr = COLOR_BASE;
- crtc_type = KD_VGA;
- memset_io(Crtat, 0, 800*600/8);
- } else
-#endif
- if (readw(cp)) {
- Crtat = CGA_BUF;
- crtc_addr = COLOR_BASE;
- crtc_type = KD_CGA;
- } else {
- cp = Crtat;
- was = readw(cp);
- writew(cp, 0xA55A);
- if (readw(cp) != 0xA55A) {
- /* no screen at all, bail out */
- Crtat = 0;
- return FALSE;
- }
- }
- writew(cp, was);
+ return (crtc_type != -1);
- if (!VESA_MODE(bios_video_mode)) {
-#ifdef __i386__
- /*
- * 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;
- }
-#endif
+ 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);
-
-#ifdef __i386__
- /* Get the BIOS video mode pointer */
- segoff = readl(0x4a8);
- pa = ((segoff & 0xffff0000) >> 12) + (segoff & 0xffff);
- if (ISMAPPED(pa, sizeof(u_int))) {
- segoff = readl(pa);
- pa = ((segoff & 0xffff0000) >> 12) + (segoff & 0xffff);
- if (ISMAPPED(pa, MODE_PARAM_SIZE))
- video_mode_ptr = (char *)pa_to_va(pa);
- }
-#endif
- }
- }
+ crtc_type = adp->va_type;
+ crtc_vga = (crtc_type == KD_VGA);
+ crtc_addr = adp->va_crtc_addr;
+ Crtat = 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;
}
@@ -784,92 +688,57 @@ static int
scattach(device_t dev)
{
scr_stat *scp;
+ video_info_t info;
dev_t cdev = makedev(CDEV_MAJOR, 0);
- char *p;
- void *ih;
#ifdef DEVFS
int vc;
#endif
+ void *ih;
scinit();
flags = isa_get_flags(dev);
- 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 */
- scrn_timer((void*)TRUE);
+ scrn_timer((void *)TRUE);
update_leds(scp->status);
- if ((crtc_type == KD_VGA) && bootverbose) {
- printf("sc%d: BIOS video mode:%d\n", device_get_unit(dev), bios_video_mode);
- printf("sc%d: VGA registers upon power-up\n", device_get_unit(dev));
- dump_vgaregs(vgaregs);
- printf("sc%d: video mode:%d\n", device_get_unit(dev), scp->mode);
- printf("sc%d: VGA registers in BIOS for mode:%d\n",
- device_get_unit(dev), 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",
- device_get_unit(dev), scp->mode);
- dump_vgaregs(p);
- }
- printf("sc%d: rows_offset:%d\n", device_get_unit(dev), 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",
- device_get_unit(dev));
-
printf("sc%d: ", device_get_unit(dev));
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");
@@ -877,7 +746,7 @@ scattach(device_t 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);
@@ -894,12 +763,11 @@ scattach(device_t dev)
#ifdef DEVFS
for (vc = 0; vc < MAXCONS; vc++)
- sc_devfs_token[vc] = devfs_add_devswf(&scdevsw, vc, DV_CHR,
+ sc_devfs_token[vc] = devfs_add_devswf(&sc_cdevsw, vc, DV_CHR,
UID_ROOT, GID_WHEEL, 0600, "ttyv%r", vc);
- sc_vga_devfs_token = devfs_link(sc_devfs_token[0], "vga");
- sc_mouse_devfs_token = devfs_add_devswf(&scdevsw, SC_MOUSE, DV_CHR,
+ sc_mouse_devfs_token = devfs_add_devswf(&sc_cdevsw, SC_MOUSE, DV_CHR,
UID_ROOT, GID_WHEEL, 0600, "sysmouse");
- sc_console_devfs_token = devfs_add_devswf(&scdevsw, SC_CONSOLE, DV_CHR,
+ sc_console_devfs_token = devfs_add_devswf(&sc_cdevsw, SC_CONSOLE, DV_CHR,
UID_ROOT, GID_WHEEL, 0600, "consolectl");
#endif
@@ -911,7 +779,6 @@ scattach(device_t dev)
BUS_CONNECT_INTR(device_get_parent(dev), ih);
-
return 0;
}
@@ -953,7 +820,6 @@ scopen(dev_t dev, int flag, int mode, struct proc *p)
tp->t_lflag = TTYDEF_LFLAG;
tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
scparam(tp, &tp->t_termios);
- ttsetwater(tp);
(*linesw[tp->t_line].l_modem)(tp, 1);
if (minor(dev) == SC_MOUSE)
mouse_level = 0; /* XXX */
@@ -963,6 +829,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;
@@ -980,7 +848,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
@@ -994,9 +862,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;
@@ -1075,10 +943,17 @@ scintr(void *arg)
}
}
+#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
@@ -1097,21 +972,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 */
@@ -1119,18 +998,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) */
@@ -1148,7 +1016,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
@@ -1157,7 +1025,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);
@@ -1184,37 +1052,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
@@ -1238,7 +1091,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) {
@@ -1287,7 +1141,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);
@@ -1298,7 +1152,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;
@@ -1343,7 +1197,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) {
@@ -1388,7 +1242,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);
@@ -1425,7 +1279,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) {
@@ -1454,7 +1308,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) {
@@ -1634,18 +1488,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;
@@ -1664,226 +1541,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;
@@ -1906,7 +1563,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;
@@ -1946,32 +1603,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 */
@@ -1991,102 +1648,28 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
#endif
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;
@@ -2108,7 +1691,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;
@@ -2147,21 +1730,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 */
@@ -2216,7 +1798,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;
@@ -2225,17 +1807,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);
@@ -2245,7 +1822,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;
@@ -2254,17 +1831,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);
@@ -2274,7 +1847,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;
@@ -2283,17 +1856,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);
@@ -2320,7 +1888,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? */
@@ -2424,7 +1992,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);
@@ -2479,25 +2047,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);
@@ -2556,6 +2127,8 @@ scrn_timer(void *arg)
scintr(0);
}
+ scp = cur_console;
+
/* should we stop the screen saver? */
getmicrouptime(&tv);
if (panicstr || shutdown_in_progress) {
@@ -2571,7 +2144,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 ? */
@@ -2583,14 +2156,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);
@@ -2678,9 +2250,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;
}
@@ -2708,9 +2280,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)
@@ -2727,8 +2311,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)
@@ -2737,8 +2321,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;
@@ -2763,8 +2347,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;
}
@@ -2816,25 +2399,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) {
- memset_io(Crtat, 0, 800*600/8);
- }
+
+ /* FIXME: the screen size may be larger than a 64K segment. */
+ if (ISPIXELSC(new_scp))
+ memset_io(Crtat, 0, new_scp->xpixel*new_scp->ypixel/8);
}
static void
@@ -2883,7 +2467,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 */
@@ -2969,7 +2553,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 */
@@ -3031,7 +2615,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 */
@@ -3046,7 +2630,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 */
@@ -3287,7 +2871,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;
@@ -3304,8 +2888,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;
@@ -3318,9 +2902,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);
}
@@ -3461,7 +3045,7 @@ outloop:
break;
case 0x0c: /* form feed, clears screen */
- clear_screen(scp);
+ sc_clear_screen(scp);
break;
case 0x0d: /* return, return to pos 0 */
@@ -3508,42 +3092,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;
@@ -3551,51 +3110,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]))
memcpy_fromio(sc_buffer, Crtat,
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;
@@ -3610,28 +3140,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
}
@@ -3646,52 +3174,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
@@ -3701,22 +3256,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;
}
@@ -3724,43 +3272,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;
@@ -3788,7 +3322,7 @@ init_scp(scr_stat *scp)
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
@@ -4237,9 +3771,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);
}
}
}
@@ -4506,459 +4040,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 = 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;
-
- 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] = readb(0x44a); /* COLS */
- buf[1] = readb(0x484); /* ROWS */
- buf[2] = readb(0x485); /* POINTS */
- buf[3] = readb(0x44c);
- buf[4] = readb(0x44d);
+ set_border(scp, scp->border);
- 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
- outb(TSIDX, 0x00); outb(TSREG, 0x01);
- outb(TSIDX, 0x02); outb(TSREG, 0x04);
- outb(TSIDX, 0x04); outb(TSREG, 0x07);
- outb(TSIDX, 0x00); outb(TSREG, 0x03);
- outb(GDCIDX, 0x04); outb(GDCREG, 0x02);
- outb(GDCIDX, 0x05); outb(GDCREG, 0x00);
- outb(GDCIDX, 0x06); outb(GDCREG, 0x04);
-#else
- outw(TSIDX, 0x0100);
- outw(TSIDX, 0x0402);
- outw(TSIDX, 0x0704);
- outw(TSIDX, 0x0300);
- 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
- outb(TSIDX, 0x00); outb(TSREG, 0x01);
- outb(TSIDX, 0x02); outb(TSREG, buf[0]);
- outb(TSIDX, 0x04); outb(TSREG, buf[1]);
- outb(TSIDX, 0x00); outb(TSREG, 0x03);
- 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
- outw(TSIDX, 0x0100);
- outw(TSIDX, 0x0002 | (buf[0] << 8));
- outw(TSIDX, 0x0004 | (buf[1] << 8));
- outw(TSIDX, 0x0300);
- 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)
- writeb(VIDEOMEM+(segment)+(ch*32)+line,
- font_image[(ch*fontsize)+line]);
- else
- font_image[(ch*fontsize)+line] =
- readb(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];
- u_int32_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 = VIDEOMEM + 0x8000;
- }
- else if (scp->font_size >= 16) {
+ font_size = 8;
+ } else if (scp->font_size >= 16) {
font_buffer = font_16;
- address = VIDEOMEM;
- }
- else {
+ font_size = 16;
+ } else {
font_buffer = font_14;
- address = VIDEOMEM + 0x4000;
+ font_size = 14;
}
- /*
- * FONT KLUDGE
- * Always use the font page #0. XXX
- */
- address = VIDEOMEM;
if (scp->status & MOUSE_VISIBLE) {
if ((scp->cursor_saveunder & 0xff) == SC_MOUSE_CHAR)
@@ -4983,9 +4158,18 @@ set_destructive_cursor(scr_stat *scp)
#if 1
while (!(inb(crtc_addr+6) & 0x08)) /* wait for vertical retrace */ ;
#endif
- set_font_mode(buf);
- memcpy_toio(address + DEAD_CHAR * 32, cursor, 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
@@ -4997,7 +4181,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)
@@ -5068,7 +4252,7 @@ mouse_cut(scr_stat *scp)
j = i;
/* trim trailing blank when crossing lines */
if (((p - scp->scr_buf) % scp->xsize) == (scp->xsize - 1)) {
- cut_buffer[j++] = '\n';
+ cut_buffer[j++] = '\r';
i = j;
}
}
@@ -5087,7 +4271,7 @@ mouse_cut(scr_stat *scp)
scp->mouse_cut_start = p;
else
scp->mouse_cut_end = p;
- cut_buffer[j++] = '\n';
+ cut_buffer[j++] = '\r';
cut_buffer[j] = '\0';
}
@@ -5112,7 +4296,7 @@ mouse_cut_start(scr_stat *scp)
((scp->mouse_pos - scp->scr_buf) / scp->xsize) * scp->xsize + i;
scp->mouse_cut_end = scp->scr_buf +
((scp->mouse_pos - scp->scr_buf) / scp->xsize + 1) * scp->xsize;
- cut_buffer[0] = '\n';
+ cut_buffer[0] = '\r';
cut_buffer[1] = '\0';
scp->status |= MOUSE_CUTTING;
} else {
@@ -5195,7 +4379,7 @@ mouse_cut_line(scr_stat *scp)
scp->mouse_cut_end = scp->mouse_cut_start + scp->xsize;
for (i = 0, p = scp->mouse_cut_start; p < scp->mouse_cut_end; ++p)
cut_buffer[i++] = *p & 0xff;
- cut_buffer[i++] = '\n';
+ cut_buffer[i++] = '\r';
cut_buffer[i] = '\0';
scp->status |= MOUSE_CUTTING;
}
@@ -5227,35 +4411,26 @@ mouse_paste(scr_stat *scp)
static void
draw_mouse_image(scr_stat *scp)
{
- u_int32_t address;
- int i;
- char *font_buffer;
- u_char buf[PARAM_BUFSIZE];
u_short buffer[32];
u_short xoffset, yoffset;
u_int32_t crt_pos = Crtat + 2*(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 = VIDEOMEM + 0x8000;
- }
- else if (font_size >= 16) {
+ font_size = 8;
+ } else if (scp->font_size >= 16) {
font_buffer = font_16;
- address = VIDEOMEM;
- }
- else {
+ font_size = 16;
+ } else {
font_buffer = font_14;
- address = VIDEOMEM + 0x4000;
+ font_size = 14;
}
- /*
- * FONT KLUDGE
- * Always use the font page #0. XXX
- */
- address = 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),
@@ -5290,9 +4465,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);
- memcpy_toio(address + SC_MOUSE_CHAR * 32, scp->mouse_cursor, 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;
+
writew(crt_pos, (*(scp->mouse_pos) & 0xff00) | SC_MOUSE_CHAR);
writew(crt_pos+2*scp->xsize,
(*(scp->mouse_pos + scp->xsize) & 0xff00) | (SC_MOUSE_CHAR + 2));
@@ -5310,6 +4487,8 @@ remove_mouse_image(scr_stat *scp)
{
u_int32_t crt_pos = Crtat + 2*(scp->mouse_oldpos - scp->scr_buf);
+ if (!ISTEXTSC(scp))
+ return;
writew(crt_pos, *(scp->mouse_oldpos));
writew(crt_pos+2, *(scp->mouse_oldpos+1));
writew(crt_pos+2*scp->xsize, *(scp->mouse_oldpos+scp->xsize));
@@ -5360,30 +4539,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)
@@ -5411,7 +4566,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)
@@ -5432,25 +4587,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)) {
- memcpy_toio(Crtat+2*from, p+from, (to-from+1)*sizeof (u_short));
- } else if (scp->mode == 0x102) {
- u_int32_t d, e;
- int i,j;
+ u_char *font;
+ u_int32_t d, e;
+ u_char *f;
+ int font_size;
+ int line_length;
+ int xsize;
+ int i, j;
+ if (ISTEXTSC(scp)) {
+ memcpy_toio(Crtat+2*from, p+from, (to-from+1)*sizeof (u_short));
+ } else /* if ISPIXELSC(scp) */ {
if (mark)
- mark = 255;
- d = 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 = 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++) {
- writeb(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++) {
+ writeb(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;
}
}
}
@@ -5458,40 +4629,42 @@ 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 */
CDEV_DRIVER_MODULE(sc, isa, sc_driver, sc_devclass,
- CDEV_MAJOR, scdevsw, 0, 0);
+ CDEV_MAJOR, sc_cdevsw, 0, 0);
#endif /* NSC */
diff --git a/sys/isa/syscons.h b/sys/isa/syscons.h
index dc57f07..e8f9461 100644
--- a/sys/isa/syscons.h
+++ b/sys/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,8 +25,8 @@
* (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$
- * from: i386/isa syscons.h,v 1.39
+ * $Id: syscons.h,v 1.40 1998/08/06 09:15:53 dfr Exp $
+ * from: i386/isa syscons.h,v 1.40
*/
#ifndef _I386_ISA_SYSCONS_H_
@@ -77,6 +77,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
@@ -86,6 +89,7 @@
#define XT_KEYBD 0x00010
#define KBD_NORESET 0x00020
#define QUIET_BELL 0x00040
+#define VESA800X600 0x00080
/* attribute flags */
#define NORMAL_ATTR 0x00
@@ -96,9 +100,6 @@
#define FOREGROUND_CHANGED 0x10
#define BACKGROUND_CHANGED 0x20
-/* video hardware memory addresses */
-#define VIDEOMEM 0x000A0000
-
/* misc defines */
#define FALSE 0
#define TRUE 1
@@ -116,20 +117,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
@@ -153,6 +140,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 */
@@ -162,6 +150,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 */
@@ -200,7 +190,8 @@ typedef struct scr_stat {
struct apmhook r_hook; /* reconfiguration support */
#endif
#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;
@@ -209,18 +200,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/isa/videoio.c b/sys/isa/videoio.c
new file mode 100644
index 0000000..c5b84c6
--- /dev/null
+++ b/sys/isa/videoio.c
@@ -0,0 +1,1628 @@
+/*-
+ * 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$
+ * from: i386/isa videoio.c,v 1.1
+ */
+
+#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 <isa/isareg.h>
+#include <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_int32_t buf;
+ u_short v;
+ u_int32_t p;
+
+ buf = BIOS_PADDRTOVADDR(adp->va_window);
+ v = readw(buf);
+ writew(buf, 0xA55A);
+ if (readw(buf) != 0xA55A)
+ return 1;
+ writew(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 */
+
+#ifdef __i386__
+ /* 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);
+ }
+#endif
+ 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.
+ */
+#ifdef __i386__
+ switch ((rtcin(RTC_EQUIPMENT) >> 4) & 3) { /* bit 4 and 5 */
+ case 0:
+ /* EGA/VGA */
+ fill_adapter_param(readb(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;
+ }
+#else
+ /* EGA/VGA */
+ fill_adapter_param(-1, adapter);
+#endif
+
+ 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;
+#ifdef __i386__
+ adapter[V_ADP_PRIMARY].va_initial_bios_mode =
+ *(u_int8_t *)BIOS_PADDRTOVADDR(0x449);
+#else
+ adapter[V_ADP_PRIMARY].va_initial_bios_mode = 3;
+#endif
+ 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) {
+ memcpy_fromio(data, BIOS_PADDRTOVADDR(segment + ch*32),
+ fontsize*count);
+ } else {
+ for (c = ch; count > 0; ++c, --count) {
+ memcpy_fromio(data, 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_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) {
+ memcpy_toio(BIOS_PADDRTOVADDR(segment + ch*32), data,
+ fontsize*count);
+ } else {
+ for (c = ch; count > 0; ++c, --count) {
+ memcpy_toio(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_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 */
+
+#ifdef __i386__
+ 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
+ }
+#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, (int)adp->va_window_size, (int)adp->va_window_gran,
+ adp->va_buffer, (int)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;
+
+#ifdef __i386__
+ 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);
+ }
+#endif
+
+ 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/isa/videoio.h b/sys/isa/videoio.h
new file mode 100644
index 0000000..d004478
--- /dev/null
+++ b/sys/isa/videoio.h
@@ -0,0 +1,108 @@
+/*-
+ * 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$
+ * from: i386/isa/videoio.h,v 1.1
+ */
+
+#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_ */
OpenPOWER on IntegriCloud