summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/alpha/alpha/cons.c38
-rw-r--r--sys/alpha/conf/files.alpha7
-rw-r--r--sys/alpha/conf/options.alpha20
-rw-r--r--sys/alpha/include/cons.h12
-rw-r--r--sys/alpha/include/console.h638
-rw-r--r--sys/conf/NOTES31
-rw-r--r--sys/conf/files.alpha7
-rw-r--r--sys/conf/files.i38615
-rw-r--r--sys/conf/options.alpha20
-rw-r--r--sys/conf/options.i38621
-rw-r--r--sys/dev/fb/fb.c473
-rw-r--r--sys/dev/fb/fbreg.h65
-rw-r--r--sys/dev/fb/splash.c15
-rw-r--r--sys/dev/fb/splash_bmp.c5
-rw-r--r--sys/dev/fb/splash_pcx.c5
-rw-r--r--sys/dev/fb/splashreg.h5
-rw-r--r--sys/dev/fb/vga.c3041
-rw-r--r--sys/dev/fb/vgareg.h34
-rw-r--r--sys/dev/sio/sio.c15
-rw-r--r--sys/dev/syscons/blank/blank_saver.c71
-rw-r--r--sys/dev/syscons/daemon/daemon_saver.c103
-rw-r--r--sys/dev/syscons/fade/fade_saver.c69
-rw-r--r--sys/dev/syscons/fire/fire_saver.c9
-rw-r--r--sys/dev/syscons/green/green_saver.c82
-rw-r--r--sys/dev/syscons/logo/logo_saver.c10
-rw-r--r--sys/dev/syscons/rain/rain_saver.c8
-rw-r--r--sys/dev/syscons/scgfbrndr.c829
-rw-r--r--sys/dev/syscons/schistory.c222
-rw-r--r--sys/dev/syscons/scmouse.c1083
-rw-r--r--sys/dev/syscons/scvesactl.c9
-rw-r--r--sys/dev/syscons/scvgarndr.c829
-rw-r--r--sys/dev/syscons/scvidctl.c474
-rw-r--r--sys/dev/syscons/scvtb.c283
-rw-r--r--sys/dev/syscons/snake/snake_saver.c56
-rw-r--r--sys/dev/syscons/star/star_saver.c49
-rw-r--r--sys/dev/syscons/syscons.c4167
-rw-r--r--sys/dev/syscons/syscons.h411
-rw-r--r--sys/dev/syscons/warp/warp_saver.c9
-rw-r--r--sys/i386/conf/LINT31
-rw-r--r--sys/i386/conf/NOTES31
-rw-r--r--sys/i386/conf/files.i38615
-rw-r--r--sys/i386/conf/options.i38621
-rw-r--r--sys/i386/i386/cons.c17
-rw-r--r--sys/i386/i386/cons.h13
-rw-r--r--sys/i386/include/console.h637
-rw-r--r--sys/i386/isa/pcvt/pcvt_drv.c9
-rw-r--r--sys/i386/isa/vesa.c668
-rw-r--r--sys/isa/sio.c15
-rw-r--r--sys/isa/syscons_isa.c170
-rw-r--r--sys/isa/vga_isa.c2129
-rw-r--r--sys/kern/tty_cons.c17
-rw-r--r--sys/modules/splash/bmp/splash_bmp.c5
-rw-r--r--sys/modules/splash/pcx/splash_pcx.c5
-rw-r--r--sys/modules/syscons/blank/blank_saver.c71
-rw-r--r--sys/modules/syscons/daemon/daemon_saver.c103
-rw-r--r--sys/modules/syscons/fade/fade_saver.c69
-rw-r--r--sys/modules/syscons/fire/fire_saver.c9
-rw-r--r--sys/modules/syscons/green/green_saver.c82
-rw-r--r--sys/modules/syscons/logo/logo_saver.c10
-rw-r--r--sys/modules/syscons/rain/rain_saver.c8
-rw-r--r--sys/modules/syscons/saver.h39
-rw-r--r--sys/modules/syscons/snake/snake_saver.c56
-rw-r--r--sys/modules/syscons/star/star_saver.c49
-rw-r--r--sys/modules/syscons/warp/warp_saver.c9
-rw-r--r--sys/sys/cons.h13
-rw-r--r--sys/sys/consio.h385
-rw-r--r--sys/sys/fbio.h289
-rw-r--r--sys/sys/kbio.h228
68 files changed, 11762 insertions, 6681 deletions
diff --git a/sys/alpha/alpha/cons.c b/sys/alpha/alpha/cons.c
index 161fecf..7194a33 100644
--- a/sys/alpha/alpha/cons.c
+++ b/sys/alpha/alpha/cons.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* from: @(#)cons.c 7.2 (Berkeley) 5/9/91
- * $Id: cons.c,v 1.9 1999/05/31 11:23:35 phk Exp $
+ * $Id: cons.c,v 1.10 1999/06/01 20:26:04 dt Exp $
*/
#include "opt_devfs.h"
@@ -57,25 +57,6 @@
#include <machine/cpu.h>
#include <machine/cons.h>
-/* XXX this should be config(8)ed. */
-#if 0
-#include "sc.h"
-#include "vt.h"
-#include "sio.h"
-#endif
-static struct consdev constab[] = {
-#if NSC > 0
- { sccnprobe, sccninit, sccngetc, sccncheckc, sccnputc },
-#endif
-#if NVT > 0
- { pccnprobe, pccninit, pccngetc, pccncheckc, pccnputc },
-#endif
-#if NSIO > 0
- { siocnprobe, siocninit, siocngetc, siocncheckc, siocnputc },
-#endif
- { 0 },
-};
-
static d_open_t cnopen;
static d_close_t cnclose;
static d_read_t cnread;
@@ -129,16 +110,22 @@ static struct tty *cn_tp; /* physical console tty struct */
static void *cn_devfs_token; /* represents the devfs entry */
#endif /* DEVFS */
+CONS_DRIVER(cons, NULL, NULL, NULL, NULL, NULL, NULL);
+
void
cninit()
{
struct consdev *best_cp, *cp;
+ struct consdev **list;
/*
* Find the first console with the highest priority.
*/
best_cp = NULL;
- for (cp = constab; cp->cn_probe; cp++) {
+ list = (struct consdev **)cons_set.ls_items;
+ while ((cp = *list++) != NULL) {
+ if (cp->cn_probe == NULL)
+ continue;
(*cp->cn_probe)(cp);
if (cp->cn_pri > CN_DEAD &&
(best_cp == NULL || cp->cn_pri > best_cp->cn_pri))
@@ -161,6 +148,8 @@ cninit()
* If no console, give up.
*/
if (best_cp == NULL) {
+ if (cn_tab != NULL && cn_tab->cn_term != NULL)
+ (*cn_tab->cn_term)(cn_tab);
cn_tab = best_cp;
return;
}
@@ -168,10 +157,13 @@ cninit()
/*
* Initialize console, then attach to it. This ordering allows
* debugging using the previous console, if any.
- * XXX if there was a previous console, then its driver should
- * be informed when we forget about it.
*/
(*best_cp->cn_init)(best_cp);
+ if (cn_tab != NULL && cn_tab != best_cp) {
+ /* Turn off the previous console. */
+ if (cn_tab->cn_term != NULL)
+ (*cn_tab->cn_term)(cn_tab);
+ }
cn_tab = best_cp;
}
diff --git a/sys/alpha/conf/files.alpha b/sys/alpha/conf/files.alpha
index 112d8f8..fb69c9a 100644
--- a/sys/alpha/conf/files.alpha
+++ b/sys/alpha/conf/files.alpha
@@ -1,7 +1,7 @@
# This file tells config what files go into building a kernel,
# files marked standard are always included.
#
-# $Id: files.alpha,v 1.20 1999/06/05 13:29:57 dfr Exp $
+# $Id: files.alpha,v 1.21 1999/06/19 13:12:51 dfr Exp $
#
# The long compile-with and dependency lines are required because of
# limitations in config: backslash-newline doesn't work in strings, and
@@ -152,6 +152,7 @@ libkern/alpha/ntohs.S standard
isa/sio.c optional sio device-driver
dev/fb/fb.c optional fb device-driver
dev/fb/fb.c optional vga device-driver
+dev/fb/vga.c optional vga device-driver
isa/vga_isa.c optional vga device-driver
dev/fb/splash.c optional splash
dev/kbd/atkbd.c optional atkbd device-driver
@@ -162,7 +163,11 @@ dev/kbd/kbd.c optional atkbd device-driver
dev/kbd/kbd.c optional kbd device-driver
dev/kbd/kbd.c optional ukbd device-driver
dev/syscons/syscons.c optional sc device-driver
+dev/syscons/schistory.c optional sc device-driver
+dev/syscons/scmouse.c optional sc device-driver
+dev/syscons/scvgarndr.c optional sc device-driver
dev/syscons/scvidctl.c optional sc device-driver
+dev/syscons/scvtb.c optional sc device-driver
isa/syscons_isa.c optional sc device-driver
isa/psm.c optional psm device-driver
isa/fd.c optional fd device-driver
diff --git a/sys/alpha/conf/options.alpha b/sys/alpha/conf/options.alpha
index 9c8e8e1..d78c220 100644
--- a/sys/alpha/conf/options.alpha
+++ b/sys/alpha/conf/options.alpha
@@ -1,4 +1,4 @@
-# $Id: options.alpha,v 1.10 1999/03/10 10:36:50 yokota Exp $
+# $Id: options.alpha,v 1.11 1999/05/27 22:03:31 gallatin Exp $
EV5 opt_global.h
EV4 opt_global.h
@@ -21,25 +21,35 @@ CMD640 opt_wd.h
SHOW_BUSYBUFS
PANIC_REBOOT_WAIT_TIME opt_panic.h
-SC_SPLASH_SCREEN opt_syscons.h
MAXCONS opt_syscons.h
-SLOW_VGA opt_syscons.h
-STD8X16FONT opt_syscons.h
-SC_HISTORY_SIZE opt_syscons.h
+SC_ALT_MOUSE_IMAGE opt_syscons.h
+SC_DEBUG_LEVEL opt_syscons.h
+SC_DFLT_FONT opt_syscons.h
+SC_DISABLE_DDB opt_syscons.h
SC_DISABLE_REBOOT opt_syscons.h
+SC_HISTORY_SIZE opt_syscons.h
SC_MOUSE_CHAR opt_syscons.h
+SC_NO_CUTPASTE opt_syscons.h
+SC_NO_FONT_LOADING opt_syscons.h
+SC_NO_HISTORY opt_syscons.h
+SC_NO_SYSMOUSE opt_syscons.h
+SC_PIXEL_MODE opt_syscons.h
+SC_RENDER_DEBUG opt_syscons.h
+SC_VIDEO_DEBUG opt_syscons.h
VGA_ALT_SEQACCESS opt_vga.h
VGA_DEBUG opt_vga.h
VGA_NO_FONT_LOADING opt_vga.h
VGA_NO_MODE_CHANGE opt_vga.h
VGA_SLOW_IOACCESS opt_vga.h
+VGA_WIDTH90 opt_vga.h
PSM_HOOKAPM opt_psm.h
PSM_RESETAFTERSUSPEND opt_psm.h
PSM_DEBUG opt_psm.h
# Fb options
+FB_DEBUG opt_fb.h
FB_INSTALL_CDEV opt_fb.h
# Atkbd options
diff --git a/sys/alpha/include/cons.h b/sys/alpha/include/cons.h
index 057a2fa..fdc0da0 100644
--- a/sys/alpha/include/cons.h
+++ b/sys/alpha/include/cons.h
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* from: @(#)cons.h 7.2 (Berkeley) 5/9/91
- * $Id: cons.h,v 1.1 1998/06/10 10:54:42 dfr Exp $
+ * $Id: cons.h,v 1.2 1999/01/23 16:53:27 dfr Exp $
*/
#ifndef _MACHINE_CONS_H_
@@ -45,6 +45,7 @@
struct consdev;
typedef void cn_probe_t __P((struct consdev *));
typedef void cn_init_t __P((struct consdev *));
+typedef void cn_term_t __P((struct consdev *));
typedef int cn_getc_t __P((dev_t));
typedef int cn_checkc_t __P((dev_t));
typedef void cn_putc_t __P((dev_t, int));
@@ -66,6 +67,8 @@ struct consdev {
/* probe hardware and fill in consdev info */
cn_init_t *cn_init;
/* turn on as console */
+ cn_term_t *cn_term;
+ /* turn off as console */
cn_getc_t *cn_getc;
/* kernel getchar interface */
cn_checkc_t *cn_checkc;
@@ -84,8 +87,15 @@ struct consdev {
#define CN_REMOTE 3 /* serial interface with remote bit set */
#ifdef KERNEL
+extern struct linker_set cons_set;
extern int cons_unavail;
+#define CONS_DRIVER(name, probe, init, term, getc, checkc, putc) \
+ static struct consdev name##_consdev = { \
+ probe, init, term, getc, checkc, putc \
+ }; \
+ DATA_SET(cons_set, name##_consdev)
+
/* Other kernel entry points. */
int cncheckc __P((void));
int cngetc __P((void));
diff --git a/sys/alpha/include/console.h b/sys/alpha/include/console.h
index 9521dfa..79a6b57 100644
--- a/sys/alpha/include/console.h
+++ b/sys/alpha/include/console.h
@@ -1,636 +1,8 @@
-/*-
- * Copyright (c) 1991-1996 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.
- * 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 AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $Id: console.h,v 1.43 1999/02/05 11:51:56 yokota Exp $
- * from: i386/include console.h,v 1.43
- */
+#ifndef _MACHINE_CONSOLE_H_
+#define _MACHINE_CONSOLE_H_
-#ifndef _MACHINE_CONSOLE_H_
-#define _MACHINE_CONSOLE_H_
-
-#ifndef KERNEL
-#include <sys/types.h>
-#endif
-#include <sys/ioccom.h>
-
-#define KDGKBMODE _IOR('K', 6, int)
-#define KDSKBMODE _IO('K', 7 /*, int */)
-#define KDMKTONE _IO('K', 8 /*, int */)
-#define KDGETMODE _IOR('K', 9, int)
-#define KDSETMODE _IO('K', 10 /*, int */)
-#define KDSBORDER _IO('K', 13 /*, int */)
-#define KDGKBSTATE _IOR('K', 19, int)
-#define KDSKBSTATE _IO('K', 20 /*, int */)
-#define KDENABIO _IO('K', 60)
-#define KDDISABIO _IO('K', 61)
-#define KIOCSOUND _IO('K', 63 /*, int */)
-#define KDGKBTYPE _IOR('K', 64, int)
-#define KDGETLED _IOR('K', 65, int)
-#define KDSETLED _IO('K', 66 /*, int */)
-#define KDSETRAD _IO('K', 67 /*, int */) /* obsolete */
-#define KDRASTER _IOW('K', 100, scr_size_t)
-#define KDGKBINFO _IOR('K', 101, keyboard_info_t)
-#define KDSETREPEAT _IOW('K', 102, keyboard_delay_t)
-
-#define GETFKEY _IOWR('k', 0, fkeyarg_t)
-#define SETFKEY _IOWR('k', 1, fkeyarg_t)
-#define GIO_SCRNMAP _IOR('k', 2, scrmap_t)
-#define PIO_SCRNMAP _IOW('k', 3, scrmap_t)
-#define GIO_KEYMAP _IOR('k', 6, keymap_t)
-#define PIO_KEYMAP _IOW('k', 7, keymap_t)
-#define GIO_DEADKEYMAP _IOR('k', 8, accentmap_t)
-#define PIO_DEADKEYMAP _IOW('k', 9, accentmap_t)
-#define GIO_KEYMAPENT _IOWR('k', 10, keyarg_t)
-#define PIO_KEYMAPENT _IOW('k', 11, keyarg_t)
-
-#define GIO_ATTR _IOR('a', 0, int)
-#define GIO_COLOR _IOR('c', 0, int)
-#define CONS_CURRENT _IOR('c', 1, int)
-#define CONS_GET _IOR('c', 2, int)
-#define CONS_IO _IO('c', 3)
-#define CONS_BLANKTIME _IOW('c', 4, int)
-#define CONS_SSAVER _IOW('c', 5, ssaver_t)
-#define CONS_GSAVER _IOWR('c', 6, ssaver_t)
-#define CONS_CURSORTYPE _IOW('c', 7, int)
-#define CONS_BELLTYPE _IOW('c', 8, int)
-#define CONS_HISTORY _IOW('c', 9, int)
-#define CONS_MOUSECTL _IOWR('c', 10, mouse_info_t)
-#define CONS_IDLE _IOR('c', 11, int)
-#define CONS_SAVERMODE _IOW('c', 12, int)
-#define CONS_SAVERSTART _IOW('c', 13, int)
-#define PIO_FONT8x8 _IOW('c', 64, fnt8_t)
-#define GIO_FONT8x8 _IOR('c', 65, fnt8_t)
-#define PIO_FONT8x14 _IOW('c', 66, fnt14_t)
-#define GIO_FONT8x14 _IOR('c', 67, fnt14_t)
-#define PIO_FONT8x16 _IOW('c', 68, fnt16_t)
-#define GIO_FONT8x16 _IOR('c', 69, fnt16_t)
-#define CONS_GETINFO _IOWR('c', 73, vid_info_t)
-#define CONS_GETVERS _IOR('c', 74, int)
-#define CONS_CURRENTADP _IOR('c', 100, int)
-#define CONS_ADPINFO _IOWR('c', 101, video_adapter_info_t)
-#define CONS_MODEINFO _IOWR('c', 102, video_info_t)
-#define CONS_FINDMODE _IOWR('c', 103, video_info_t)
-#define CONS_SETWINORG _IO('c', 104 /* u_int */)
-
-#define CONS_SETKBD _IO('c', 110 /* int */)
-#define CONS_RELKBD _IO('c', 111)
-
-/* CONS_SAVERMODE */
-#define CONS_LKM_SAVER 0
-#define CONS_USR_SAVER 1
-
-#ifdef PC98
-#define ADJUST_CLOCK _IO('t',100) /* for 98note resume */
-#endif
-
-#define VT_OPENQRY _IOR('v', 1, int)
-#define VT_SETMODE _IOW('v', 2, vtmode_t)
-#define VT_GETMODE _IOR('v', 3, vtmode_t)
-#define VT_RELDISP _IO('v', 4 /*, int */)
-#define VT_ACTIVATE _IO('v', 5 /*, int */)
-#define VT_WAITACTIVE _IO('v', 6 /*, int */)
-#define VT_GETACTIVE _IOR('v', 7, int)
-
-#define VT_FALSE 0
-#define VT_TRUE 1
-#define VT_ACKACQ 2
-
-#define VT_AUTO 0 /* switching is automatic */
-#define VT_PROCESS 1 /* switching controlled by prog */
-#define VT_KERNEL 255 /* switching controlled in kernel */
-
-#ifndef _VT_MODE_DECLARED
-#define _VT_MODE_DECLARED
-struct vt_mode {
- char mode;
- char waitv; /* not implemented yet SOS */
- short relsig;
- short acqsig;
- short frsig; /* not implemented yet SOS */
-};
-
-typedef struct vt_mode vtmode_t;
-#endif /* !_VT_MODE_DECLARED */
-
-struct mouse_data {
- int x;
- int y;
- int z;
- int buttons;
-};
-
-struct mouse_mode {
- int mode;
- int signal;
-};
-
-struct mouse_event {
- int id; /* one based */
- int value;
-};
-
-#define MOUSE_SHOW 0x01
-#define MOUSE_HIDE 0x02
-#define MOUSE_MOVEABS 0x03
-#define MOUSE_MOVEREL 0x04
-#define MOUSE_GETINFO 0x05
-#define MOUSE_MODE 0x06
-#define MOUSE_ACTION 0x07
-#define MOUSE_MOTION_EVENT 0x08
-#define MOUSE_BUTTON_EVENT 0x09
-
-struct mouse_info {
- int operation;
- union {
- struct mouse_data data;
- struct mouse_mode mode;
- struct mouse_event event;
- }u;
-};
-
-#define KD_MONO 1 /* monochrome adapter */
-#define KD_HERCULES 2 /* hercules adapter */
-#define KD_CGA 3 /* color graphics adapter */
-#define KD_EGA 4 /* enhanced graphics adapter */
-#define KD_VGA 5 /* video graphics adapter */
-#define KD_PC98 6 /* PC-98 display */
-
-#define KD_TEXT 0 /* set text mode restore fonts */
-#define KD_TEXT0 0 /* ditto */
-#define KD_TEXT1 2 /* set text mode !restore fonts */
-#define KD_GRAPHICS 1 /* set graphics mode */
-#define KD_PIXEL 3 /* set pixel mode */
-
-#define K_RAW 0 /* keyboard returns scancodes */
-#define K_XLATE 1 /* keyboard returns ascii */
-#define K_CODE 2 /* keyboard returns keycodes */
-
-#define KB_84 1 /* 'old' 84 key AT-keyboard */
-#define KB_101 2 /* MF-101 or MF-102 keyboard */
-#define KB_OTHER 3 /* keyboard not known */
-
-#define CLKED 1 /* Caps locked */
-#define NLKED 2 /* Num locked */
-#define SLKED 4 /* Scroll locked */
-#define ALKED 8 /* AltGr locked */
-#define LOCK_MASK (CLKED | NLKED | SLKED | ALKED)
-#define LED_CAP 1 /* Caps lock LED */
-#define LED_NUM 2 /* Num lock LED */
-#define LED_SCR 4 /* Scroll lock LED */
-#define LED_MASK (LED_CAP | LED_NUM | LED_SCR)
-
-/* possible flag values */
-#define FLAG_LOCK_O 0
-#define FLAG_LOCK_C 1
-#define FLAG_LOCK_N 2
-
-#define NUM_KEYS 256 /* number of keys in table */
-#define NUM_STATES 8 /* states per key */
-#define ALTGR_OFFSET 128 /* offset for altlock keys */
-
-#ifndef _KEYMAP_DECLARED
-#define _KEYMAP_DECLARED
-struct keyent_t {
- u_char map[NUM_STATES];
- u_char spcl;
- u_char flgs;
-};
-
-struct keymap {
- u_short n_keys;
- struct keyent_t key[NUM_KEYS];
-};
-
-typedef struct keymap keymap_t;
-
-struct keyarg {
- u_short keynum;
- struct keyent_t key;
-};
-
-typedef struct keyarg keyarg_t;
-#endif /* !_KEYMAP_DECLARED */
-
-#define NUM_DEADKEYS 15 /* number of accent keys */
-#define NUM_ACCENTCHARS 52 /* max number of accent chars */
-
-struct acc_t {
- u_char accchar;
- u_char map[NUM_ACCENTCHARS][2];
-};
-
-struct accentmap {
- u_short n_accs;
- struct acc_t acc[NUM_DEADKEYS];
-};
-
-#define MAXFK 16
-#define NUM_FKEYS 96
-
-struct fkeytab {
- u_char str[MAXFK];
- u_char len;
-};
-
-struct fkeyarg {
- u_short keynum;
- char keydef[MAXFK];
- char flen;
-};
-
-struct colors {
- char fore;
- char back;
-};
-
-struct vid_info {
- short size;
- short m_num;
- u_short mv_row, mv_col;
- u_short mv_rsz, mv_csz;
- struct colors mv_norm,
- mv_rev,
- mv_grfc;
- u_char mv_ovscan;
- u_char mk_keylock;
-};
-
-#define MAXSSAVER 16
-
-struct ssaver {
- char name[MAXSSAVER];
- int num;
- long time;
-};
-
-/* video mode information block */
-struct video_info {
- int vi_mode;
- int vi_flags;
-#define V_INFO_COLOR (1<<0)
-#define V_INFO_GRAPHICS (1<<1)
-#define V_INFO_LINEAR (1<<2)
-#define V_INFO_VESA (1<<3)
- int vi_width;
- int vi_height;
- int vi_cwidth;
- int vi_cheight;
- int vi_depth;
- int vi_planes;
- u_int vi_window; /* physical address */
- size_t vi_window_size;
- size_t vi_window_gran;
- u_int vi_buffer; /* physical address */
- size_t vi_buffer_size;
- /* XXX pixel format, memory model,... */
-};
-
-/* adapter infromation block */
-struct video_adapter {
- int va_index;
- int va_type;
- char *va_name;
- int va_unit;
- int va_minor;
- int va_flags;
-#define V_ADP_COLOR (1<<0)
-#define V_ADP_MODECHANGE (1<<1)
-#define V_ADP_STATESAVE (1<<2)
-#define V_ADP_STATELOAD (1<<3)
-#define V_ADP_FONT (1<<4)
-#define V_ADP_PALETTE (1<<5)
-#define V_ADP_BORDER (1<<6)
-#define V_ADP_VESA (1<<7)
-#define V_ADP_PROBED (1<<16)
-#define V_ADP_INITIALIZED (1<<17)
-#define V_ADP_REGISTERED (1<<18)
- int va_io_base;
- int va_io_size;
- int va_crtc_addr;
- int va_mem_base;
- int va_mem_size;
- u_int va_window; /* virtual address */
- size_t va_window_size;
- size_t va_window_gran;
- u_int va_buffer; /* virtual address */
- size_t va_buffer_size;
- int va_initial_mode;
- int va_initial_bios_mode;
- int va_mode;
- struct video_info va_info;
- int va_line_width;
- void *va_token;
-};
-
-struct video_adapter_info {
- int va_index;
- int va_type;
- char va_name[16];
- int va_unit;
- int va_flags;
- int va_io_base;
- int va_io_size;
- int va_crtc_addr;
- int va_mem_base;
- int va_mem_size;
- u_int va_window; /* virtual address */
- size_t va_window_size;
- size_t va_window_gran;
- u_int va_buffer; /* virtual address */
- size_t va_buffer_size;
- int va_initial_mode;
- int va_initial_bios_mode;
- int va_mode;
- int va_line_width;
-};
-
-#define V_ADP_PRIMARY 0
-#define V_ADP_SECONDARY 1
-
-struct keyboard_info {
- int kb_index; /* kbdio index# */
- char kb_name[16]; /* driver name */
- int kb_unit; /* unit# */
- int kb_type; /* KB_84, KB_101, KB_OTHER,... */
- int kb_config; /* device configuration flags */
- int kb_flags; /* internal flags */
-};
-
-typedef struct accentmap accentmap_t;
-typedef struct fkeytab fkeytab_t;
-typedef struct fkeyarg fkeyarg_t;
-typedef struct vid_info vid_info_t;
-typedef struct mouse_info mouse_info_t;
-typedef struct {char scrmap[256];} scrmap_t;
-typedef struct {char fnt8x8[8*256];} fnt8_t;
-typedef struct {char fnt8x14[14*256];} fnt14_t;
-typedef struct {char fnt8x16[16*256];} fnt16_t;
-typedef struct ssaver ssaver_t;
-typedef struct video_adapter video_adapter_t;
-typedef struct video_adapter_info video_adapter_info_t;
-typedef struct video_info video_info_t;
-typedef struct keyboard_info keyboard_info_t;
-typedef struct {int scr_size[3];} scr_size_t;
-typedef struct {int kbd_delay[2];} keyboard_delay_t;
-
-/* defines for "special" keys (spcl bit set in keymap) */
-#define NOP 0x00 /* nothing (dead key) */
-#define LSH 0x02 /* left shift key */
-#define RSH 0x03 /* right shift key */
-#define CLK 0x04 /* caps lock key */
-#define NLK 0x05 /* num lock key */
-#define SLK 0x06 /* scroll lock key */
-#define LALT 0x07 /* left alt key */
-#define BTAB 0x08 /* backwards tab */
-#define LCTR 0x09 /* left control key */
-#define NEXT 0x0a /* switch to next screen */
-#define F_SCR 0x0b /* switch to first screen */
-#define L_SCR 0x1a /* switch to last screen */
-#define F_FN 0x1b /* first function key */
-#define L_FN 0x7a /* last function key */
-/* 0x7b-0x7f reserved do not use ! */
-#define RCTR 0x80 /* right control key */
-#define RALT 0x81 /* right alt (altgr) key */
-#define ALK 0x82 /* alt lock key */
-#define ASH 0x83 /* alt shift key */
-#define META 0x84 /* meta key */
-#define RBT 0x85 /* boot machine */
-#define DBG 0x86 /* call debugger */
-#define SUSP 0x87 /* suspend power (APM) */
-#define SPSC 0x88 /* toggle splash/text screen */
-
-#define F_ACC DGRA /* first accent key */
-#define DGRA 0x89 /* grave */
-#define DACU 0x8a /* acute */
-#define DCIR 0x8b /* circumflex */
-#define DTIL 0x8c /* tilde */
-#define DMAC 0x8d /* macron */
-#define DBRE 0x8e /* breve */
-#define DDOT 0x8f /* dot */
-#define DUML 0x90 /* umlaut/diaresis */
-#define DDIA 0x90 /* diaresis */
-#define DSLA 0x91 /* slash */
-#define DRIN 0x92 /* ring */
-#define DCED 0x93 /* cedilla */
-#define DAPO 0x94 /* apostrophe */
-#define DDAC 0x95 /* double acute */
-#define DOGO 0x96 /* ogonek */
-#define DCAR 0x97 /* caron */
-#define L_ACC DCAR /* last accent key */
-
-#define STBY 0x98 /* Go into standby mode (apm) */
-
-#define F(x) ((x)+F_FN-1)
-#define S(x) ((x)+F_SCR-1)
-#define ACC(x) ((x)+F_ACC)
-#define NOKEY 0x100 /* no key pressed marker */
-#define FKEY 0x200 /* function key marker */
-#define MKEY 0x400 /* meta key marker (prepend ESC)*/
-#define BKEY 0x800 /* backtab (ESC [ Z) */
-
-#define SPCLKEY 0x8000 /* special key */
-#define RELKEY 0x4000 /* key released */
-#define ERRKEY 0x2000 /* error */
-
-#define KEYCHAR(c) ((c) & 0x00ff)
-#define KEYFLAGS(c) ((c) & ~0x00ff)
-
-/* video mode definitions */
-#define M_B40x25 0 /* black & white 40 columns */
-#define M_C40x25 1 /* color 40 columns */
-#define M_B80x25 2 /* black & white 80 columns */
-#define M_C80x25 3 /* color 80 columns */
-#define M_BG320 4 /* black & white graphics 320x200 */
-#define M_CG320 5 /* color graphics 320x200 */
-#define M_BG640 6 /* black & white graphics 640x200 hi-res */
-#define M_EGAMONO80x25 7 /* ega-mono 80x25 */
-#define M_CG320_D 13 /* ega mode D */
-#define M_CG640_E 14 /* ega mode E */
-#define M_EGAMONOAPA 15 /* ega mode F */
-#define M_CG640x350 16 /* ega mode 10 */
-#define M_ENHMONOAPA2 17 /* ega mode F with extended memory */
-#define M_ENH_CG640 18 /* ega mode 10* */
-#define M_ENH_B40x25 19 /* ega enhanced black & white 40 columns */
-#define M_ENH_C40x25 20 /* ega enhanced color 40 columns */
-#define M_ENH_B80x25 21 /* ega enhanced black & white 80 columns */
-#define M_ENH_C80x25 22 /* ega enhanced color 80 columns */
-#define M_VGA_C40x25 23 /* vga 8x16 font on color */
-#define M_VGA_C80x25 24 /* vga 8x16 font on color */
-#define M_VGA_M80x25 25 /* vga 8x16 font on mono */
-
-#define M_VGA11 26 /* vga 640x480 2 colors */
-#define M_BG640x480 26
-#define M_VGA12 27 /* vga 640x480 16 colors */
-#define M_CG640x480 27
-#define M_VGA13 28 /* vga 640x200 256 colors */
-#define M_VGA_CG320 28
-
-#define M_VGA_C80x50 30 /* vga 8x8 font on color */
-#define M_VGA_M80x50 31 /* vga 8x8 font on color */
-#define M_VGA_C80x30 32 /* vga 8x16 font on color */
-#define M_VGA_M80x30 33 /* vga 8x16 font on color */
-#define M_VGA_C80x60 34 /* vga 8x8 font on color */
-#define M_VGA_M80x60 35 /* vga 8x8 font on color */
-#define M_VGA_CG640 36 /* vga 640x400 256 color */
-#define M_VGA_MODEX 37 /* vga 320x240 256 color */
-
-#define M_ENH_B80x43 0x70 /* ega black & white 80x43 */
-#define M_ENH_C80x43 0x71 /* ega color 80x43 */
-
-#define M_PC98_80x25 98 /* PC98 80x25 */
-#define M_PC98_80x30 99 /* PC98 80x30 */
-
-#define M_HGC_P0 0xe0 /* hercules graphics - page 0 @ B0000 */
-#define M_HGC_P1 0xe1 /* hercules graphics - page 1 @ B8000 */
-#define M_MCA_MODE 0xff /* monochrome adapter mode */
-
-#define M_TEXT_80x25 200 /* generic text modes */
-#define M_TEXT_80x30 201
-#define M_TEXT_80x43 202
-#define M_TEXT_80x50 203
-#define M_TEXT_80x60 204
-#define M_TEXT_132x25 205
-#define M_TEXT_132x30 206
-#define M_TEXT_132x43 207
-#define M_TEXT_132x50 208
-#define M_TEXT_132x60 209
-
-#define SW_PC98_80x25 _IO('S', M_PC98_80x25)
-#define SW_PC98_80x30 _IO('S', M_PC98_80x30)
-#define SW_B40x25 _IO('S', M_B40x25)
-#define SW_C40x25 _IO('S', M_C40x25)
-#define SW_B80x25 _IO('S', M_B80x25)
-#define SW_C80x25 _IO('S', M_C80x25)
-#define SW_BG320 _IO('S', M_BG320)
-#define SW_CG320 _IO('S', M_CG320)
-#define SW_BG640 _IO('S', M_BG640)
-#define SW_EGAMONO80x25 _IO('S', M_EGAMONO80x25)
-#define SW_CG320_D _IO('S', M_CG320_D)
-#define SW_CG640_E _IO('S', M_CG640_E)
-#define SW_EGAMONOAPA _IO('S', M_EGAMONOAPA)
-#define SW_CG640x350 _IO('S', M_CG640x350)
-#define SW_ENH_MONOAPA2 _IO('S', M_ENHMONOAPA2)
-#define SW_ENH_CG640 _IO('S', M_ENH_CG640)
-#define SW_ENH_B40x25 _IO('S', M_ENH_B40x25)
-#define SW_ENH_C40x25 _IO('S', M_ENH_C40x25)
-#define SW_ENH_B80x25 _IO('S', M_ENH_B80x25)
-#define SW_ENH_C80x25 _IO('S', M_ENH_C80x25)
-#define SW_ENH_B80x43 _IO('S', M_ENH_B80x43)
-#define SW_ENH_C80x43 _IO('S', M_ENH_C80x43)
-#define SW_MCAMODE _IO('S', M_MCA_MODE)
-#define SW_VGA_C40x25 _IO('S', M_VGA_C40x25)
-#define SW_VGA_C80x25 _IO('S', M_VGA_C80x25)
-#define SW_VGA_C80x30 _IO('S', M_VGA_C80x30)
-#define SW_VGA_C80x50 _IO('S', M_VGA_C80x50)
-#define SW_VGA_C80x60 _IO('S', M_VGA_C80x60)
-#define SW_VGA_M80x25 _IO('S', M_VGA_M80x25)
-#define SW_VGA_M80x30 _IO('S', M_VGA_M80x30)
-#define SW_VGA_M80x50 _IO('S', M_VGA_M80x50)
-#define SW_VGA_M80x60 _IO('S', M_VGA_M80x60)
-#define SW_VGA11 _IO('S', M_VGA11)
-#define SW_BG640x480 _IO('S', M_VGA11)
-#define SW_VGA12 _IO('S', M_VGA12)
-#define SW_CG640x480 _IO('S', M_VGA12)
-#define SW_VGA13 _IO('S', M_VGA13)
-#define SW_VGA_CG320 _IO('S', M_VGA13)
-#define SW_VGA_CG640 _IO('S', M_VGA_CG640)
-#define SW_VGA_MODEX _IO('S', M_VGA_MODEX)
-
-#define SW_TEXT_80x25 _IO('S', M_TEXT_80x25)
-#define SW_TEXT_80x30 _IO('S', M_TEXT_80x30)
-#define SW_TEXT_80x43 _IO('S', M_TEXT_80x43)
-#define SW_TEXT_80x50 _IO('S', M_TEXT_80x50)
-#define SW_TEXT_80x60 _IO('S', M_TEXT_80x60)
-#define SW_TEXT_132x25 _IO('S', M_TEXT_132x25)
-#define SW_TEXT_132x30 _IO('S', M_TEXT_132x30)
-#define SW_TEXT_132x43 _IO('S', M_TEXT_132x43)
-#define SW_TEXT_132x50 _IO('S', M_TEXT_132x50)
-#define SW_TEXT_132x60 _IO('S', M_TEXT_132x60)
-
-#define M_VESA_BASE 0x100 /* VESA mode number base */
-
-#define M_VESA_CG640x400 0x100 /* 640x400, 256 color */
-#define M_VESA_CG640x480 0x101 /* 640x480, 256 color */
-#define M_VESA_800x600 0x102 /* 800x600, 16 color */
-#define M_VESA_CG800x600 0x103 /* 800x600, 256 color */
-#define M_VESA_1024x768 0x104 /* 1024x768, 16 color */
-#define M_VESA_CG1024x768 0x105 /* 1024x768, 256 color */
-#define M_VESA_1280x1024 0x106 /* 1280x1024, 16 color */
-#define M_VESA_CG1280x1024 0x107 /* 1280x1024, 256 color */
-#define M_VESA_C80x60 0x108 /* 8x8 font */
-#define M_VESA_C132x25 0x109 /* 8x16 font */
-#define M_VESA_C132x43 0x10a /* 8x14 font */
-#define M_VESA_C132x50 0x10b /* 8x8 font */
-#define M_VESA_C132x60 0x10c /* 8x8 font */
-#define M_VESA_32K_320 0x10d /* 320x200, 5:5:5 */
-#define M_VESA_64K_320 0x10e /* 320x200, 5:6:5 */
-#define M_VESA_FULL_320 0x10f /* 320x200, 8:8:8 */
-#define M_VESA_32K_640 0x110 /* 640x480, 5:5:5 */
-#define M_VESA_64K_640 0x111 /* 640x480, 5:6:5 */
-#define M_VESA_FULL_640 0x112 /* 640x480, 8:8:8 */
-#define M_VESA_32K_800 0x113 /* 800x600, 5:5:5 */
-#define M_VESA_64K_800 0x114 /* 800x600, 5:6:5 */
-#define M_VESA_FULL_800 0x115 /* 800x600, 8:8:8 */
-#define M_VESA_32K_1024 0x116 /* 1024x768, 5:5:5 */
-#define M_VESA_64K_1024 0x117 /* 1024x768, 5:6:5 */
-#define M_VESA_FULL_1024 0x118 /* 1024x768, 8:8:8 */
-#define M_VESA_32K_1280 0x119 /* 1280x1024, 5:5:5 */
-#define M_VESA_64K_1280 0x11a /* 1280x1024, 5:6:5 */
-#define M_VESA_FULL_1280 0x11b /* 1280x1024, 8:8:8 */
-#define M_VESA_MODE_MAX 0x1ff
-
-#define SW_VESA_CG640x400 _IO('V', M_VESA_CG640x400 - M_VESA_BASE)
-#define SW_VESA_CG640x480 _IO('V', M_VESA_CG640x480 - M_VESA_BASE)
-#define SW_VESA_800x600 _IO('V', M_VESA_800x600 - M_VESA_BASE)
-#define SW_VESA_CG800x600 _IO('V', M_VESA_CG800x600 - M_VESA_BASE)
-#define SW_VESA_1024x768 _IO('V', M_VESA_1024x768 - M_VESA_BASE)
-#define SW_VESA_CG1024x768 _IO('V', M_VESA_CG1024x768 - M_VESA_BASE)
-#define SW_VESA_1280x1024 _IO('V', M_VESA_1280x1024 - M_VESA_BASE)
-#define SW_VESA_CG1280x1024 _IO('V', M_VESA_CG1280x1024 - M_VESA_BASE)
-#define SW_VESA_C80x60 _IO('V', M_VESA_C80x60 - M_VESA_BASE)
-#define SW_VESA_C132x25 _IO('V', M_VESA_C132x25 - M_VESA_BASE)
-#define SW_VESA_C132x43 _IO('V', M_VESA_C132x43 - M_VESA_BASE)
-#define SW_VESA_C132x50 _IO('V', M_VESA_C132x50 - M_VESA_BASE)
-#define SW_VESA_C132x60 _IO('V', M_VESA_C132x60 - M_VESA_BASE)
-#define SW_VESA_32K_320 _IO('V', M_VESA_32K_320 - M_VESA_BASE)
-#define SW_VESA_64K_320 _IO('V', M_VESA_64K_320 - M_VESA_BASE)
-#define SW_VESA_FULL_320 _IO('V', M_VESA_FULL_320 - M_VESA_BASE)
-#define SW_VESA_32K_640 _IO('V', M_VESA_32K_640 - M_VESA_BASE)
-#define SW_VESA_64K_640 _IO('V', M_VESA_64K_640 - M_VESA_BASE)
-#define SW_VESA_FULL_640 _IO('V', M_VESA_FULL_640 - M_VESA_BASE)
-#define SW_VESA_32K_800 _IO('V', M_VESA_32K_800 - M_VESA_BASE)
-#define SW_VESA_64K_800 _IO('V', M_VESA_64K_800 - M_VESA_BASE)
-#define SW_VESA_FULL_800 _IO('V', M_VESA_FULL_800 - M_VESA_BASE)
-#define SW_VESA_32K_1024 _IO('V', M_VESA_32K_1024 - M_VESA_BASE)
-#define SW_VESA_64K_1024 _IO('V', M_VESA_64K_1024 - M_VESA_BASE)
-#define SW_VESA_FULL_1024 _IO('V', M_VESA_FULL_1024 - M_VESA_BASE)
-#define SW_VESA_32K_1280 _IO('V', M_VESA_32K_1280 - M_VESA_BASE)
-#define SW_VESA_64K_1280 _IO('V', M_VESA_64K_1280 - M_VESA_BASE)
-#define SW_VESA_FULL_1280 _IO('V', M_VESA_FULL_1280 - M_VESA_BASE)
+#include <sys/fbio.h>
+#include <sys/kbio.h>
+#include <sys/consio.h>
#endif /* !_MACHINE_CONSOLE_H_ */
-
diff --git a/sys/conf/NOTES b/sys/conf/NOTES
index 5563146..cc51183 100644
--- a/sys/conf/NOTES
+++ b/sys/conf/NOTES
@@ -2,7 +2,7 @@
# LINT -- config file for checking all the sources, tries to pull in
# as much of the source tree as it can.
#
-# $Id: LINT,v 1.606 1999/06/15 13:14:40 des Exp $
+# $Id: LINT,v 1.607 1999/06/19 20:20:52 rnordier Exp $
#
# NB: You probably don't want to try running a kernel built from this
# file. Instead, you should start from GENERIC, and add options from
@@ -912,6 +912,9 @@ options VGA_NO_MODE_CHANGE # don't change video modes
# Older video cards may require this option for proper operation.
options VGA_SLOW_IOACCESS # do byte-wide i/o's to TS and GDC regs
+# The following option probably won't work with the LCD displays.
+options VGA_WIDTH90 # support 90 column modes
+
# To include support for VESA video modes
options VESA
@@ -939,18 +942,20 @@ options PCVT_VT220KEYB
# The syscons console driver (sco color console compatible).
device sc0 at isa?
options MAXCONS=16 # number of virtual consoles
-options STD8X16FONT # Compile font in
-makeoptions STD8X16FONT=cp850
-options SC_HISTORY_SIZE=200 # number of history buffer lines
+options SC_ALT_MOUSE_IMAGE # simplified mouse cursor in text mode
+options SC_DFLT_FONT # compile font in
+makeoptions SC_DFLT_FONT="cp850"
+options SC_DISABLE_DDBKEY # disable `debug' key
options SC_DISABLE_REBOOT # disable reboot key sequence
+options SC_HISTORY_SIZE=200 # number of history buffer lines
+options SC_MOUSE_CHAR=0x3 # char code for text mode mouse cursor
+options SC_PIXEL_MODE # add support for the raster text mode
-#
-# `flags' for sc0:
-# 0x01 Use a 'visual' bell
-# 0x02 Use a 'blink' cursor
-# 0x04 Use a 'underline' cursor
-# 0x06 Use a 'blinking underline' (destructive) cursor
-# 0x40 Make the bell quiet if it is rung in the background vty.
+# You can selectively disable features in syscons.
+options SC_NO_CUTPASTE
+options SC_NO_FONT_LOADING
+options SC_NO_HISTORY
+options SC_NO_SYSMOUSE
#
# The Numeric Processing eXtension driver. This should be configured if
@@ -2155,6 +2160,10 @@ options ULPT_DEBUG
options UMASS_DEBUG
options UMS_DEBUG
+# options for ukbd:
+options UKBD_DFLT_KEYMAP # specify the built-in keymap
+makeoptions UKBD_DFLT_KEYMAP="it.iso"
+
#
# Embedded system options:
#
diff --git a/sys/conf/files.alpha b/sys/conf/files.alpha
index 112d8f8..fb69c9a 100644
--- a/sys/conf/files.alpha
+++ b/sys/conf/files.alpha
@@ -1,7 +1,7 @@
# This file tells config what files go into building a kernel,
# files marked standard are always included.
#
-# $Id: files.alpha,v 1.20 1999/06/05 13:29:57 dfr Exp $
+# $Id: files.alpha,v 1.21 1999/06/19 13:12:51 dfr Exp $
#
# The long compile-with and dependency lines are required because of
# limitations in config: backslash-newline doesn't work in strings, and
@@ -152,6 +152,7 @@ libkern/alpha/ntohs.S standard
isa/sio.c optional sio device-driver
dev/fb/fb.c optional fb device-driver
dev/fb/fb.c optional vga device-driver
+dev/fb/vga.c optional vga device-driver
isa/vga_isa.c optional vga device-driver
dev/fb/splash.c optional splash
dev/kbd/atkbd.c optional atkbd device-driver
@@ -162,7 +163,11 @@ dev/kbd/kbd.c optional atkbd device-driver
dev/kbd/kbd.c optional kbd device-driver
dev/kbd/kbd.c optional ukbd device-driver
dev/syscons/syscons.c optional sc device-driver
+dev/syscons/schistory.c optional sc device-driver
+dev/syscons/scmouse.c optional sc device-driver
+dev/syscons/scvgarndr.c optional sc device-driver
dev/syscons/scvidctl.c optional sc device-driver
+dev/syscons/scvtb.c optional sc device-driver
isa/syscons_isa.c optional sc device-driver
isa/psm.c optional psm device-driver
isa/fd.c optional fd device-driver
diff --git a/sys/conf/files.i386 b/sys/conf/files.i386
index 44c115c..ae19e96 100644
--- a/sys/conf/files.i386
+++ b/sys/conf/files.i386
@@ -1,7 +1,7 @@
# This file tells config what files go into building a kernel,
# files marked standard are always included.
#
-# $Id: files.i386,v 1.246 1999/06/01 18:18:38 jlemon Exp $
+# $Id: files.i386,v 1.247 1999/06/18 19:55:50 green Exp $
#
# The long compile-with and dependency lines are required because of
# limitations in config: backslash-newline doesn't work in strings, and
@@ -19,10 +19,10 @@ linux_assym.h optional compat_linux \
no-obj no-implicit-rule before-depend \
clean "linux_assym.h"
#
-font8x16.o optional std8x16font \
- compile-with "uudecode < /usr/share/syscons/fonts/${STD8X16FONT}-8x16.fnt && file2c 'unsigned char font_16[16*256] = {' '};' < ${STD8X16FONT}-8x16 > font8x16.c && ${CC} -c ${CFLAGS} font8x16.c" \
- no-implicit-rule before-depend \
- clean "${STD8X16FONT}-8x16 font8x16.c"
+font.h optional sc_dflt_font \
+ compile-with "uudecode < /usr/share/syscons/fonts/${SC_DFLT_FONT}-8x16.fnt && file2c 'static u_char dflt_font_16[16*256] = {' '};' < ${SC_DFLT_FONT}-8x16 > font.h && uudecode < /usr/share/syscons/fonts/${SC_DFLT_FONT}-8x14.fnt && file2c 'static u_char dflt_font_14[14*256] = {' '};' < ${SC_DFLT_FONT}-8x14 >> font.h && uudecode < /usr/share/syscons/fonts/${SC_DFLT_FONT}-8x8.fnt && file2c 'static u_char dflt_font_8[8*256] = {' '};' < ${SC_DFLT_FONT}-8x8 >> font.h" \
+ no-obj no-implicit-rule before-depend \
+ clean "font.h"
#
atkbdmap.h optional atkbd_dflt_keymap \
compile-with "kbdcontrol -L ${ATKBD_DFLT_KEYMAP} | sed -e 's/^static keymap_t.* = /static keymap_t key_map = /' -e 's/^static accentmap_t.* = /static accentmap_t accent_map = /' > atkbdmap.h" \
@@ -44,14 +44,19 @@ dev/ata/atapi-tape.c optional atapist device-driver
dev/fb/fb.c optional fb device-driver
dev/fb/fb.c optional vga device-driver
dev/fb/splash.c optional splash
+dev/fb/vga.c optional vga device-driver
dev/kbd/atkbd.c optional atkbd device-driver
dev/kbd/atkbdc.c optional atkbdc device-driver
dev/kbd/kbd.c optional atkbd device-driver
dev/kbd/kbd.c optional kbd device-driver
dev/kbd/kbd.c optional ukbd device-driver
dev/syscons/syscons.c optional sc device-driver
+dev/syscons/schistory.c optional sc device-driver
+dev/syscons/scmouse.c optional sc device-driver
dev/syscons/scvidctl.c optional sc device-driver
dev/syscons/scvesactl.c optional sc device-driver
+dev/syscons/scvgarndr.c optional sc device-driver
+dev/syscons/scvtb.c optional sc device-driver
i386/apm/apm.c optional apm device-driver
i386/apm/apm_setup.s optional apm
i386/eisa/dpt_eisa.c optional eisa dpt device-driver
diff --git a/sys/conf/options.alpha b/sys/conf/options.alpha
index 9c8e8e1..d78c220 100644
--- a/sys/conf/options.alpha
+++ b/sys/conf/options.alpha
@@ -1,4 +1,4 @@
-# $Id: options.alpha,v 1.10 1999/03/10 10:36:50 yokota Exp $
+# $Id: options.alpha,v 1.11 1999/05/27 22:03:31 gallatin Exp $
EV5 opt_global.h
EV4 opt_global.h
@@ -21,25 +21,35 @@ CMD640 opt_wd.h
SHOW_BUSYBUFS
PANIC_REBOOT_WAIT_TIME opt_panic.h
-SC_SPLASH_SCREEN opt_syscons.h
MAXCONS opt_syscons.h
-SLOW_VGA opt_syscons.h
-STD8X16FONT opt_syscons.h
-SC_HISTORY_SIZE opt_syscons.h
+SC_ALT_MOUSE_IMAGE opt_syscons.h
+SC_DEBUG_LEVEL opt_syscons.h
+SC_DFLT_FONT opt_syscons.h
+SC_DISABLE_DDB opt_syscons.h
SC_DISABLE_REBOOT opt_syscons.h
+SC_HISTORY_SIZE opt_syscons.h
SC_MOUSE_CHAR opt_syscons.h
+SC_NO_CUTPASTE opt_syscons.h
+SC_NO_FONT_LOADING opt_syscons.h
+SC_NO_HISTORY opt_syscons.h
+SC_NO_SYSMOUSE opt_syscons.h
+SC_PIXEL_MODE opt_syscons.h
+SC_RENDER_DEBUG opt_syscons.h
+SC_VIDEO_DEBUG opt_syscons.h
VGA_ALT_SEQACCESS opt_vga.h
VGA_DEBUG opt_vga.h
VGA_NO_FONT_LOADING opt_vga.h
VGA_NO_MODE_CHANGE opt_vga.h
VGA_SLOW_IOACCESS opt_vga.h
+VGA_WIDTH90 opt_vga.h
PSM_HOOKAPM opt_psm.h
PSM_RESETAFTERSUSPEND opt_psm.h
PSM_DEBUG opt_psm.h
# Fb options
+FB_DEBUG opt_fb.h
FB_INSTALL_CDEV opt_fb.h
# Atkbd options
diff --git a/sys/conf/options.i386 b/sys/conf/options.i386
index c3aa0d9..d7cc7b4 100644
--- a/sys/conf/options.i386
+++ b/sys/conf/options.i386
@@ -1,4 +1,4 @@
-# $Id: options.i386,v 1.116 1999/06/06 22:45:04 steve Exp $
+# $Id: options.i386,v 1.117 1999/06/15 13:14:43 des Exp $
DISABLE_PSE
IDE_DELAY
@@ -65,17 +65,30 @@ I586_CPU opt_global.h
I686_CPU opt_global.h
MAXCONS opt_syscons.h
-STD8X16FONT opt_syscons.h
-SC_HISTORY_SIZE opt_syscons.h
+SC_ALT_MOUSE_IMAGE opt_syscons.h
+SC_DEBUG_LEVEL opt_syscons.h
+SC_DFLT_FONT opt_syscons.h
+SC_DISABLE_DDBKEY opt_syscons.h
SC_DISABLE_REBOOT opt_syscons.h
+SC_HISTORY_SIZE opt_syscons.h
SC_MOUSE_CHAR opt_syscons.h
-
+SC_NO_CUTPASTE opt_syscons.h
+SC_NO_FONT_LOADING opt_syscons.h
+SC_NO_HISTORY opt_syscons.h
+SC_NO_SYSMOUSE opt_syscons.h
+SC_PIXEL_MODE opt_syscons.h
+SC_RENDER_DEBUG opt_syscons.h
+SC_VIDEO_DEBUG opt_syscons.h
+
+FB_DEBUG opt_fb.h
FB_INSTALL_CDEV opt_fb.h
VGA_ALT_SEQACCESS opt_vga.h
+VGA_DEBUG opt_vga.h
VGA_NO_FONT_LOADING opt_vga.h
VGA_NO_MODE_CHANGE opt_vga.h
VGA_SLOW_IOACCESS opt_vga.h
+VGA_WIDTH90 opt_vga.h
VESA opt_vesa.h
VESA_DEBUG opt_vesa.h
diff --git a/sys/dev/fb/fb.c b/sys/dev/fb/fb.c
index a1d5f11..e10b75b 100644
--- a/sys/dev/fb/fb.c
+++ b/sys/dev/fb/fb.c
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: fb.c,v 1.4 1999/05/30 16:51:23 phk Exp $
+ * $Id: fb.c,v 1.5 1999/05/31 11:24:38 phk Exp $
*/
#include "fb.h"
@@ -34,10 +34,14 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/conf.h>
+#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
+#include <sys/uio.h>
+#include <sys/fbio.h>
-#include <machine/console.h>
+#include <vm/vm.h>
+#include <vm/pmap.h>
#include <dev/fb/fbreg.h>
@@ -49,6 +53,7 @@
* when necessary.
*/
+static int vid_malloc;
static int adapters = 1;
static video_adapter_t *adp_ini;
static video_adapter_t **adapter = &adp_ini;
@@ -56,48 +61,69 @@ static video_switch_t *vidsw_ini;
video_switch_t **vidsw = &vidsw_ini;
#ifdef FB_INSTALL_CDEV
-
-#define ARRAY_DELTA 4
-
static struct cdevsw *vidcdevsw_ini;
static struct cdevsw **vidcdevsw = &vidcdevsw_ini;
+#endif
-static void
+#define ARRAY_DELTA 4
+
+static int
vid_realloc_array(void)
{
video_adapter_t **new_adp;
video_switch_t **new_vidsw;
+#ifdef FB_INSTALL_CDEV
struct cdevsw **new_cdevsw;
+#endif
int newsize;
int s;
+ if (!vid_malloc)
+ return ENOMEM;
+
s = spltty();
newsize = ((adapters + ARRAY_DELTA)/ARRAY_DELTA)*ARRAY_DELTA;
new_adp = malloc(sizeof(*new_adp)*newsize, M_DEVBUF, M_WAITOK);
new_vidsw = malloc(sizeof(*new_vidsw)*newsize, M_DEVBUF, M_WAITOK);
+#ifdef FB_INSTALL_CDEV
new_cdevsw = malloc(sizeof(*new_cdevsw)*newsize, M_DEVBUF, M_WAITOK);
+#endif
bzero(new_adp, sizeof(*new_adp)*newsize);
bzero(new_vidsw, sizeof(*new_vidsw)*newsize);
- bzero(new_cdevsw, sizeof(*new_cdevsw)*newsize);
bcopy(adapter, new_adp, sizeof(*adapter)*adapters);
bcopy(vidsw, new_vidsw, sizeof(*vidsw)*adapters);
+#ifdef FB_INSTALL_CDEV
+ bzero(new_cdevsw, sizeof(*new_cdevsw)*newsize);
bcopy(vidcdevsw, new_cdevsw, sizeof(*vidcdevsw)*adapters);
+#endif
if (adapters > 1) {
free(adapter, M_DEVBUF);
free(vidsw, M_DEVBUF);
+#ifdef FB_INSTALL_CDEV
free(vidcdevsw, M_DEVBUF);
+#endif
}
adapter = new_adp;
vidsw = new_vidsw;
+#ifdef FB_INSTALL_CDEV
vidcdevsw = new_cdevsw;
+#endif
adapters = newsize;
splx(s);
if (bootverbose)
printf("fb: new array size %d\n", adapters);
+
+ return 0;
}
-#endif /* FB_INSTALL_CDEV */
+static void
+vid_malloc_init(void *arg)
+{
+ vid_malloc = TRUE;
+}
+
+SYSINIT(vid_mem, SI_SUB_KMEM, SI_ORDER_ANY, vid_malloc_init, NULL);
/*
* Low-level frame buffer driver functions
@@ -120,20 +146,22 @@ vid_init_struct(video_adapter_t *adp, char *name, int type, int unit)
int
vid_register(video_adapter_t *adp)
{
- video_driver_t **list;
- video_driver_t *p;
+ const video_driver_t **list;
+ const video_driver_t *p;
int index;
for (index = 0; index < adapters; ++index) {
if (adapter[index] == NULL)
break;
}
- if (index >= adapters)
- return -1;
+ if (index >= adapters) {
+ if (vid_realloc_array())
+ return -1;
+ }
adp->va_index = index;
adp->va_token = NULL;
- list = (video_driver_t **)videodriver_set.ls_items;
+ list = (const video_driver_t **)videodriver_set.ls_items;
while ((p = *list++) != NULL) {
if (strcmp(p->name, adp->va_name) == 0) {
adapter[index] = adp;
@@ -162,10 +190,10 @@ vid_unregister(video_adapter_t *adp)
video_switch_t
*vid_get_switch(char *name)
{
- video_driver_t **list;
- video_driver_t *p;
+ const video_driver_t **list;
+ const video_driver_t *p;
- list = (video_driver_t **)videodriver_set.ls_items;
+ list = (const video_driver_t **)videodriver_set.ls_items;
while ((p = *list++) != NULL) {
if (strcmp(p->name, name) == 0)
return p->vidsw;
@@ -251,10 +279,10 @@ video_adapter_t
int
vid_configure(int flags)
{
- video_driver_t **list;
- video_driver_t *p;
+ const video_driver_t **list;
+ const video_driver_t *p;
- list = (video_driver_t **)videodriver_set.ls_items;
+ list = (const video_driver_t **)videodriver_set.ls_items;
while ((p = *list++) != NULL) {
if (p->configure != NULL)
(*p->configure)(flags);
@@ -269,27 +297,73 @@ vid_configure(int flags)
* appropriate subdrivers.
*/
-#define DRIVER_NAME "fb"
+#define FB_DRIVER_NAME "fb"
#ifdef FB_INSTALL_CDEV
+#if experimental
+
+static devclass_t fb_devclass;
+
+static int fbprobe(device_t dev);
+static int fbattach(device_t dev);
+
+static device_method_t fb_methods[] = {
+ DEVMETHOD(device_probe, fbprobe),
+ DEVMETHOD(device_attach, fbattach),
+
+ DEVMETHOD(bus_print_child, bus_generic_print_child),
+ { 0, 0 }
+};
+
+static driver_t fb_driver = {
+ FB_DRIVER_NAME,
+ fb_methods,
+ 0,
+};
+
+static int
+fbprobe(device_t dev)
+{
+ int unit;
+
+ unit = device_get_unit(dev);
+ if (unit >= adapters)
+ return ENXIO;
+ if (adapter[unit] == NULL)
+ return ENXIO;
+
+ device_set_desc(dev, "generic frame buffer");
+ return 0;
+}
+
+static int
+fbattach(device_t dev)
+{
+ printf("fbattach: about to attach children\n");
+ bus_generic_attach(dev);
+ return 0;
+}
+
+#endif /* experimental */
+
#define FB_UNIT(dev) minor(dev)
#define FB_MKMINOR(unit) (u)
-#if notyet
-
static d_open_t fbopen;
static d_close_t fbclose;
+static d_read_t fbread;
+static d_write_t fbwrite;
static d_ioctl_t fbioctl;
static d_mmap_t fbmmap;
-#define CDEV_MAJOR 141 /* XXX */
+#define CDEV_MAJOR 123 /* XXX */
static struct cdevsw fb_cdevsw = {
/* open */ fbopen,
/* close */ fbclose,
- /* read */ noread,
- /* write */ nowrite,
+ /* read */ fbread,
+ /* write */ fbwrite,
/* ioctl */ fbioctl,
/* stop */ nostop,
/* reset */ noreset,
@@ -297,7 +371,7 @@ static struct cdevsw fb_cdevsw = {
/* poll */ nopoll,
/* mmap */ fbmmap,
/* strategy */ nostrategy,
- /* name */ DRIVER_NAME,
+ /* name */ FB_DRIVER_NAME,
/* parms */ noparms,
/* maj */ CDEV_MAJOR,
/* dump */ nodump,
@@ -320,10 +394,8 @@ vfbattach(void *arg)
PSEUDO_SET(vfbattach, fb);
-#endif /* notyet */
-
int
-fb_attach(dev_t dev, video_adapter *adp, struct cdevsw *cdevsw)
+fb_attach(dev_t dev, video_adapter_t *adp, struct cdevsw *cdevsw)
{
int s;
@@ -339,15 +411,12 @@ fb_attach(dev_t dev, video_adapter *adp, struct cdevsw *cdevsw)
/* XXX: DEVFS? */
- if (adp->va_index + 1 >= adapters)
- vid_realloc_array();
-
printf("fb%d at %s%d\n", adp->va_index, adp->va_name, adp->va_unit);
return 0;
}
int
-fb_detach(dev_t dev, video_adapter *adp, struct cdevsw *cdevsw)
+fb_detach(dev_t dev, video_adapter_t *adp, struct cdevsw *cdevsw)
{
int s;
@@ -364,6 +433,165 @@ fb_detach(dev_t dev, video_adapter *adp, struct cdevsw *cdevsw)
return 0;
}
+static int
+fbopen(dev_t dev, int flag, int mode, struct proc *p)
+{
+ int unit;
+
+ unit = FB_UNIT(dev);
+ if (unit >= adapters)
+ return ENXIO;
+ if (vidcdevsw[unit] == NULL)
+ return ENXIO;
+ return (*vidcdevsw[unit]->d_open)(makedev(0, adapter[unit]->va_minor),
+ flag, mode, p);
+}
+
+static int
+fbclose(dev_t dev, int flag, int mode, struct proc *p)
+{
+ int unit;
+
+ unit = FB_UNIT(dev);
+ if (vidcdevsw[unit] == NULL)
+ return ENXIO;
+ return (*vidcdevsw[unit]->d_close)(makedev(0, adapter[unit]->va_minor),
+ flag, mode, p);
+}
+
+static int
+fbread(dev_t dev, struct uio *uio, int flag)
+{
+ int unit;
+
+ unit = FB_UNIT(dev);
+ if (vidcdevsw[unit] == NULL)
+ return ENXIO;
+ return (*vidcdevsw[unit]->d_read)(makedev(0, adapter[unit]->va_minor),
+ uio, flag);
+}
+
+static int
+fbwrite(dev_t dev, struct uio *uio, int flag)
+{
+ int unit;
+
+ unit = FB_UNIT(dev);
+ if (vidcdevsw[unit] == NULL)
+ return ENXIO;
+ return (*vidcdevsw[unit]->d_write)(makedev(0, adapter[unit]->va_minor),
+ uio, flag);
+}
+
+static int
+fbioctl(dev_t dev, u_long cmd, caddr_t arg, int flag, struct proc *p)
+{
+ int unit;
+
+ unit = FB_UNIT(dev);
+ if (vidcdevsw[unit] == NULL)
+ return ENXIO;
+ return (*vidcdevsw[unit]->d_ioctl)(makedev(0, adapter[unit]->va_minor),
+ cmd, arg, flag, p);
+}
+
+static int
+fbmmap(dev_t dev, vm_offset_t offset, int nprot)
+{
+ int unit;
+
+ unit = FB_UNIT(dev);
+ if (vidcdevsw[unit] == NULL)
+ return ENXIO;
+ return (*vidcdevsw[unit]->d_mmap)(makedev(0, adapter[unit]->va_minor),
+ offset, nprot);
+}
+
+#if experimental
+DEV_DRIVER_MODULE(fb, ???, fb_driver, fb_devclass,
+ CDEV_MAJOR, NOMAJ, fb_cdevsw, 0, 0);
+#endif
+
+/*
+ * Generic frame buffer cdev driver functions
+ * Frame buffer subdrivers may call these functions to implement common
+ * driver functions.
+ */
+
+int genfbopen(genfb_softc_t *sc, video_adapter_t *adp, int flag, int mode,
+ struct proc *p)
+{
+ int s;
+
+ s = spltty();
+ if (!(sc->gfb_flags & FB_OPEN))
+ sc->gfb_flags |= FB_OPEN;
+ splx(s);
+ return 0;
+}
+
+int genfbclose(genfb_softc_t *sc, video_adapter_t *adp, int flag, int mode,
+ struct proc *p)
+{
+ int s;
+
+ s = spltty();
+ sc->gfb_flags &= ~FB_OPEN;
+ splx(s);
+ return 0;
+}
+
+int genfbread(genfb_softc_t *sc, video_adapter_t *adp, struct uio *uio,
+ int flag)
+{
+ int size;
+ int offset;
+ int error;
+ int len;
+
+ error = 0;
+ size = adp->va_buffer_size/adp->va_info.vi_planes;
+ while (uio->uio_resid > 0) {
+ if (uio->uio_offset >= size)
+ break;
+ offset = uio->uio_offset%adp->va_window_size;
+ len = imin(uio->uio_resid, size - uio->uio_offset);
+ len = imin(len, adp->va_window_size - offset);
+ if (len <= 0)
+ break;
+ (*vidsw[adp->va_index]->set_win_org)(adp, uio->uio_offset);
+ error = uiomove((caddr_t)(adp->va_window + offset), len, uio);
+ if (error)
+ break;
+ }
+ return error;
+}
+
+int genfbwrite(genfb_softc_t *sc, video_adapter_t *adp, struct uio *uio,
+ int flag)
+{
+ return ENODEV;
+}
+
+int genfbioctl(genfb_softc_t *sc, video_adapter_t *adp, u_long cmd,
+ caddr_t arg, int flag, struct proc *p)
+{
+ int error;
+
+ if (adp == NULL) /* XXX */
+ return ENXIO;
+ error = (*vidsw[adp->va_index]->ioctl)(adp, cmd, arg);
+ if (error == ENOIOCTL)
+ error = ENODEV;
+ return error;
+}
+
+int genfbmmap(genfb_softc_t *sc, video_adapter_t *adp, vm_offset_t offset,
+ int prot)
+{
+ return (*vidsw[adp->va_index]->mmap)(adp, offset, prot);
+}
+
#endif /* FB_INSTALL_CDEV */
static char
@@ -379,6 +607,7 @@ static char
{ KD_EGA, "EGA" },
{ KD_VGA, "VGA" },
{ KD_PC98, "PC-98x1" },
+ { KD_TGA, "TGA" },
{ -1, "Unknown" },
};
int i;
@@ -389,6 +618,12 @@ static char
return names[i].name;
}
+/*
+ * Generic low-level frame buffer functions
+ * The low-level functions in the frame buffer subdriver may use these
+ * functions.
+ */
+
void
fb_dump_adp_info(char *driver, video_adapter_t *adp, int level)
{
@@ -396,19 +631,19 @@ fb_dump_adp_info(char *driver, video_adapter_t *adp, int level)
return;
printf("%s%d: %s%d, %s, type:%s (%d), flags:0x%x\n",
- DRIVER_NAME, adp->va_index, driver, adp->va_unit, adp->va_name,
+ FB_DRIVER_NAME, adp->va_index, driver, adp->va_unit, adp->va_name,
adapter_name(adp->va_type), adp->va_type, adp->va_flags);
printf("%s%d: port:0x%x-0x%x, crtc:0x%x, mem:0x%x 0x%x\n",
- DRIVER_NAME, adp->va_index,
+ FB_DRIVER_NAME, adp->va_index,
adp->va_io_base, adp->va_io_base + adp->va_io_size - 1,
adp->va_crtc_addr, adp->va_mem_base, adp->va_mem_size);
printf("%s%d: init mode:%d, bios mode:%d, current mode:%d\n",
- DRIVER_NAME, adp->va_index,
+ FB_DRIVER_NAME, adp->va_index,
adp->va_initial_mode, adp->va_initial_bios_mode, adp->va_mode);
- printf("%s%d: window:0x%x size:%dk gran:%dk, buf:0x%x size:%dk\n",
- DRIVER_NAME, adp->va_index,
- adp->va_window, (int)adp->va_window_size/1024,
- (int)adp->va_window_gran/1024, adp->va_buffer,
+ printf("%s%d: window:%p size:%dk gran:%dk, buf:%p size:%dk\n",
+ FB_DRIVER_NAME, adp->va_index,
+ (void *)adp->va_window, (int)adp->va_window_size/1024,
+ (int)adp->va_window_gran/1024, (void *)adp->va_buffer,
(int)adp->va_buffer_size/1024);
}
@@ -432,3 +667,161 @@ fb_dump_mode_info(char *driver, video_adapter_t *adp, video_info_t *info,
info->vi_cwidth, info->vi_cheight);
printf("win:0x%x\n", info->vi_window);
}
+
+int
+fb_type(int adp_type)
+{
+ static struct {
+ int fb_type;
+ int va_type;
+ } types[] = {
+ { FBTYPE_MDA, KD_MONO },
+ { FBTYPE_HERCULES, KD_HERCULES },
+ { FBTYPE_CGA, KD_CGA },
+ { FBTYPE_EGA, KD_EGA },
+ { FBTYPE_VGA, KD_VGA },
+ { FBTYPE_PC98, KD_PC98 },
+ { FBTYPE_TGA, KD_TGA },
+ };
+ int i;
+
+ for (i = 0; i < sizeof(types)/sizeof(types[0]); ++i) {
+ if (types[i].va_type == adp_type)
+ return types[i].fb_type;
+ }
+ return -1;
+}
+
+int
+fb_commonioctl(video_adapter_t *adp, u_long cmd, caddr_t arg)
+{
+ int error;
+ int s;
+
+ /* assert(adp != NULL) */
+
+ error = 0;
+ s = spltty();
+
+ switch (cmd) {
+
+ case FBIO_ADAPTER: /* get video adapter index */
+ *(int *)arg = adp->va_index;
+ break;
+
+ case FBIO_ADPTYPE: /* get video adapter type */
+ *(int *)arg = adp->va_type;
+ break;
+
+ case FBIO_ADPINFO: /* get video adapter info */
+ ((video_adapter_info_t *)arg)->va_index = adp->va_index;
+ ((video_adapter_info_t *)arg)->va_type = adp->va_type;
+ bcopy(adp->va_name, ((video_adapter_info_t *)arg)->va_name,
+ imin(strlen(adp->va_name) + 1,
+ sizeof(((video_adapter_info_t *)arg)->va_name)));
+ ((video_adapter_info_t *)arg)->va_unit = adp->va_unit;
+ ((video_adapter_info_t *)arg)->va_flags = adp->va_flags;
+ ((video_adapter_info_t *)arg)->va_io_base = adp->va_io_base;
+ ((video_adapter_info_t *)arg)->va_io_size = adp->va_io_size;
+ ((video_adapter_info_t *)arg)->va_crtc_addr = adp->va_crtc_addr;
+ ((video_adapter_info_t *)arg)->va_mem_base = adp->va_mem_base;
+ ((video_adapter_info_t *)arg)->va_mem_size = adp->va_mem_size;
+ ((video_adapter_info_t *)arg)->va_window
+ = vtophys(adp->va_window);
+ ((video_adapter_info_t *)arg)->va_window_size
+ = adp->va_window_size;
+ ((video_adapter_info_t *)arg)->va_window_gran
+ = adp->va_window_gran;
+ ((video_adapter_info_t *)arg)->va_window_orig
+ = adp->va_window_orig;
+ ((video_adapter_info_t *)arg)->va_unused0
+ = (adp->va_buffer) ? vtophys(adp->va_buffer) : 0;
+ ((video_adapter_info_t *)arg)->va_buffer_size
+ = adp->va_buffer_size;
+ ((video_adapter_info_t *)arg)->va_mode = adp->va_mode;
+ ((video_adapter_info_t *)arg)->va_initial_mode
+ = adp->va_initial_mode;
+ ((video_adapter_info_t *)arg)->va_initial_bios_mode
+ = adp->va_initial_bios_mode;
+ ((video_adapter_info_t *)arg)->va_line_width
+ = adp->va_line_width;
+ ((video_adapter_info_t *)arg)->va_disp_start.x
+ = adp->va_disp_start.x;
+ ((video_adapter_info_t *)arg)->va_disp_start.y
+ = adp->va_disp_start.y;
+ break;
+
+ case FBIO_MODEINFO: /* get mode information */
+ error = (*vidsw[adp->va_index]->get_info)(adp,
+ ((video_info_t *)arg)->vi_mode,
+ (video_info_t *)arg);
+ if (error)
+ error = ENODEV;
+ break;
+
+ case FBIO_FINDMODE: /* find a matching video mode */
+ error = (*vidsw[adp->va_index]->query_mode)(adp,
+ (video_info_t *)arg);
+ if (error < 0) {
+ error = EINVAL;
+ } else {
+ error = (*vidsw[adp->va_index]->get_info)(adp,
+ error, (video_info_t *)arg);
+ if (error)
+ error = ENODEV; /* shouldn't happen */
+ }
+ break;
+
+ case FBIO_GETMODE: /* get video mode */
+ *(int *)arg = adp->va_mode;
+ break;
+
+ case FBIO_SETMODE: /* set video mode */
+ error = (*vidsw[adp->va_index]->set_mode)(adp, *(int *)arg);
+ if (error)
+ error = ENODEV; /* EINVAL? */
+ break;
+
+ case FBIO_GETWINORG: /* get frame buffer window origin */
+ *(u_int *)arg = adp->va_window_orig;
+ break;
+
+ case FBIO_GETDISPSTART: /* get display start address */
+ ((video_display_start_t *)arg)->x = adp->va_disp_start.x;
+ ((video_display_start_t *)arg)->y = adp->va_disp_start.y;
+ break;
+
+ case FBIO_GETLINEWIDTH: /* get scan line width in bytes */
+ *(u_int *)arg = adp->va_line_width;
+ break;
+
+ case FBIO_GETPALETTE: /* get color palette */
+ case FBIO_SETPALETTE: /* set color palette */
+ /* XXX */
+
+ case FBIOPUTCMAP:
+ case FBIOGETCMAP:
+ /* XXX */
+
+ case FBIO_SETWINORG: /* set frame buffer window origin */
+ case FBIO_SETDISPSTART: /* set display start address */
+ case FBIO_SETLINEWIDTH: /* set scan line width in pixel */
+
+ case FBIOGTYPE:
+ case FBIOGATTR:
+ case FBIOSVIDEO:
+ case FBIOGVIDEO:
+ case FBIOSCURSOR:
+ case FBIOGCURSOR:
+ case FBIOSCURPOS:
+ case FBIOGCURPOS:
+ case FBIOGCURMAX:
+
+ default:
+ error = ENODEV;
+ break;
+ }
+
+ splx(s);
+ return error;
+}
diff --git a/sys/dev/fb/fbreg.h b/sys/dev/fb/fbreg.h
index 561ac57..ff13bd8 100644
--- a/sys/dev/fb/fbreg.h
+++ b/sys/dev/fb/fbreg.h
@@ -23,7 +23,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: fbreg.h,v 1.2 1999/01/19 11:31:11 yokota Exp $
+ * $Id: fbreg.h,v 1.3 1999/04/12 13:34:56 des Exp $
*/
#ifndef _DEV_FB_FBREG_H_
@@ -35,15 +35,22 @@
/* some macros */
#ifdef __i386__
-#define bcopy_toio(s, d, c) generic_bcopy((void *)(s), (void *)(d), c)
-#define bcopy_fromio(s, d, c) generic_bcopy((void *)(s), (void *)(d), c)
-#define bzero_io(d, c) generic_bzero((void *)(d), c)
+#define bcopy_io(s, d, c) generic_bcopy((void *)(s), (void *)(d), (c))
+#define bcopy_toio(s, d, c) generic_bcopy((void *)(s), (void *)(d), (c))
+#define bcopy_fromio(s, d, c) generic_bcopy((void *)(s), (void *)(d), (c))
+#define bzero_io(d, c) generic_bzero((void *)(d), (c))
+#define fill_io(p, d, c) fill((p), (void *)(d), (c))
+#define fillw_io(p, d, c) fillw((p), (void *)(d), (c))
void generic_bcopy(const void *s, void *d, size_t c);
void generic_bzero(void *d, size_t c);
#else /* !__i386__ */
-#define bcopy_toio(s, d, c) memcpy_toio(d, s, c)
-#define bcopy_fromio(s, d, c) memcpy_fromio(d, s, c)
-#define bzero_io(d, c) memset_io(d, 0, c)
+#define bcopy_io(s, d, c) memcpy_io((d), (s), (c))
+#define bcopy_toio(s, d, c) memcpy_toio((d), (void *)(s), (c))
+#define bcopy_fromio(s, d, c) memcpy_fromio((void *)(d), (s), (c))
+#define bzero_io(d, c) memset_io((d), 0, (c))
+#define fill_io(p, d, c) memset_io((d), (p), (c))
+#define fillw(p, d, c) memsetw((d), (p), (c))
+#define fillw_io(p, d, c) memsetw_io((d), (p), (c))
#endif /* !__i386__ */
/* video function table */
@@ -68,12 +75,16 @@ typedef int vi_set_hw_cursor_t(video_adapter_t *adp, int col, int row);
typedef int vi_set_hw_cursor_shape_t(video_adapter_t *adp, int base,
int height, int celsize, int blink);
typedef int vi_blank_display_t(video_adapter_t *adp, int mode);
-#define V_DISPLAY_POWER_ON 0
-#define V_DISPLAY_SUSPEND 1
-#define V_DISPLAY_SUSPEND1 1
-#define V_DISPLAY_SUSPEND2 2
-#define V_DISPLAY_POWER_OFF 3
-typedef int vi_mmap_t(video_adapter_t *adp, vm_offset_t offset);
+#define V_DISPLAY_ON 0
+#define V_DISPLAY_BLANK 1
+#define V_DISPLAY_STAND_BY 2
+#define V_DISPLAY_SUSPEND 3
+typedef int vi_mmap_t(video_adapter_t *adp, vm_offset_t offset, int prot);
+typedef int vi_ioctl_t(video_adapter_t *adp, u_long cmd, caddr_t data);
+typedef int vi_clear_t(video_adapter_t *adp);
+typedef int vi_fill_rect_t(video_adapter_t *adp, int val, int x, int y,
+ int cx, int cy);
+typedef int vi_bitblt_t(video_adapter_t *adp,...);
typedef int vi_diag_t(video_adapter_t *adp, int level);
typedef struct video_switch {
@@ -96,6 +107,12 @@ typedef struct video_switch {
vi_set_hw_cursor_shape_t *set_hw_cursor_shape;
vi_blank_display_t *blank_display;
vi_mmap_t *mmap;
+ vi_ioctl_t *ioctl;
+ vi_clear_t *clear;
+ vi_fill_rect_t *fill_rect;
+ vi_bitblt_t *bitblt;
+ int (*reserved1)(void);
+ int (*reserved2)(void);
vi_diag_t *diag;
} video_switch_t;
@@ -158,6 +175,26 @@ int fb_attach(dev_t dev, video_adapter_t *adp,
int fb_detach(dev_t dev, video_adapter_t *adp,
struct cdevsw *cdevsw);
+/* generic frame buffer cdev driver functions */
+
+typedef struct genfb_softc {
+ int gfb_flags; /* flag/status bits */
+#define FB_OPEN (1 << 0)
+} genfb_softc_t;
+
+int genfbopen(genfb_softc_t *sc, video_adapter_t *adp,
+ int flag, int mode, struct proc *p);
+int genfbclose(genfb_softc_t *sc, video_adapter_t *adp,
+ int flag, int mode, struct proc *p);
+int genfbread(genfb_softc_t *sc, video_adapter_t *adp,
+ struct uio *uio, int flag);
+int genfbwrite(genfb_softc_t *sc, video_adapter_t *adp,
+ struct uio *uio, int flag);
+int genfbioctl(genfb_softc_t *sc, video_adapter_t *adp,
+ u_long cmd, caddr_t arg, int flag, struct proc *p);
+int genfbmmap(genfb_softc_t *sc, video_adapter_t *adp,
+ vm_offset_t offset, int prot);
+
#endif /* FB_INSTALL_CDEV */
/* generic low-level driver functions */
@@ -165,6 +202,8 @@ int fb_detach(dev_t dev, video_adapter_t *adp,
void fb_dump_adp_info(char *driver, video_adapter_t *adp, int level);
void fb_dump_mode_info(char *driver, video_adapter_t *adp,
video_info_t *info, int level);
+int fb_type(int adp_type);
+int fb_commonioctl(video_adapter_t *adp, u_long cmd, caddr_t arg);
#endif /* KERNEL */
diff --git a/sys/dev/fb/splash.c b/sys/dev/fb/splash.c
index e8f9cf2..40f1d01 100644
--- a/sys/dev/fb/splash.c
+++ b/sys/dev/fb/splash.c
@@ -35,8 +35,7 @@
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/linker.h>
-
-#include <machine/console.h>
+#include <sys/fbio.h>
#include <dev/fb/fbreg.h>
#include <dev/fb/splashreg.h>
@@ -51,7 +50,8 @@ static splash_decoder_t **decoder_set;
#define DECODER_ARRAY_DELTA 4
/* console driver callback */
-static int (*splash_callback)(int);
+static int (*splash_callback)(int, void *);
+static void *splash_arg;
static int
splash_find_data(splash_decoder_t *decoder)
@@ -98,7 +98,7 @@ splash_new(splash_decoder_t *decoder)
{
splash_decoder = decoder;
if (splash_callback != NULL)
- (*splash_callback)(SPLASH_INIT);
+ (*splash_callback)(SPLASH_INIT, splash_arg);
}
int
@@ -159,12 +159,13 @@ splash_unregister(splash_decoder_t *decoder)
}
int
-splash_init(video_adapter_t *adp, int (*callback)(int))
+splash_init(video_adapter_t *adp, int (*callback)(int, void *), void *arg)
{
int i;
splash_adp = adp;
splash_callback = callback;
+ splash_arg = arg;
splash_decoder = NULL;
for (i = 0; i < decoders; ++i) {
@@ -187,9 +188,11 @@ splash_term(video_adapter_t *adp)
{
int error = 0;
+ if (splash_adp != adp)
+ return EINVAL;
if (splash_decoder != NULL) {
if (splash_callback != NULL)
- error = (*splash_callback)(SPLASH_TERM);
+ error = (*splash_callback)(SPLASH_TERM, splash_arg);
if (error == 0)
error = (*splash_decoder->term)(adp);
if (error == 0)
diff --git a/sys/dev/fb/splash_bmp.c b/sys/dev/fb/splash_bmp.c
index 44ac914..6de5a28 100644
--- a/sys/dev/fb/splash_bmp.c
+++ b/sys/dev/fb/splash_bmp.c
@@ -24,15 +24,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: splash_bmp.c,v 1.7 1999/03/29 15:13:53 yokota Exp $
+ * $Id: splash_bmp.c,v 1.8 1999/06/16 14:04:45 yokota Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/linker.h>
-
-#include <machine/console.h>
+#include <sys/fbio.h>
#include <dev/fb/fbreg.h>
#include <dev/fb/splashreg.h>
diff --git a/sys/dev/fb/splash_pcx.c b/sys/dev/fb/splash_pcx.c
index 3066bb3..5423295 100644
--- a/sys/dev/fb/splash_pcx.c
+++ b/sys/dev/fb/splash_pcx.c
@@ -27,15 +27,14 @@
* (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$
+ * $Id: splash_pcx.c,v 1.1 1999/04/12 13:39:11 des Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/linker.h>
-
-#include <machine/console.h>
+#include <sys/fbio.h>
#include <dev/fb/fbreg.h>
#include <dev/fb/splashreg.h>
diff --git a/sys/dev/fb/splashreg.h b/sys/dev/fb/splashreg.h
index fb78534..a34a3b9 100644
--- a/sys/dev/fb/splashreg.h
+++ b/sys/dev/fb/splashreg.h
@@ -23,7 +23,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: splashreg.h,v 1.1 1999/01/09 02:44:49 yokota Exp $
+ * $Id: splashreg.h,v 1.2 1999/01/11 03:06:28 yokota Exp $
*/
#ifndef _DEV_FB_SPLASHREG_H_
@@ -91,7 +91,8 @@ int splash_register(splash_decoder_t *decoder);
int splash_unregister(splash_decoder_t *decoder);
/* entry points for the console driver */
-int splash_init(video_adapter_t *adp, int (*callback)(int));
+int splash_init(video_adapter_t *adp, int (*callback)(int, void *),
+ void *arg);
int splash_term(video_adapter_t *adp);
int splash(video_adapter_t *adp, int on);
diff --git a/sys/dev/fb/vga.c b/sys/dev/fb/vga.c
new file mode 100644
index 0000000..91f99e9
--- /dev/null
+++ b/sys/dev/fb/vga.c
@@ -0,0 +1,3041 @@
+/*-
+ * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
+ * 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 as
+ * the first lines of this file unmodified.
+ * 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 AUTHORS ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: $
+ */
+
+#include "vga.h"
+#include "opt_vga.h"
+#include "opt_fb.h"
+#include "opt_syscons.h" /* should be removed in the future, XXX */
+
+#if NVGA > 0
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/conf.h>
+#include <sys/proc.h>
+#include <sys/fcntl.h>
+#include <sys/malloc.h>
+#include <sys/fbio.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/pmap.h>
+
+#include <machine/md_var.h>
+#include <machine/pc/bios.h>
+
+#include <dev/fb/fbreg.h>
+#include <dev/fb/vgareg.h>
+
+#include <isa/isareg.h>
+
+#ifndef VGA_DEBUG
+#define VGA_DEBUG 0
+#endif
+
+int
+vga_probe_unit(int unit, video_adapter_t *buf, int flags)
+{
+ video_adapter_t *adp;
+ video_switch_t *sw;
+ int error;
+
+ sw = vid_get_switch(VGA_DRIVER_NAME);
+ if (sw == NULL)
+ return 0;
+ error = (*sw->probe)(unit, &adp, NULL, flags);
+ if (error)
+ return error;
+ bcopy(adp, buf, sizeof(*buf));
+ return 0;
+}
+
+int
+vga_attach_unit(int unit, vga_softc_t *sc, int flags)
+{
+ video_switch_t *sw;
+ int error;
+
+ sw = vid_get_switch(VGA_DRIVER_NAME);
+ if (sw == NULL)
+ return ENXIO;
+
+ error = (*sw->probe)(unit, &sc->adp, NULL, flags);
+ if (error)
+ return error;
+ return (*sw->init)(unit, sc->adp, flags);
+}
+
+/* cdev driver functions */
+
+#ifdef FB_INSTALL_CDEV
+
+int
+vga_open(dev_t dev, vga_softc_t *sc, int flag, int mode, struct proc *p)
+{
+ if (sc == NULL)
+ return ENXIO;
+ if (mode & (O_CREAT | O_APPEND | O_TRUNC))
+ return ENODEV;
+
+ return genfbopen(&sc->gensc, sc->adp, flag, mode, p);
+}
+
+int
+vga_close(dev_t dev, vga_softc_t *sc, int flag, int mode, struct proc *p)
+{
+ return genfbclose(&sc->gensc, sc->adp, flag, mode, p);
+}
+
+int
+vga_read(dev_t dev, vga_softc_t *sc, struct uio *uio, int flag)
+{
+ return genfbread(&sc->gensc, sc->adp, uio, flag);
+}
+
+int
+vga_write(dev_t dev, vga_softc_t *sc, struct uio *uio, int flag)
+{
+ return genfbread(&sc->gensc, sc->adp, uio, flag);
+}
+
+int
+vga_ioctl(dev_t dev, vga_softc_t *sc, u_long cmd, caddr_t arg, int flag,
+ struct proc *p)
+{
+ return genfbioctl(&sc->gensc, sc->adp, cmd, arg, flag, p);
+}
+
+int
+vga_mmap(dev_t dev, vga_softc_t *sc, vm_offset_t offset, int prot)
+{
+ return genfbmmap(&sc->gensc, sc->adp, offset, prot);
+}
+
+#endif /* FB_INSTALL_CDEV */
+
+/* LOW-LEVEL */
+
+#include <machine/clock.h>
+#include <machine/pc/vesa.h>
+
+#define probe_done(adp) ((adp)->va_flags & V_ADP_PROBED)
+#define init_done(adp) ((adp)->va_flags & V_ADP_INITIALIZED)
+#define config_done(adp) ((adp)->va_flags & V_ADP_REGISTERED)
+
+/* for compatibility with old kernel options */
+#ifdef SC_ALT_SEQACCESS
+#undef SC_ALT_SEQACCESS
+#undef VGA_ALT_SEQACCESS
+#define VGA_ALT_SEQACCESS 1
+#endif
+
+#ifdef SLOW_VGA
+#undef SLOW_VGA
+#undef VGA_SLOW_IOACCESS
+#define VGA_SLOW_IOACCESS 1
+#endif
+
+/* architecture dependent option */
+#ifdef __alpha__
+#define VGA_NO_BIOS 1
+#endif
+
+/* this should really be in `rtc.h' */
+#define RTC_EQUIPMENT 0x14
+
+/* various sizes */
+#define V_MODE_MAP_SIZE (M_VGA_CG320 + 1)
+#define V_MODE_PARAM_SIZE 64
+
+/* 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[] = {
+ /* DCC_MONO */
+ { 0, KD_MONO, "mda", 0, 0, 0, IO_MDA, IO_MDASIZE, MONO_CRTC,
+ MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE,
+ 0, 0, 0, 0, 7, 0, },
+ /* DCC_CGA40 */
+ { 0, KD_CGA, "cga", 0, 0, V_ADP_COLOR, IO_CGA, IO_CGASIZE, COLOR_CRTC,
+ CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE,
+ 0, 0, 0, 0, 3, 0, },
+ /* DCC_CGA80 */
+ { 0, KD_CGA, "cga", 0, 0, V_ADP_COLOR, IO_CGA, IO_CGASIZE, COLOR_CRTC,
+ CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE,
+ 0, 0, 0, 0, 3, 0, },
+ /* DCC_EGAMONO */
+ { 0, KD_EGA, "ega", 0, 0, 0, IO_MDA, 48, MONO_CRTC,
+ EGA_BUF_BASE, EGA_BUF_SIZE, MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE,
+ 0, 0, 0, 0, 7, 0, },
+ /* DCC_EGA40 */
+ { 0, KD_EGA, "ega", 0, 0, V_ADP_COLOR, IO_MDA, 48, COLOR_CRTC,
+ EGA_BUF_BASE, EGA_BUF_SIZE, CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE,
+ 0, 0, 0, 0, 3, 0, },
+ /* DCC_EGA80 */
+ { 0, KD_EGA, "ega", 0, 0, V_ADP_COLOR, IO_MDA, 48, COLOR_CRTC,
+ EGA_BUF_BASE, EGA_BUF_SIZE, CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE,
+ 0, 0, 0, 0, 3, 0, },
+};
+
+static video_adapter_t biosadapter[2];
+static int biosadapters = 0;
+
+/* video driver declarations */
+static int vga_configure(int flags);
+ int (*vga_sub_configure)(int flags);
+static int vga_nop(void);
+static int vga_error(void);
+static vi_probe_t vga_probe;
+static vi_init_t vga_init;
+static vi_get_info_t vga_get_info;
+static vi_query_mode_t vga_query_mode;
+static vi_set_mode_t vga_set_mode;
+static vi_save_font_t vga_save_font;
+static vi_load_font_t vga_load_font;
+static vi_show_font_t vga_show_font;
+static vi_save_palette_t vga_save_palette;
+static vi_load_palette_t vga_load_palette;
+static vi_set_border_t vga_set_border;
+static vi_save_state_t vga_save_state;
+static vi_load_state_t vga_load_state;
+static vi_set_win_org_t vga_set_origin;
+static vi_read_hw_cursor_t vga_read_hw_cursor;
+static vi_set_hw_cursor_t vga_set_hw_cursor;
+static vi_set_hw_cursor_shape_t vga_set_hw_cursor_shape;
+static vi_blank_display_t vga_blank_display;
+static vi_mmap_t vga_mmap_buf;
+static vi_ioctl_t vga_dev_ioctl;
+#ifndef VGA_NO_MODE_CHANGE
+static vi_clear_t vga_clear;
+static vi_fill_rect_t vga_fill_rect;
+static vi_bitblt_t vga_bitblt;
+#else /* VGA_NO_MODE_CHANGE */
+#define vga_clear (vi_clear_t *)vga_error
+#define vga_fill_rect (vi_fill_rect_t *)vga_error
+#define vga_bitblt (vi_bitblt_t *)vga_error
+#endif
+static vi_diag_t vga_diag;
+
+static video_switch_t vgavidsw = {
+ vga_probe,
+ vga_init,
+ vga_get_info,
+ vga_query_mode,
+ vga_set_mode,
+ vga_save_font,
+ vga_load_font,
+ vga_show_font,
+ vga_save_palette,
+ vga_load_palette,
+ vga_set_border,
+ vga_save_state,
+ vga_load_state,
+ vga_set_origin,
+ vga_read_hw_cursor,
+ vga_set_hw_cursor,
+ vga_set_hw_cursor_shape,
+ vga_blank_display,
+ vga_mmap_buf,
+ vga_dev_ioctl,
+ vga_clear,
+ vga_fill_rect,
+ vga_bitblt,
+ vga_error,
+ vga_error,
+ vga_diag,
+};
+
+VIDEO_DRIVER(mda, vgavidsw, NULL);
+VIDEO_DRIVER(cga, vgavidsw, NULL);
+VIDEO_DRIVER(ega, vgavidsw, NULL);
+VIDEO_DRIVER(vga, vgavidsw, vga_configure);
+
+/* 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,
+ CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT },
+ { M_C40x25, V_INFO_COLOR, 40, 25, 8, 8, 4, 1,
+ CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT },
+ { M_B80x25, V_INFO_COLOR, 80, 25, 8, 8, 2, 1,
+ CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT },
+ { M_C80x25, V_INFO_COLOR, 80, 25, 8, 8, 4, 1,
+ CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT },
+ /* EGA */
+ { M_ENH_B40x25, V_INFO_COLOR, 40, 25, 8, 14, 2, 1,
+ CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT },
+ { M_ENH_C40x25, V_INFO_COLOR, 40, 25, 8, 14, 4, 1,
+ CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT },
+ { M_ENH_B80x25, V_INFO_COLOR, 80, 25, 8, 14, 2, 1,
+ CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT },
+ { M_ENH_C80x25, V_INFO_COLOR, 80, 25, 8, 14, 4, 1,
+ CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT },
+ /* VGA */
+ { M_VGA_C40x25, V_INFO_COLOR, 40, 25, 8, 16, 4, 1,
+ CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT },
+ { M_VGA_M80x25, 0, 80, 25, 8, 16, 2, 1,
+ MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT },
+ { M_VGA_C80x25, V_INFO_COLOR, 80, 25, 8, 16, 4, 1,
+ CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT },
+ /* MDA */
+ { M_EGAMONO80x25, 0, 80, 25, 8, 14, 2, 1,
+ MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT },
+ /* EGA */
+ { M_ENH_B80x43, 0, 80, 43, 8, 8, 2, 1,
+ CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT },
+ { M_ENH_C80x43, V_INFO_COLOR, 80, 43, 8, 8, 4, 1,
+ CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT },
+ /* VGA */
+ { M_VGA_M80x30, 0, 80, 30, 8, 16, 2, 1,
+ MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT },
+ { M_VGA_C80x30, V_INFO_COLOR, 80, 30, 8, 16, 4, 1,
+ CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT },
+ { M_VGA_M80x50, 0, 80, 50, 8, 8, 2, 1,
+ MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT },
+ { M_VGA_C80x50, V_INFO_COLOR, 80, 50, 8, 8, 4, 1,
+ CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT },
+ { M_VGA_M80x60, 0, 80, 60, 8, 8, 2, 1,
+ MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT },
+ { M_VGA_C80x60, V_INFO_COLOR, 80, 60, 8, 8, 4, 1,
+ CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT },
+
+#ifndef VGA_NO_MODE_CHANGE
+
+#ifdef VGA_WIDTH90
+ { M_VGA_M90x25, 0, 90, 25, 8, 16, 2, 1,
+ MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT },
+ { M_VGA_C90x25, V_INFO_COLOR, 90, 25, 8, 16, 4, 1,
+ CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT },
+ { M_VGA_M90x30, 0, 90, 30, 8, 16, 2, 1,
+ MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT },
+ { M_VGA_C90x30, V_INFO_COLOR, 90, 30, 8, 16, 4, 1,
+ CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT },
+ { M_VGA_M90x43, 0, 90, 43, 8, 8, 2, 1,
+ CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT },
+ { M_VGA_C90x43, V_INFO_COLOR, 90, 43, 8, 8, 4, 1,
+ CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT },
+ { M_VGA_M90x50, 0, 90, 50, 8, 8, 2, 1,
+ MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT },
+ { M_VGA_C90x50, V_INFO_COLOR, 90, 50, 8, 8, 4, 1,
+ CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT },
+ { M_VGA_M90x60, 0, 90, 60, 8, 8, 2, 1,
+ MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT },
+ { M_VGA_C90x60, V_INFO_COLOR, 90, 60, 8, 8, 4, 1,
+ CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT },
+#endif /* VGA_WIDTH90 */
+
+ /* CGA */
+ { M_BG320, V_INFO_COLOR | V_INFO_GRAPHICS, 320, 200, 8, 8, 2, 1,
+ CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_CGA },
+ { M_CG320, V_INFO_COLOR | V_INFO_GRAPHICS, 320, 200, 8, 8, 2, 1,
+ CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_CGA },
+ { M_BG640, V_INFO_COLOR | V_INFO_GRAPHICS, 640, 200, 8, 8, 1, 1,
+ CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_CGA },
+ /* EGA */
+ { M_CG320_D, V_INFO_COLOR | V_INFO_GRAPHICS, 320, 200, 8, 8, 4, 4,
+ GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0,
+ V_INFO_MM_PLANAR },
+ { M_CG640_E, V_INFO_COLOR | V_INFO_GRAPHICS, 640, 200, 8, 8, 4, 4,
+ GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0 ,
+ V_INFO_MM_PLANAR },
+ { M_EGAMONOAPA, V_INFO_GRAPHICS, 640, 350, 8, 14, 4, 4,
+ GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, 64*1024, 0, 0 ,
+ V_INFO_MM_PLANAR },
+ { M_ENHMONOAPA2,V_INFO_GRAPHICS, 640, 350, 8, 14, 4, 4,
+ GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0 ,
+ V_INFO_MM_PLANAR },
+ { M_CG640x350, V_INFO_COLOR | V_INFO_GRAPHICS, 640, 350, 8, 14, 2, 2,
+ GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0 ,
+ V_INFO_MM_PLANAR },
+ { M_ENH_CG640, V_INFO_COLOR | V_INFO_GRAPHICS, 640, 350, 8, 14, 4, 4,
+ GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0 ,
+ V_INFO_MM_PLANAR },
+ /* VGA */
+ { M_BG640x480, V_INFO_COLOR | V_INFO_GRAPHICS, 640, 480, 8, 16, 4, 4,
+ GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0 ,
+ V_INFO_MM_PLANAR },
+ { M_CG640x480, V_INFO_COLOR | V_INFO_GRAPHICS, 640, 480, 8, 16, 4, 4,
+ GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0 ,
+ V_INFO_MM_PLANAR },
+ { M_VGA_CG320, V_INFO_COLOR | V_INFO_GRAPHICS, 320, 200, 8, 8, 8, 1,
+ GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0,
+ V_INFO_MM_PACKED, 1 },
+ { M_VGA_MODEX, V_INFO_COLOR | V_INFO_GRAPHICS, 320, 240, 8, 8, 8, 1,
+ GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0,
+ V_INFO_MM_PACKED, 1 },
+#endif /* VGA_NO_MODE_CHANGE */
+
+ { EOT },
+};
+
+static int vga_init_done = FALSE;
+#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE)
+static u_char *video_mode_ptr = NULL; /* EGA/VGA */
+static u_char *video_mode_ptr2 = NULL; /* CGA/MDA */
+#endif
+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))
+
+#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE)
+static void map_mode_table(u_char *map[], u_char *table, int max);
+#endif
+static void clear_mode_map(video_adapter_t *adp, u_char *map[], int max,
+ int color);
+#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE)
+static int map_mode_num(int mode);
+#endif
+static int map_gen_mode_num(int type, int color, int mode);
+static int map_bios_mode_num(int type, int color, int bios_mode);
+static u_char *get_mode_param(int mode);
+#ifndef VGA_NO_BIOS
+static void fill_adapter_param(int code, video_adapter_t *adp);
+#endif
+static int verify_adapter(video_adapter_t *adp);
+static void update_adapter_info(video_adapter_t *adp, video_info_t *info);
+#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE)
+#define COMP_IDENTICAL 0
+#define COMP_SIMILAR 1
+#define COMP_DIFFERENT 2
+static int comp_adpregs(u_char *buf1, u_char *buf2);
+#endif
+static int probe_adapters(void);
+static int set_line_length(video_adapter_t *adp, int pixel);
+static int set_display_start(video_adapter_t *adp, int x, int y);
+static void filll_io(int val, vm_offset_t d, size_t size);
+
+#ifndef VGA_NO_MODE_CHANGE
+#ifdef VGA_WIDTH90
+static void set_width90(adp_state_t *params);
+#endif
+#endif /* !VGA_NO_MODE_CHANGE */
+
+#ifndef VGA_NO_FONT_LOADING
+#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);
+#endif
+
+#ifndef VGA_NO_MODE_CHANGE
+static void planar_fill(video_adapter_t *adp, int val);
+static void packed_fill(video_adapter_t *adp, int val);
+static void direct_fill(video_adapter_t *adp, int val);
+#ifdef notyet
+static void planar_fill_rect(video_adapter_t *adp, int val, int x, int y,
+ int cx, int cy);
+static void packed_fill_rect(video_adapter_t *adp, int val, int x, int y,
+ int cx, int cy);
+static void direct_fill_rect16(video_adapter_t *adp, int val, int x, int y,
+ int cx, int cy);
+static void direct_fill_rect24(video_adapter_t *adp, int val, int x, int y,
+ int cx, int cy);
+static void direct_fill_rect32(video_adapter_t *adp, int val, int x, int y,
+ int cx, int cy);
+#endif /* notyet */
+#endif /* !VGA_NO_MODE_CHANGE */
+
+static void dump_buffer(u_char *buf, size_t len);
+
+#define ISMAPPED(pa, width) \
+ (((pa) <= (u_long)0x1000 - (width)) \
+ || ((pa) >= ISA_HOLE_START && (pa) <= 0x100000 - (width)))
+
+#define prologue(adp, flag, err) \
+ if (!vga_init_done || !((adp)->va_flags & (flag))) \
+ return (err)
+
+/* a backdoor for the console driver */
+static int
+vga_configure(int flags)
+{
+ int i;
+
+ probe_adapters();
+ for (i = 0; i < biosadapters; ++i) {
+ if (!probe_done(&biosadapter[i]))
+ continue;
+ biosadapter[i].va_flags |= V_ADP_INITIALIZED;
+ if (!config_done(&biosadapter[i])) {
+ if (vid_register(&biosadapter[i]) < 0)
+ continue;
+ biosadapter[i].va_flags |= V_ADP_REGISTERED;
+ }
+ }
+ if (vga_sub_configure != NULL)
+ (*vga_sub_configure)(flags);
+
+ return biosadapters;
+}
+
+/* local subroutines */
+
+#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE)
+/* 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;
+}
+#endif /* !VGA_NO_BIOS && !VGA_NO_MODE_CHANGE */
+
+static void
+clear_mode_map(video_adapter_t *adp, 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 (vga_get_info(adp, i, &info))
+ continue;
+ if ((info.vi_flags & V_INFO_COLOR) != color)
+ map[i] = NULL;
+ }
+}
+
+#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE)
+/* map the non-standard video mode to a known mode number */
+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 },
+#ifdef VGA_WIDTH90
+ { M_VGA_M90x25, M_VGA_M80x25 },
+ { M_VGA_C90x25, M_VGA_C80x25 },
+ { M_VGA_M90x30, M_VGA_M80x25 },
+ { M_VGA_C90x30, M_VGA_C80x25 },
+ { M_VGA_M90x43, M_ENH_B80x25 },
+ { M_VGA_C90x43, M_ENH_C80x25 },
+ { M_VGA_M90x50, M_VGA_M80x25 },
+ { M_VGA_C90x50, M_VGA_C80x25 },
+ { M_VGA_M90x60, M_VGA_M80x25 },
+ { M_VGA_C90x60, M_VGA_C80x25 },
+#endif
+ { 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;
+}
+#endif /* !VGA_NO_BIOS && !VGA_NO_MODE_CHANGE */
+
+/* map a generic video mode to a known mode number */
+static int
+map_gen_mode_num(int type, int color, int mode)
+{
+ static struct {
+ int from;
+ int to_color;
+ int to_mono;
+ } mode_map[] = {
+ { M_TEXT_80x30, M_VGA_C80x30, M_VGA_M80x30, },
+ { M_TEXT_80x43, M_ENH_C80x43, M_ENH_B80x43, },
+ { M_TEXT_80x50, M_VGA_C80x50, M_VGA_M80x50, },
+ { M_TEXT_80x60, M_VGA_C80x60, M_VGA_M80x60, },
+ };
+ int i;
+
+ if (mode == M_TEXT_80x25) {
+ switch (type) {
+
+ case KD_VGA:
+ if (color)
+ return M_VGA_C80x25;
+ else
+ return M_VGA_M80x25;
+ break;
+
+ case KD_EGA:
+ if (color)
+ return M_ENH_C80x25;
+ else
+ return M_EGAMONO80x25;
+ break;
+
+ case KD_CGA:
+ return M_C80x25;
+
+ case KD_MONO:
+ case KD_HERCULES:
+ return M_EGAMONO80x25; /* XXX: this name is confusing */
+
+ default:
+ return -1;
+ }
+ }
+
+ for (i = 0; i < sizeof(mode_map)/sizeof(mode_map[0]); ++i) {
+ if (mode_map[i].from == mode)
+ return ((color) ? mode_map[i].to_color : mode_map[i].to_mono);
+ }
+ 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 !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE)
+ if (mode >= V_MODE_MAP_SIZE)
+ mode = map_mode_num(mode);
+#endif
+ if ((mode >= 0) && (mode < V_MODE_MAP_SIZE))
+ return mode_map[mode];
+ else
+ return NULL;
+}
+
+#ifndef VGA_NO_BIOS
+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];
+ }
+}
+#endif /* VGA_NO_BIOS */
+
+static int
+verify_adapter(video_adapter_t *adp)
+{
+ vm_offset_t buf;
+ u_int16_t v;
+#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE)
+ u_int32_t p;
+#endif
+
+ buf = BIOS_PADDRTOVADDR(adp->va_window);
+ v = readw(buf);
+ writew(buf, 0xA55A);
+ if (readw(buf) != 0xA55A)
+ return ENXIO;
+ 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_name = "vga";
+ adp->va_flags |= V_ADP_STATESAVE | V_ADP_PALETTE;
+ }
+ adp->va_flags |= V_ADP_STATELOAD | V_ADP_BORDER;
+ /* the color adapter may be in the 40x25 mode... XXX */
+
+#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE)
+ /* 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 */
+#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE)
+ /* get the BIOS video mode pointer */
+ p = *(u_int32_t *)BIOS_PADDRTOVADDR(0x1d*4);
+ p = BIOS_SADDRTOLADDR(p);
+ video_mode_ptr2 = (u_char *)BIOS_PADDRTOVADDR(p);
+#endif
+ break;
+
+ case KD_MONO:
+#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE)
+ /* get the BIOS video mode pointer */
+ p = *(u_int32_t *)BIOS_PADDRTOVADDR(0x1d*4);
+ p = BIOS_SADDRTOLADDR(p);
+ video_mode_ptr2 = (u_char *)BIOS_PADDRTOVADDR(p);
+#endif
+ break;
+ }
+
+ return 0;
+}
+
+static void
+update_adapter_info(video_adapter_t *adp, video_info_t *info)
+{
+ adp->va_flags &= ~V_ADP_COLOR;
+ adp->va_flags |=
+ (info->vi_flags & V_INFO_COLOR) ? V_ADP_COLOR : 0;
+ adp->va_crtc_addr =
+ (adp->va_flags & V_ADP_COLOR) ? COLOR_CRTC : MONO_CRTC;
+ adp->va_window = BIOS_PADDRTOVADDR(info->vi_window);
+ adp->va_window_size = info->vi_window_size;
+ adp->va_window_gran = info->vi_window_gran;
+ adp->va_window_orig = 0;
+ /* XXX */
+ adp->va_buffer = info->vi_buffer;
+ adp->va_buffer_size = info->vi_buffer_size;
+ if (info->vi_flags & V_INFO_GRAPHICS) {
+ switch (info->vi_depth/info->vi_planes) {
+ case 1:
+ adp->va_line_width = info->vi_width/8;
+ break;
+ case 2:
+ adp->va_line_width = info->vi_width/4;
+ break;
+ case 4:
+ adp->va_line_width = info->vi_width/2;
+ break;
+ case 8:
+ default: /* shouldn't happen */
+ adp->va_line_width = info->vi_width;
+ break;
+ }
+ } else {
+ adp->va_line_width = info->vi_width;
+ }
+ adp->va_disp_start.x = 0;
+ adp->va_disp_start.y = 0;
+ bcopy(info, &adp->va_info, sizeof(adp->va_info));
+}
+
+#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE)
+/* 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 regs */
+ {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;
+}
+#endif /* !VGA_NO_BIOS && !VGA_NO_MODE_CHANGE */
+
+/* probe video adapters and return the number of detected adapters */
+static int
+probe_adapters(void)
+{
+ video_adapter_t *adp;
+ video_info_t info;
+#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE)
+ u_char *mp;
+#endif
+ int i;
+
+ /* do this test only once */
+ if (vga_init_done)
+ return biosadapters;
+ vga_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 data area.
+ * XXX: we don't use BIOSDATA_EQUIPMENT, since it is not a dead
+ * copy of RTC_EQUIPMENT. Bits 4 and 5 of ETC_EQUIPMENT are
+ * zeros for EGA and VGA. However, the EGA/VGA BIOS sets
+ * these bits in BIOSDATA_EQUIPMENT according to the monitor
+ * type detected.
+ */
+#ifndef VGA_NO_BIOS
+ switch ((rtcin(RTC_EQUIPMENT) >> 4) & 3) { /* bit 4 and 5 */
+ case 0:
+ /* EGA/VGA */
+ fill_adapter_param(readb(BIOS_PADDRTOVADDR(0x488)) & 0x0f,
+ biosadapter);
+ break;
+ case 1:
+ /* CGA 40x25 */
+ /* FIXME: switch to the 80x25 mode? XXX */
+ biosadapter[V_ADP_PRIMARY] = adapter_init_value[DCC_CGA40];
+ biosadapter[V_ADP_SECONDARY] = adapter_init_value[DCC_MONO];
+ break;
+ case 2:
+ /* CGA 80x25 */
+ biosadapter[V_ADP_PRIMARY] = adapter_init_value[DCC_CGA80];
+ biosadapter[V_ADP_SECONDARY] = adapter_init_value[DCC_MONO];
+ break;
+ case 3:
+ /* MDA */
+ biosadapter[V_ADP_PRIMARY] = adapter_init_value[DCC_MONO];
+ biosadapter[V_ADP_SECONDARY] = adapter_init_value[DCC_CGA80];
+ break;
+ }
+#else
+ /* assume EGA/VGA? XXX */
+ biosadapter[V_ADP_PRIMARY] = adapter_init_value[DCC_EGA80];
+ biosadapter[V_ADP_SECONDARY] = adapter_init_value[DCC_MONO];
+#endif /* VGA_NO_BIOS */
+
+ biosadapters = 0;
+ if (verify_adapter(&biosadapter[V_ADP_SECONDARY]) == 0) {
+ ++biosadapters;
+ biosadapter[V_ADP_SECONDARY].va_flags |= V_ADP_PROBED;
+ biosadapter[V_ADP_SECONDARY].va_mode =
+ biosadapter[V_ADP_SECONDARY].va_initial_mode =
+ map_bios_mode_num(biosadapter[V_ADP_SECONDARY].va_type,
+ biosadapter[V_ADP_SECONDARY].va_flags
+ & V_ADP_COLOR,
+ biosadapter[V_ADP_SECONDARY].va_initial_bios_mode);
+ } else {
+ biosadapter[V_ADP_SECONDARY].va_type = -1;
+ }
+ if (verify_adapter(&biosadapter[V_ADP_PRIMARY]) == 0) {
+ ++biosadapters;
+ biosadapter[V_ADP_PRIMARY].va_flags |= V_ADP_PROBED;
+#ifndef VGA_NO_BIOS
+ biosadapter[V_ADP_PRIMARY].va_initial_bios_mode =
+ readb(BIOS_PADDRTOVADDR(0x449));
+#else
+ biosadapter[V_ADP_PRIMARY].va_initial_bios_mode = 3; /* XXX */
+#endif
+ biosadapter[V_ADP_PRIMARY].va_mode =
+ biosadapter[V_ADP_PRIMARY].va_initial_mode =
+ map_bios_mode_num(biosadapter[V_ADP_PRIMARY].va_type,
+ biosadapter[V_ADP_PRIMARY].va_flags & V_ADP_COLOR,
+ biosadapter[V_ADP_PRIMARY].va_initial_bios_mode);
+ } else {
+ biosadapter[V_ADP_PRIMARY] = biosadapter[V_ADP_SECONDARY];
+ biosadapter[V_ADP_SECONDARY].va_type = -1;
+ }
+ if (biosadapters == 0)
+ return biosadapters;
+ biosadapter[V_ADP_PRIMARY].va_unit = V_ADP_PRIMARY;
+ biosadapter[V_ADP_SECONDARY].va_unit = V_ADP_SECONDARY;
+
+#if 0 /* we don't need these... */
+ fb_init_struct(&biosadapter[V_ADP_PRIMARY], ...);
+ fb_init_struct(&biosadapter[V_ADP_SECONDARY], ...);
+#endif
+
+#if notyet
+ /*
+ * 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 (biosadapters > 1) {
+ if (!((biosadapter[0].va_flags ^ biosadapter[1].va_flags)
+ & V_ADP_COLOR))
+ /* we have two mono or color adapters!! */
+ return (biosadapters = 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 vga_save_state() for VGA.
+ */
+ outb(biosadapter[V_ADP_PRIMARY].va_crtc_addr, 12);
+ outb(biosadapter[V_ADP_PRIMARY].va_crtc_addr + 1, 0);
+ outb(biosadapter[V_ADP_PRIMARY].va_crtc_addr, 13);
+ outb(biosadapter[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 ((biosadapter[V_ADP_PRIMARY].va_type == KD_EGA) ||
+ (biosadapter[V_ADP_PRIMARY].va_type == KD_VGA)) {
+ adp = &biosadapter[V_ADP_PRIMARY];
+ } else if ((biosadapter[V_ADP_SECONDARY].va_type == KD_EGA) ||
+ (biosadapter[V_ADP_SECONDARY].va_type == KD_VGA)) {
+ adp = &biosadapter[V_ADP_SECONDARY];
+ } else {
+ adp = NULL;
+ }
+ bzero(mode_map, sizeof(mode_map));
+ if (adp != NULL) {
+ if (adp->va_type == KD_VGA) {
+ vga_save_state(adp, &adpstate, sizeof(adpstate));
+#if defined(VGA_NO_BIOS) || defined(VGA_NO_MODE_CHANGE)
+ mode_map[adp->va_initial_mode] = adpstate.regs;
+ rows_offset = 1;
+#else /* VGA_NO_BIOS || VGA_NO_MODE_CHANGE */
+ if (video_mode_ptr == NULL) {
+ mode_map[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[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[adp->va_initial_mode] = adpstate.regs;
+ rows_offset = 1;
+ break;
+ }
+ }
+#endif /* VGA_NO_BIOS || VGA_NO_MODE_CHANGE */
+
+#ifndef VGA_NO_MODE_CHANGE
+ adp->va_flags |= V_ADP_MODECHANGE;
+#endif
+#ifndef VGA_NO_FONT_LOADING
+ adp->va_flags |= V_ADP_FONT;
+#endif
+ } else if (adp->va_type == KD_EGA) {
+#if defined(VGA_NO_BIOS) || defined(VGA_NO_MODE_CHANGE)
+ rows_offset = 1;
+#else /* VGA_NO_BIOS || VGA_NO_MODE_CHANGE */
+ if (video_mode_ptr == NULL) {
+ 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;
+#ifndef VGA_NO_FONT_LOADING
+ adp->va_flags |= V_ADP_FONT;
+#endif
+ rows_offset = 1;
+ } else {
+ /*
+ * This is serious. We will not be able to switch video
+ * modes at all...
+ */
+ video_mode_ptr = NULL;
+ bzero(mode_map, sizeof(mode_map));
+ rows_offset = 1;
+ }
+ }
+#endif /* VGA_NO_BIOS || VGA_NO_MODE_CHANGE */
+ }
+ }
+
+ /* remove conflicting modes if we have more than one adapter */
+ if (biosadapters > 1) {
+ for (i = 0; i < biosadapters; ++i) {
+ if (!(biosadapter[i].va_flags & V_ADP_MODECHANGE))
+ continue;
+ clear_mode_map(&biosadapter[i], mode_map, M_VGA_CG320 + 1,
+ (biosadapter[i].va_flags & V_ADP_COLOR) ?
+ V_INFO_COLOR : 0);
+ if ((biosadapter[i].va_type == KD_VGA)
+ || (biosadapter[i].va_type == KD_EGA)) {
+ biosadapter[i].va_io_base =
+ (biosadapter[i].va_flags & V_ADP_COLOR) ?
+ IO_VGA : IO_MDA;
+ biosadapter[i].va_io_size = 32;
+ }
+ }
+ }
+
+ /* buffer address */
+ vga_get_info(&biosadapter[V_ADP_PRIMARY],
+ biosadapter[V_ADP_PRIMARY].va_initial_mode, &info);
+ info.vi_flags &= ~V_INFO_LINEAR; /* XXX */
+ update_adapter_info(&biosadapter[V_ADP_PRIMARY], &info);
+
+ if (biosadapters > 1) {
+ vga_get_info(&biosadapter[V_ADP_SECONDARY],
+ biosadapter[V_ADP_SECONDARY].va_initial_mode, &info);
+ info.vi_flags &= ~V_INFO_LINEAR; /* XXX */
+ update_adapter_info(&biosadapter[V_ADP_SECONDARY], &info);
+ }
+
+ /*
+ * 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 biosadapters;
+}
+
+/* set the scan line length in pixel */
+static int
+set_line_length(video_adapter_t *adp, int pixel)
+{
+ u_char *mp;
+ int ppw; /* pixels per word */
+ int bpl; /* bytes per line */
+ int count;
+
+ if ((adp->va_type != KD_VGA) && (adp->va_type != KD_EGA))
+ return ENODEV;
+ mp = get_mode_param(adp->va_mode);
+ if (mp == NULL)
+ return EINVAL;
+
+ switch (adp->va_info.vi_mem_model) {
+ case V_INFO_MM_PLANAR:
+ ppw = 16/(adp->va_info.vi_depth/adp->va_info.vi_planes);
+ count = (pixel + ppw - 1)/ppw/2;
+ bpl = ((pixel + ppw - 1)/ppw/2)*4;
+ break;
+ case V_INFO_MM_PACKED:
+ count = (pixel + 7)/8;
+ bpl = ((pixel + 7)/8)*8;
+ break;
+ case V_INFO_MM_TEXT:
+ count = (pixel + 7)/8; /* columns */
+ bpl = (pixel + 7)/8; /* columns */
+ break;
+ default:
+ return ENODEV;
+ }
+
+ if (mp[10 + 0x17] & 0x40) /* CRTC mode control reg */
+ count *= 2; /* byte mode */
+ outb(adp->va_crtc_addr, 0x13);
+ outb(adp->va_crtc_addr + 1, count);
+ adp->va_line_width = bpl;
+
+ return 0;
+}
+
+static int
+set_display_start(video_adapter_t *adp, int x, int y)
+{
+ int off; /* byte offset (graphics mode)/word offset (text mode) */
+ int poff; /* pixel offset */
+ int roff; /* row offset */
+ int ppb; /* pixels per byte */
+
+ if ((adp->va_type != KD_VGA) && (adp->va_type != KD_EGA))
+ x &= ~7;
+ if (adp->va_info.vi_flags & V_INFO_GRAPHICS) {
+ ppb = 8/(adp->va_info.vi_depth/adp->va_info.vi_planes);
+ off = y*adp->va_line_width + x/ppb;
+ roff = 0;
+ poff = x%ppb;
+ } else {
+ if ((adp->va_type == KD_VGA) || (adp->va_type == KD_EGA)) {
+ outb(TSIDX, 1);
+ if (inb(TSREG) & 1)
+ ppb = 9;
+ else
+ ppb = 8;
+ } else {
+ ppb = 8;
+ }
+ off = y/adp->va_info.vi_cheight*adp->va_line_width + x/ppb;
+ roff = y%adp->va_info.vi_cheight;
+ /* FIXME: is this correct? XXX */
+ if (ppb == 8)
+ poff = x%ppb;
+ else
+ poff = (x + 8)%ppb;
+ }
+
+ /* start address */
+ outb(adp->va_crtc_addr, 0xc); /* high */
+ outb(adp->va_crtc_addr + 1, off >> 8);
+ outb(adp->va_crtc_addr, 0xd); /* low */
+ outb(adp->va_crtc_addr + 1, off & 0xff);
+
+ /* horizontal pel pan */
+ if ((adp->va_type == KD_VGA) || (adp->va_type == KD_EGA)) {
+ inb(adp->va_crtc_addr + 6);
+ outb(ATC, 0x13 | 0x20);
+ outb(ATC, poff);
+ inb(adp->va_crtc_addr + 6);
+ outb(ATC, 0x20);
+ }
+
+ /* preset raw scan */
+ outb(adp->va_crtc_addr, 8);
+ outb(adp->va_crtc_addr + 1, roff);
+
+ adp->va_disp_start.x = x;
+ adp->va_disp_start.y = y;
+ return 0;
+}
+
+#ifdef __i386__ /* XXX */
+static void
+fill(int val, void *d, size_t size)
+{
+ u_char *p = d;
+
+ while (size-- > 0)
+ *p++ = val;
+}
+#endif /* __i386__ */
+
+static void
+filll_io(int val, vm_offset_t d, size_t size)
+{
+ while (size-- > 0) {
+ writel(d, val);
+ d += sizeof(u_int32_t);
+ }
+}
+
+/* entry points */
+
+static int
+vga_nop(void)
+{
+ return 0;
+}
+
+static int
+vga_error(void)
+{
+ return ENODEV;
+}
+
+static int
+vga_probe(int unit, video_adapter_t **adpp, void *arg, int flags)
+{
+ probe_adapters();
+ if (unit >= biosadapters)
+ return ENXIO;
+
+ *adpp = &biosadapter[unit];
+
+ return 0;
+}
+
+static int
+vga_init(int unit, video_adapter_t *adp, int flags)
+{
+ if ((unit >= biosadapters) || (adp == NULL) || !probe_done(adp))
+ return ENXIO;
+
+ if (!init_done(adp)) {
+ /* nothing to do really... */
+ adp->va_flags |= V_ADP_INITIALIZED;
+ }
+
+ if (!config_done(adp)) {
+ if (vid_register(adp) < 0)
+ return ENXIO;
+ adp->va_flags |= V_ADP_REGISTERED;
+ }
+ if (vga_sub_configure != NULL)
+ (*vga_sub_configure)(0);
+
+ return 0;
+}
+
+/*
+ * get_info():
+ * Return the video_info structure of the requested video mode.
+ *
+ * all adapters
+ */
+static int
+vga_get_info(video_adapter_t *adp, int mode, video_info_t *info)
+{
+ int i;
+
+ if (!vga_init_done)
+ return ENXIO;
+
+ mode = map_gen_mode_num(adp->va_type, adp->va_flags & V_ADP_COLOR, mode);
+#ifndef VGA_NO_MODE_CHANGE
+ if (adp->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 EINVAL;
+ } else
+#endif /* VGA_NO_MODE_CHANGE */
+ {
+ /*
+ * 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 != adp->va_initial_mode)
+ return EINVAL;
+ }
+
+ 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];
+ /* XXX */
+ info->vi_buffer_size = info->vi_window_size*info->vi_planes;
+ return 0;
+ }
+ }
+ return EINVAL;
+}
+
+/*
+ * query_mode():
+ * Find a video mode matching the requested parameters.
+ * Fields filled with 0 are considered "don't care" fields and
+ * match any modes.
+ *
+ * all adapters
+ */
+static int
+vga_query_mode(video_adapter_t *adp, video_info_t *info)
+{
+ video_info_t buf;
+ int i;
+
+ if (!vga_init_done)
+ 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 (vga_get_info(adp, bios_vmode[i].vi_mode, &buf))
+ continue;
+ return bios_vmode[i].vi_mode;
+ }
+ return -1;
+}
+
+/*
+ * set_mode():
+ * Change the video mode.
+ *
+ * EGA/VGA
+ */
+
+#ifndef VGA_NO_MODE_CHANGE
+#ifdef VGA_WIDTH90
+static void
+set_width90(adp_state_t *params)
+{
+ /*
+ * Based on code submitted by Kelly Yancey (kbyanc@freedomnet.com)
+ * and alexv@sui.gda.itesm.mx.
+ */
+ params->regs[5] |= 1; /* toggle 8 pixel wide fonts */
+ params->regs[10+0x0] = 0x6b;
+ params->regs[10+0x1] = 0x59;
+ params->regs[10+0x2] = 0x5a;
+ params->regs[10+0x3] = 0x8e;
+ params->regs[10+0x4] = 0x5e;
+ params->regs[10+0x5] = 0x8a;
+ params->regs[10+0x13] = 45;
+ params->regs[35+0x13] = 0;
+}
+#endif /* VGA_WIDTH90 */
+#endif /* !VGA_NO_MODE_CHANGE */
+
+static int
+vga_set_mode(video_adapter_t *adp, int mode)
+{
+#ifndef VGA_NO_MODE_CHANGE
+ video_info_t info;
+ adp_state_t params;
+
+ prologue(adp, V_ADP_MODECHANGE, ENODEV);
+
+ mode = map_gen_mode_num(adp->va_type,
+ adp->va_flags & V_ADP_COLOR, mode);
+ if (vga_get_info(adp, mode, &info))
+ return EINVAL;
+
+#if VGA_DEBUG > 1
+ printf("vga_set_mode(): setting mode %d\n", mode);
+#endif
+
+ params.sig = V_STATE_SIG;
+ bcopy(get_mode_param(mode), params.regs, sizeof(params.regs));
+
+ switch (mode) {
+#ifdef VGA_WIDTH90
+ case M_VGA_C90x60: case M_VGA_M90x60:
+ set_width90(&params);
+ /* FALL THROUGH */
+#endif
+ case M_VGA_C80x60: case M_VGA_M80x60:
+ params.regs[2] = 0x08;
+ params.regs[19] = 0x47;
+ goto special_480l;
+
+#ifdef VGA_WIDTH90
+ case M_VGA_C90x30: case M_VGA_M90x30:
+ set_width90(&params);
+ /* FALL THROUGH */
+#endif
+ 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;
+
+#ifdef VGA_WIDTH90
+ case M_VGA_C90x43: case M_VGA_M90x43:
+ set_width90(&params);
+ /* FALL THROUGH */
+#endif
+ case M_ENH_C80x43: case M_ENH_B80x43:
+ params.regs[28] = 87;
+ goto special_80x50;
+
+#ifdef VGA_WIDTH90
+ case M_VGA_C90x50: case M_VGA_M90x50:
+ set_width90(&params);
+ /* FALL THROUGH */
+#endif
+ case M_VGA_C80x50: case M_VGA_M80x50:
+special_80x50:
+ params.regs[2] = 8;
+ params.regs[19] = 7;
+ goto setup_mode;
+
+#ifdef VGA_WIDTH90
+ case M_VGA_C90x25: case M_VGA_M90x25:
+ set_width90(&params);
+ /* FALL THROUGH */
+#endif
+ 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:
+ vga_load_state(adp, &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:
+ vga_load_state(adp, &params);
+ break;
+
+ default:
+ return EINVAL;
+ }
+
+ adp->va_mode = mode;
+ info.vi_flags &= ~V_INFO_LINEAR; /* XXX */
+ update_adapter_info(adp, &info);
+
+ /* move hardware cursor out of the way */
+ (*vidsw[adp->va_index]->set_hw_cursor)(adp, -1, -1);
+
+ return 0;
+#else /* VGA_NO_MODE_CHANGE */
+ return ENODEV;
+#endif /* VGA_NO_MODE_CHANGE */
+}
+
+#ifndef VGA_NO_FONT_LOADING
+
+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 VGA_SLOW_IOACCESS
+#ifdef VGA_ALT_SEQACCESS
+ outb(TSIDX, 0x00); outb(TSREG, 0x01);
+#endif
+ outb(TSIDX, 0x02); outb(TSREG, 0x04);
+ outb(TSIDX, 0x04); outb(TSREG, 0x07);
+#ifdef VGA_ALT_SEQACCESS
+ 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 /* VGA_SLOW_IOACCESS */
+#ifdef VGA_ALT_SEQACCESS
+ outw(TSIDX, 0x0100);
+#endif
+ outw(TSIDX, 0x0402);
+ outw(TSIDX, 0x0704);
+#ifdef VGA_ALT_SEQACCESS
+ outw(TSIDX, 0x0300);
+#endif
+ outw(GDCIDX, 0x0204);
+ outw(GDCIDX, 0x0005);
+ outw(GDCIDX, 0x0406); /* addr = a0000, 64kb */
+#endif /* VGA_SLOW_IOACCESS */
+
+ 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 VGA_SLOW_IOACCESS
+#ifdef VGA_ALT_SEQACCESS
+ outb(TSIDX, 0x00); outb(TSREG, 0x01);
+#endif
+ outb(TSIDX, 0x02); outb(TSREG, buf[0]);
+ outb(TSIDX, 0x04); outb(TSREG, buf[1]);
+#ifdef VGA_ALT_SEQACCESS
+ 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_CRTC) {
+ outb(GDCIDX, 0x06); outb(GDCREG,(buf[4] & 0x03) | 0x08);
+ } else {
+ outb(GDCIDX, 0x06); outb(GDCREG,(buf[4] & 0x03) | 0x0c);
+ }
+#else /* VGA_SLOW_IOACCESS */
+#ifdef VGA_ALT_SEQACCESS
+ outw(TSIDX, 0x0100);
+#endif
+ outw(TSIDX, 0x0002 | (buf[0] << 8));
+ outw(TSIDX, 0x0004 | (buf[1] << 8));
+#ifdef VGA_ALT_SEQACCESS
+ outw(TSIDX, 0x0300);
+#endif
+ outw(GDCIDX, 0x0004 | (buf[2] << 8));
+ outw(GDCIDX, 0x0005 | (buf[3] << 8));
+ if (adp->va_crtc_addr == MONO_CRTC)
+ outw(GDCIDX, 0x0006 | (((buf[4] & 0x03) | 0x08)<<8));
+ else
+ outw(GDCIDX, 0x0006 | (((buf[4] & 0x03) | 0x0c)<<8));
+#endif /* VGA_SLOW_IOACCESS */
+
+ splx(s);
+}
+
+#endif /* VGA_NO_FONT_LOADING */
+
+/*
+ * save_font():
+ * Read the font data in the requested font page from the video adapter.
+ *
+ * EGA/VGA
+ */
+static int
+vga_save_font(video_adapter_t *adp, int page, int fontsize, u_char *data,
+ int ch, int count)
+{
+#ifndef VGA_NO_FONT_LOADING
+ u_char buf[PARAM_BUFSIZE];
+ u_int32_t segment;
+ int c;
+#ifdef VGA_ALT_SEQACCESS
+ int s;
+ u_char val = 0;
+#endif
+
+ prologue(adp, V_ADP_FONT, ENODEV);
+
+ 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 EINVAL;
+ segment = FONT_BUF + 0x4000*page;
+ if (page > 3)
+ segment -= 0xe000;
+
+#ifdef VGA_ALT_SEQACCESS
+ if (adp->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);
+ }
+#endif
+
+ set_font_mode(adp, buf);
+ if (fontsize == 32) {
+ bcopy_fromio(segment + ch*32, data, fontsize*count);
+ } else {
+ for (c = ch; count > 0; ++c, --count) {
+ bcopy_fromio(segment + c*32, data, fontsize);
+ data += fontsize;
+ }
+ }
+ set_normal_mode(adp, buf);
+
+#ifdef VGA_ALT_SEQACCESS
+ if (adp->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);
+ }
+#endif
+
+ return 0;
+#else /* VGA_NO_FONT_LOADING */
+ return ENODEV;
+#endif /* VGA_NO_FONT_LOADING */
+}
+
+/*
+ * load_font():
+ * Set the font data in the requested font page.
+ * NOTE: it appears that some recent video adapters do not support
+ * the font page other than 0... XXX
+ *
+ * EGA/VGA
+ */
+static int
+vga_load_font(video_adapter_t *adp, int page, int fontsize, u_char *data,
+ int ch, int count)
+{
+#ifndef VGA_NO_FONT_LOADING
+ u_char buf[PARAM_BUFSIZE];
+ u_int32_t segment;
+ int c;
+#ifdef VGA_ALT_SEQACCESS
+ int s;
+ u_char val = 0;
+#endif
+
+ prologue(adp, V_ADP_FONT, ENODEV);
+
+ 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 EINVAL;
+ segment = FONT_BUF + 0x4000*page;
+ if (page > 3)
+ segment -= 0xe000;
+
+#ifdef VGA_ALT_SEQACCESS
+ if (adp->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);
+ }
+#endif
+
+ set_font_mode(adp, buf);
+ if (fontsize == 32) {
+ bcopy_toio(data, segment + ch*32, fontsize*count);
+ } else {
+ for (c = ch; count > 0; ++c, --count) {
+ bcopy_toio(data, segment + c*32, fontsize);
+ data += fontsize;
+ }
+ }
+ set_normal_mode(adp, buf);
+
+#ifdef VGA_ALT_SEQACCESS
+ if (adp->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);
+ }
+#endif
+
+ return 0;
+#else /* VGA_NO_FONT_LOADING */
+ return ENODEV;
+#endif /* VGA_NO_FONT_LOADING */
+}
+
+/*
+ * show_font():
+ * Activate the requested font page.
+ * NOTE: it appears that some recent video adapters do not support
+ * the font page other than 0... XXX
+ *
+ * EGA/VGA
+ */
+static int
+vga_show_font(video_adapter_t *adp, int page)
+{
+#ifndef VGA_NO_FONT_LOADING
+ static u_char cg[] = { 0x00, 0x05, 0x0a, 0x0f, 0x30, 0x35, 0x3a, 0x3f };
+ int s;
+
+ prologue(adp, V_ADP_FONT, ENODEV);
+ if (page < 0 || page >= 8)
+ return EINVAL;
+
+ s = splhigh();
+ outb(TSIDX, 0x03); outb(TSREG, cg[page]);
+ splx(s);
+
+ return 0;
+#else /* VGA_NO_FONT_LOADING */
+ return ENODEV;
+#endif /* VGA_NO_FONT_LOADING */
+}
+
+/*
+ * save_palette():
+ * Read DAC values. The values have expressed in 8 bits.
+ *
+ * VGA
+ */
+static int
+vga_save_palette(video_adapter_t *adp, u_char *palette)
+{
+ int i;
+
+ prologue(adp, V_ADP_PALETTE, ENODEV);
+
+ /*
+ * 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(adp->va_crtc_addr + 6); /* reset flip/flop */
+ return 0;
+}
+
+static int
+vga_save_palette2(video_adapter_t *adp, int base, int count,
+ u_char *r, u_char *g, u_char *b)
+{
+ int i;
+
+ prologue(adp, V_ADP_PALETTE, ENODEV);
+
+ outb(PALRADR, base);
+ for (i = 0; i < count; ++i) {
+ r[i] = inb(PALDATA) << 2;
+ g[i] = inb(PALDATA) << 2;
+ b[i] = inb(PALDATA) << 2;
+ }
+ inb(adp->va_crtc_addr + 6); /* reset flip/flop */
+ return 0;
+}
+
+/*
+ * load_palette():
+ * Set DAC values.
+ *
+ * VGA
+ */
+static int
+vga_load_palette(video_adapter_t *adp, u_char *palette)
+{
+ int i;
+
+ prologue(adp, V_ADP_PALETTE, ENODEV);
+
+ outb(PIXMASK, 0xff); /* no pixelmask */
+ outb(PALWADR, 0x00);
+ for (i = 0; i < 256*3; ++i)
+ outb(PALDATA, palette[i] >> 2);
+ inb(adp->va_crtc_addr + 6); /* reset flip/flop */
+ outb(ATC, 0x20); /* enable palette */
+ return 0;
+}
+
+static int
+vga_load_palette2(video_adapter_t *adp, int base, int count,
+ u_char *r, u_char *g, u_char *b)
+{
+ int i;
+
+ prologue(adp, V_ADP_PALETTE, ENODEV);
+
+ outb(PIXMASK, 0xff); /* no pixelmask */
+ outb(PALWADR, base);
+ for (i = 0; i < count; ++i) {
+ outb(PALDATA, r[i] >> 2);
+ outb(PALDATA, g[i] >> 2);
+ outb(PALDATA, b[i] >> 2);
+ }
+ inb(adp->va_crtc_addr + 6); /* reset flip/flop */
+ outb(ATC, 0x20); /* enable palette */
+ return 0;
+}
+
+/*
+ * set_border():
+ * Change the border color.
+ *
+ * CGA/EGA/VGA
+ */
+static int
+vga_set_border(video_adapter_t *adp, int color)
+{
+ prologue(adp, V_ADP_BORDER, ENODEV);
+
+ switch (adp->va_type) {
+ case KD_EGA:
+ case KD_VGA:
+ inb(adp->va_crtc_addr + 6); /* reset flip-flop */
+ outb(ATC, 0x31); outb(ATC, color & 0xff);
+ break;
+ case KD_CGA:
+ outb(adp->va_crtc_addr + 5, color & 0x0f); /* color select register */
+ break;
+ case KD_MONO:
+ case KD_HERCULES:
+ default:
+ break;
+ }
+ return 0;
+}
+
+/*
+ * save_state():
+ * Read video register values.
+ * NOTE: this function only reads the standard EGA/VGA registers.
+ * any extra/extended registers of SVGA adapters are not saved.
+ *
+ * VGA
+ */
+static int
+vga_save_state(video_adapter_t *adp, 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(adp, V_ADP_STATESAVE, 0);
+ return sizeof(adp_state_t);
+ } else {
+ prologue(adp, V_ADP_STATESAVE, ENODEV);
+ if (size < sizeof(adp_state_t))
+ return EINVAL;
+ }
+
+ ((adp_state_t *)p)->sig = V_STATE_SIG;
+ buf = ((adp_state_t *)p)->regs;
+ bzero(buf, V_MODE_PARAM_SIZE);
+ crtc_addr = adp->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 (vga_get_info(adp, adp->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("vga%d: %s: failed to obtain mode info. (vga_save_state())\n",
+ adp->va_unit, adp->va_name);
+ }
+#else
+ buf[0] = readb(BIOS_PADDRTOVADDR(0x44a)); /* COLS */
+ buf[1] = readb(BIOS_PADDRTOVADDR(0x484)); /* ROWS */
+ buf[2] = readb(BIOS_PADDRTOVADDR(0x485)); /* POINTS */
+ buf[3] = readb(BIOS_PADDRTOVADDR(0x44c));
+ buf[4] = readb(BIOS_PADDRTOVADDR(0x44d));
+#endif
+
+ return 0;
+}
+
+/*
+ * load_state():
+ * Set video registers at once.
+ * NOTE: this function only updates the standard EGA/VGA registers.
+ * any extra/extended registers of SVGA adapters are not changed.
+ *
+ * EGA/VGA
+ */
+static int
+vga_load_state(video_adapter_t *adp, void *p)
+{
+ u_char *buf;
+ int crtc_addr;
+ int s;
+ int i;
+
+ prologue(adp, V_ADP_STATELOAD, ENODEV);
+ if (((adp_state_t *)p)->sig != V_STATE_SIG)
+ return EINVAL;
+
+ buf = ((adp_state_t *)p)->regs;
+ crtc_addr = adp->va_crtc_addr;
+
+#if VGA_DEBUG > 1
+ dump_buffer(buf, V_MODE_PARAM_SIZE);
+#endif
+
+ s = splhigh();
+
+ outb(TSIDX, 0x00); outb(TSREG, 0x01); /* stop sequencer */
+ for (i = 0; i < 4; ++i) { /* program sequencer */
+ outb(TSIDX, i + 1);
+ outb(TSREG, buf[i + 5]);
+ }
+ outb(MISC, buf[9]); /* set dot-clock */
+ outb(TSIDX, 0x00); outb(TSREG, 0x03); /* start sequencer */
+ outb(crtc_addr, 0x11);
+ outb(crtc_addr + 1, inb(crtc_addr + 1) & 0x7F);
+ for (i = 0; i < 25; ++i) { /* program crtc */
+ outb(crtc_addr, i);
+ outb(crtc_addr + 1, buf[i + 10]);
+ }
+ inb(crtc_addr+6); /* reset flip-flop */
+ for (i = 0; i < 20; ++i) { /* program attribute ctrl */
+ outb(ATC, i);
+ outb(ATC, buf[i + 35]);
+ }
+ for (i = 0; i < 9; ++i) { /* program graph data ctrl */
+ outb(GDCIDX, i);
+ outb(GDCREG, buf[i + 55]);
+ }
+ inb(crtc_addr + 6); /* reset flip-flop */
+ outb(ATC, 0x20); /* enable palette */
+
+#if notyet /* a temporary workaround for kernel panic, XXX */
+#ifndef VGA_NO_BIOS
+ if (adp->va_unit == V_ADP_PRIMARY) {
+ writeb(BIOS_PADDRTOVADDR(0x44a), buf[0]); /* COLS */
+ writeb(BIOS_PADDRTOVADDR(0x484), buf[1] + rows_offset - 1); /* ROWS */
+ writeb(BIOS_PADDRTOVADDR(0x485), buf[2]); /* POINTS */
+#if 0
+ writeb(BIOS_PADDRTOVADDR(0x44c), buf[3]);
+ writeb(BIOS_PADDRTOVADDR(0x44d), buf[4]);
+#endif
+ }
+#endif /* VGA_NO_BIOS */
+#endif /* notyet */
+
+ splx(s);
+ return 0;
+}
+
+/*
+ * set_origin():
+ * Change the origin (window mapping) of the banked frame buffer.
+ */
+static int
+vga_set_origin(video_adapter_t *adp, off_t offset)
+{
+ /*
+ * The standard video modes do not require window mapping;
+ * always return error.
+ */
+ return ENODEV;
+}
+
+/*
+ * read_hw_cursor():
+ * Read the position of the hardware text cursor.
+ *
+ * all adapters
+ */
+static int
+vga_read_hw_cursor(video_adapter_t *adp, int *col, int *row)
+{
+ u_int16_t off;
+ int s;
+
+ if (!vga_init_done)
+ return ENXIO;
+
+ if (adp->va_info.vi_flags & V_INFO_GRAPHICS)
+ return ENODEV;
+
+ s = spltty();
+ outb(adp->va_crtc_addr, 14);
+ off = inb(adp->va_crtc_addr + 1);
+ outb(adp->va_crtc_addr, 15);
+ off = (off << 8) | inb(adp->va_crtc_addr + 1);
+ splx(s);
+
+ *row = off / adp->va_info.vi_width;
+ *col = off % adp->va_info.vi_width;
+
+ return 0;
+}
+
+/*
+ * set_hw_cursor():
+ * Move the hardware text cursor. If col and row are both -1,
+ * the cursor won't be shown.
+ *
+ * all adapters
+ */
+static int
+vga_set_hw_cursor(video_adapter_t *adp, int col, int row)
+{
+ u_int16_t off;
+ int s;
+
+ if (!vga_init_done)
+ return ENXIO;
+
+ if ((col == -1) && (row == -1)) {
+ off = -1;
+ } else {
+ if (adp->va_info.vi_flags & V_INFO_GRAPHICS)
+ return ENODEV;
+ off = row*adp->va_info.vi_width + col;
+ }
+
+ s = spltty();
+ outb(adp->va_crtc_addr, 14);
+ outb(adp->va_crtc_addr + 1, off >> 8);
+ outb(adp->va_crtc_addr, 15);
+ outb(adp->va_crtc_addr + 1, off & 0x00ff);
+ splx(s);
+
+ return 0;
+}
+
+/*
+ * set_hw_cursor_shape():
+ * Change the shape of the hardware text cursor. If the height is
+ * zero or negative, the cursor won't be shown.
+ *
+ * all adapters
+ */
+static int
+vga_set_hw_cursor_shape(video_adapter_t *adp, int base, int height,
+ int celsize, int blink)
+{
+ int s;
+
+ if (!vga_init_done)
+ return ENXIO;
+
+ s = spltty();
+ switch (adp->va_type) {
+ case KD_VGA:
+ case KD_CGA:
+ case KD_MONO:
+ case KD_HERCULES:
+ default:
+ if (height <= 0) {
+ /* make the cursor invisible */
+ outb(adp->va_crtc_addr, 10);
+ outb(adp->va_crtc_addr + 1, 32);
+ outb(adp->va_crtc_addr, 11);
+ outb(adp->va_crtc_addr + 1, 0);
+ } else {
+ outb(adp->va_crtc_addr, 10);
+ outb(adp->va_crtc_addr + 1, celsize - base - height);
+ outb(adp->va_crtc_addr, 11);
+ outb(adp->va_crtc_addr + 1, celsize - base - 1);
+ }
+ break;
+ case KD_EGA:
+ if (height <= 0) {
+ /* make the cursor invisible */
+ outb(adp->va_crtc_addr, 10);
+ outb(adp->va_crtc_addr + 1, celsize);
+ outb(adp->va_crtc_addr, 11);
+ outb(adp->va_crtc_addr + 1, 0);
+ } else {
+ outb(adp->va_crtc_addr, 10);
+ outb(adp->va_crtc_addr + 1, celsize - base - height);
+ outb(adp->va_crtc_addr, 11);
+ outb(adp->va_crtc_addr + 1, celsize - base);
+ }
+ break;
+ }
+ splx(s);
+
+ return 0;
+}
+
+/*
+ * blank_display()
+ * Put the display in power save/power off mode.
+ *
+ * all adapters
+ */
+static int
+vga_blank_display(video_adapter_t *adp, int mode)
+{
+ u_char val;
+ int s;
+
+ s = splhigh();
+ switch (adp->va_type) {
+ case KD_VGA:
+ switch (mode) {
+ case V_DISPLAY_SUSPEND:
+ case V_DISPLAY_STAND_BY:
+ outb(TSIDX, 0x01);
+ val = inb(TSREG);
+ outb(TSIDX, 0x01);
+ outb(TSREG, val | 0x20);
+ outb(adp->va_crtc_addr, 0x17);
+ val = inb(adp->va_crtc_addr + 1);
+ outb(adp->va_crtc_addr + 1, val & ~0x80);
+ break;
+ case V_DISPLAY_BLANK:
+ outb(TSIDX, 0x01);
+ val = inb(TSREG);
+ outb(TSIDX, 0x01);
+ outb(TSREG, val | 0x20);
+ break;
+ case V_DISPLAY_ON:
+ outb(TSIDX, 0x01);
+ val = inb(TSREG);
+ outb(TSIDX, 0x01);
+ outb(TSREG, val & 0xDF);
+ outb(adp->va_crtc_addr, 0x17);
+ val = inb(adp->va_crtc_addr + 1);
+ outb(adp->va_crtc_addr + 1, val | 0x80);
+ break;
+ }
+ break;
+
+ case KD_EGA:
+ /* no support yet */
+ return ENODEV;
+
+ case KD_CGA:
+ switch (mode) {
+ case V_DISPLAY_SUSPEND:
+ case V_DISPLAY_STAND_BY:
+ case V_DISPLAY_BLANK:
+ outb(adp->va_crtc_addr + 4, 0x25);
+ break;
+ case V_DISPLAY_ON:
+ outb(adp->va_crtc_addr + 4, 0x2d);
+ break;
+ }
+ break;
+
+ case KD_MONO:
+ case KD_HERCULES:
+ switch (mode) {
+ case V_DISPLAY_SUSPEND:
+ case V_DISPLAY_STAND_BY:
+ case V_DISPLAY_BLANK:
+ outb(adp->va_crtc_addr + 4, 0x21);
+ break;
+ case V_DISPLAY_ON:
+ outb(adp->va_crtc_addr + 4, 0x29);
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ splx(s);
+
+ return 0;
+}
+
+/*
+ * mmap():
+ * Mmap frame buffer.
+ *
+ * all adapters
+ */
+static int
+vga_mmap_buf(video_adapter_t *adp, vm_offset_t offset, int prot)
+{
+ if (adp->va_info.vi_flags & V_INFO_LINEAR)
+ return -1;
+
+#if VGA_DEBUG > 0
+ printf("vga_mmap_buf(): window:0x%x, offset:0x%x\n",
+ adp->va_info.vi_window, offset);
+#endif
+
+ /* XXX: is this correct? */
+ if (offset > adp->va_window_size - PAGE_SIZE)
+ return -1;
+
+#ifdef __i386__
+ return i386_btop(adp->va_info.vi_window + offset);
+#endif
+#ifdef __alpha__
+ return alpha_btop(adp->va_info.vi_window + offset);
+#endif
+}
+
+#ifndef VGA_NO_MODE_CHANGE
+
+static void
+planar_fill(video_adapter_t *adp, int val)
+{
+ int length;
+ int at; /* position in the frame buffer */
+ int l;
+
+ outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */
+ outw(GDCIDX, 0x0003); /* data rotate/function select */
+ outw(GDCIDX, 0x0f01); /* set/reset enable */
+ outw(GDCIDX, 0xff08); /* bit mask */
+ outw(GDCIDX, (val << 8) | 0x00); /* set/reset */
+ at = 0;
+ length = adp->va_line_width*adp->va_info.vi_height;
+ while (length > 0) {
+ l = imin(length, adp->va_window_size);
+ (*vidsw[adp->va_index]->set_win_org)(adp, at);
+ bzero_io(adp->va_window, l);
+ length -= l;
+ at += l;
+ }
+ outw(GDCIDX, 0x0000); /* set/reset */
+ outw(GDCIDX, 0x0001); /* set/reset enable */
+}
+
+static void
+packed_fill(video_adapter_t *adp, int val)
+{
+ int length;
+ int at; /* position in the frame buffer */
+ int l;
+
+ at = 0;
+ length = adp->va_line_width*adp->va_info.vi_height;
+ while (length > 0) {
+ l = imin(length, adp->va_window_size);
+ (*vidsw[adp->va_index]->set_win_org)(adp, at);
+ fill_io(val, adp->va_window, l);
+ length -= l;
+ at += l;
+ }
+}
+
+static void
+direct_fill(video_adapter_t *adp, int val)
+{
+ int length;
+ int at; /* position in the frame buffer */
+ int l;
+
+ at = 0;
+ length = adp->va_line_width*adp->va_info.vi_height;
+ while (length > 0) {
+ l = imin(length, adp->va_window_size);
+ (*vidsw[adp->va_index]->set_win_org)(adp, at);
+ switch (adp->va_info.vi_pixel_size) {
+ case sizeof(u_int16_t):
+ fillw_io(val, adp->va_window, l/sizeof(u_int16_t));
+ break;
+ case 3:
+ /* FIXME */
+ break;
+ case sizeof(u_int32_t):
+ filll_io(val, adp->va_window, l/sizeof(u_int32_t));
+ break;
+ }
+ length -= l;
+ at += l;
+ }
+}
+
+static int
+vga_clear(video_adapter_t *adp)
+{
+ switch (adp->va_info.vi_mem_model) {
+ case V_INFO_MM_TEXT:
+ /* do nothing? XXX */
+ break;
+ case V_INFO_MM_PLANAR:
+ planar_fill(adp, 0);
+ break;
+ case V_INFO_MM_PACKED:
+ packed_fill(adp, 0);
+ break;
+ case V_INFO_MM_DIRECT:
+ direct_fill(adp, 0);
+ break;
+ }
+ return 0;
+}
+
+#ifdef notyet
+static void
+planar_fill_rect(video_adapter_t *adp, int val, int x, int y, int cx, int cy)
+{
+ int banksize;
+ int bank;
+ int pos;
+ int offset; /* offset within window */
+ int bx;
+ int l;
+
+ outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */
+ outw(GDCIDX, 0x0003); /* data rotate/function select */
+ outw(GDCIDX, 0x0f01); /* set/reset enable */
+ outw(GDCIDX, 0xff08); /* bit mask */
+ outw(GDCIDX, (val << 8) | 0x00); /* set/reset */
+
+ banksize = adp->va_window_size;
+ bank = -1;
+ while (cy > 0) {
+ pos = adp->va_line_width*y + x/8;
+ if (bank != pos/banksize) {
+ (*vidsw[adp->va_index]->set_win_org)(adp, pos);
+ bank = pos/banksize;
+ }
+ offset = pos%banksize;
+ bx = (x + cx)/8 - x/8;
+ if (x % 8) {
+ outw(GDCIDX, ((0xff00 >> (x % 8)) & 0xff00) | 0x08);
+ writeb(adp->va_window + offset, 0);
+ ++offset;
+ --bx;
+ if (offset >= banksize) {
+ offset = 0;
+ ++bank; /* next bank */
+ (*vidsw[adp->va_index]->set_win_org)(adp, bank*banksize);
+ }
+ outw(GDCIDX, 0xff08); /* bit mask */
+ }
+ while (bx > 0) {
+ l = imin(bx, banksize);
+ bzero_io(adp->va_window + offset, l);
+ offset += l;
+ bx -= l;
+ if (offset >= banksize) {
+ offset = 0;
+ ++bank; /* next bank */
+ (*vidsw[adp->va_index]->set_win_org)(adp, bank*banksize);
+ }
+ }
+ if ((x + cx) % 8) {
+ outw(GDCIDX, (~(0xff00 >> ((x + cx) % 8)) & 0xff00) | 0x08);
+ writeb(adp->va_window + offset, 0);
+ ++offset;
+ if (offset >= banksize) {
+ offset = 0;
+ ++bank; /* next bank */
+ (*vidsw[adp->va_index]->set_win_org)(adp, bank*banksize);
+ }
+ outw(GDCIDX, 0xff08); /* bit mask */
+ }
+ ++y;
+ --cy;
+ }
+
+ outw(GDCIDX, 0xff08); /* bit mask */
+ outw(GDCIDX, 0x0000); /* set/reset */
+ outw(GDCIDX, 0x0001); /* set/reset enable */
+}
+
+static void
+packed_fill_rect(video_adapter_t *adp, int val, int x, int y, int cx, int cy)
+{
+ int banksize;
+ int bank;
+ int pos;
+ int offset; /* offset within window */
+ int end;
+
+ banksize = adp->va_window_size;
+ bank = -1;
+ cx *= adp->va_info.vi_pixel_size;
+ while (cy > 0) {
+ pos = adp->va_line_width*y + x*adp->va_info.vi_pixel_size;
+ if (bank != pos/banksize) {
+ (*vidsw[adp->va_index]->set_win_org)(adp, pos);
+ bank = pos/banksize;
+ }
+ offset = pos%banksize;
+ end = imin(offset + cx, banksize);
+ fill_io(val, adp->va_window + offset,
+ (end - offset)/adp->va_info.vi_pixel_size);
+ /* the line may cross the window boundary */
+ if (offset + cx > banksize) {
+ ++bank; /* next bank */
+ (*vidsw[adp->va_index]->set_win_org)(adp, bank*banksize);
+ end = offset + cx - banksize;
+ fill_io(val, adp->va_window, end/adp->va_info.vi_pixel_size);
+ }
+ ++y;
+ --cy;
+ }
+}
+
+static void
+direct_fill_rect16(video_adapter_t *adp, int val, int x, int y, int cx, int cy)
+{
+ int banksize;
+ int bank;
+ int pos;
+ int offset; /* offset within window */
+ int end;
+
+ /*
+ * XXX: the function assumes that banksize is a muliple of
+ * sizeof(u_int16_t).
+ */
+ banksize = adp->va_window_size;
+ bank = -1;
+ cx *= sizeof(u_int16_t);
+ while (cy > 0) {
+ pos = adp->va_line_width*y + x*sizeof(u_int16_t);
+ if (bank != pos/banksize) {
+ (*vidsw[adp->va_index]->set_win_org)(adp, pos);
+ bank = pos/banksize;
+ }
+ offset = pos%banksize;
+ end = imin(offset + cx, banksize);
+ fillw_io(val, adp->va_window + offset,
+ (end - offset)/sizeof(u_int16_t));
+ /* the line may cross the window boundary */
+ if (offset + cx > banksize) {
+ ++bank; /* next bank */
+ (*vidsw[adp->va_index]->set_win_org)(adp, bank*banksize);
+ end = offset + cx - banksize;
+ fillw_io(val, adp->va_window, end/sizeof(u_int16_t));
+ }
+ ++y;
+ --cy;
+ }
+}
+
+static void
+direct_fill_rect24(video_adapter_t *adp, int val, int x, int y, int cx, int cy)
+{
+ int banksize;
+ int bank;
+ int pos;
+ int offset; /* offset within window */
+ int end;
+ int i;
+ int j;
+ u_int8_t b[3];
+
+ b[0] = val & 0x0000ff;
+ b[1] = (val >> 8) & 0x0000ff;
+ b[2] = (val >> 16) & 0x0000ff;
+ banksize = adp->va_window_size;
+ bank = -1;
+ cx *= 3;
+ while (cy > 0) {
+ pos = adp->va_line_width*y + x*3;
+ if (bank != pos/banksize) {
+ (*vidsw[adp->va_index]->set_win_org)(adp, pos);
+ bank = pos/banksize;
+ }
+ offset = pos%banksize;
+ end = imin(offset + cx, banksize);
+ for (i = 0, j = offset; j < end; i = (++i)%3, ++j) {
+ writeb(adp->va_window + j, b[i]);
+ }
+ /* the line may cross the window boundary */
+ if (offset + cx >= banksize) {
+ ++bank; /* next bank */
+ (*vidsw[adp->va_index]->set_win_org)(adp, bank*banksize);
+ j = 0;
+ end = offset + cx - banksize;
+ for (; j < end; i = (++i)%3, ++j) {
+ writeb(adp->va_window + j, b[i]);
+ }
+ }
+ ++y;
+ --cy;
+ }
+}
+
+static void
+direct_fill_rect32(video_adapter_t *adp, int val, int x, int y, int cx, int cy)
+{
+ int banksize;
+ int bank;
+ int pos;
+ int offset; /* offset within window */
+ int end;
+
+ /*
+ * XXX: the function assumes that banksize is a muliple of
+ * sizeof(u_int32_t).
+ */
+ banksize = adp->va_window_size;
+ bank = -1;
+ cx *= sizeof(u_int32_t);
+ while (cy > 0) {
+ pos = adp->va_line_width*y + x*sizeof(u_int32_t);
+ if (bank != pos/banksize) {
+ (*vidsw[adp->va_index]->set_win_org)(adp, pos);
+ bank = pos/banksize;
+ }
+ offset = pos%banksize;
+ end = imin(offset + cx, banksize);
+ filll_io(val, adp->va_window + offset,
+ (end - offset)/sizeof(u_int32_t));
+ /* the line may cross the window boundary */
+ if (offset + cx > banksize) {
+ ++bank; /* next bank */
+ (*vidsw[adp->va_index]->set_win_org)(adp, bank*banksize);
+ end = offset + cx - banksize;
+ filll_io(val, adp->va_window, end/sizeof(u_int32_t));
+ }
+ ++y;
+ --cy;
+ }
+}
+
+static int
+vga_fill_rect(video_adapter_t *adp, int val, int x, int y, int cx, int cy)
+{
+ switch (adp->va_info.vi_mem_model) {
+ case V_INFO_MM_TEXT:
+ /* do nothing? XXX */
+ break;
+ case V_INFO_MM_PLANAR:
+ planar_fill_rect(adp, val, x, y, cx, cy);
+ break;
+ case V_INFO_MM_PACKED:
+ packed_fill_rect(adp, val, x, y, cx, cy);
+ break;
+ case V_INFO_MM_DIRECT:
+ switch (adp->va_info.vi_pixel_size) {
+ case sizeof(u_int16_t):
+ direct_fill_rect16(adp, val, x, y, cx, cy);
+ break;
+ case 3:
+ direct_fill_rect24(adp, val, x, y, cx, cy);
+ break;
+ case sizeof(u_int32_t):
+ direct_fill_rect32(adp, val, x, y, cx, cy);
+ break;
+ }
+ break;
+ }
+ return 0;
+}
+#else /* !notyet */
+static int
+vga_fill_rect(video_adapter_t *adp, int val, int x, int y, int cx, int cy)
+{
+ return ENODEV;
+}
+#endif /* notyet */
+
+static int
+vga_bitblt(video_adapter_t *adp,...)
+{
+ /* FIXME */
+ return ENODEV;
+}
+
+#endif /* !VGA_NO_MODE_CHANGE */
+
+static int
+get_palette(video_adapter_t *adp, int base, int count,
+ u_char *red, u_char *green, u_char *blue, u_char *trans)
+{
+ u_char *r;
+ u_char *g;
+ u_char *b;
+
+ if ((base < 0) || (base >= 256) || (base + count > 256))
+ return EINVAL;
+
+ r = malloc(count*3, M_DEVBUF, M_WAITOK);
+ g = r + count;
+ b = g + count;
+ if (vga_save_palette2(adp, base, count, r, g, b))
+ return ENODEV;
+ copyout(r, red, count);
+ copyout(g, green, count);
+ copyout(b, blue, count);
+ if (trans != NULL) {
+ bzero(r, count);
+ copyout(r, trans, count);
+ }
+ free(r, M_DEVBUF);
+
+ return 0;
+}
+
+static int
+set_palette(video_adapter_t *adp, int base, int count,
+ u_char *red, u_char *green, u_char *blue, u_char *trans)
+{
+ u_char *r;
+ u_char *g;
+ u_char *b;
+ int err;
+
+ if ((base < 0) || (base >= 256) || (base + count > 256))
+ return EINVAL;
+
+ r = malloc(count*3, M_DEVBUF, M_WAITOK);
+ g = r + count;
+ b = g + count;
+ copyin(red, r, count);
+ copyin(green, g, count);
+ copyin(blue, b, count);
+ err = vga_load_palette2(adp, base, count, r, g, b);
+ free(r, M_DEVBUF);
+
+ return (err ? ENODEV : 0);
+}
+
+static int
+vga_dev_ioctl(video_adapter_t *adp, u_long cmd, caddr_t arg)
+{
+ switch (cmd) {
+ case FBIO_GETWINORG: /* get frame buffer window origin */
+ *(u_int *)arg = 0;
+ return 0;
+
+ case FBIO_SETWINORG: /* set frame buffer window origin */
+ return ENODEV;
+
+ case FBIO_SETDISPSTART: /* set display start address */
+ return (set_display_start(adp,
+ ((video_display_start_t *)arg)->x,
+ ((video_display_start_t *)arg)->y)
+ ? ENODEV : 0);
+
+ case FBIO_SETLINEWIDTH: /* set scan line length in pixel */
+ return (set_line_length(adp, *(u_int *)arg) ? ENODEV : 0);
+
+ case FBIO_GETPALETTE: /* get color palette */
+ return get_palette(adp, ((video_color_palette_t *)arg)->index,
+ ((video_color_palette_t *)arg)->count,
+ ((video_color_palette_t *)arg)->red,
+ ((video_color_palette_t *)arg)->green,
+ ((video_color_palette_t *)arg)->blue,
+ ((video_color_palette_t *)arg)->transparent);
+
+ case FBIO_SETPALETTE: /* set color palette */
+ return set_palette(adp, ((video_color_palette_t *)arg)->index,
+ ((video_color_palette_t *)arg)->count,
+ ((video_color_palette_t *)arg)->red,
+ ((video_color_palette_t *)arg)->green,
+ ((video_color_palette_t *)arg)->blue,
+ ((video_color_palette_t *)arg)->transparent);
+
+ case FBIOGTYPE: /* get frame buffer type info. */
+ ((struct fbtype *)arg)->fb_type = fb_type(adp->va_type);
+ ((struct fbtype *)arg)->fb_height = adp->va_info.vi_height;
+ ((struct fbtype *)arg)->fb_width = adp->va_info.vi_width;
+ ((struct fbtype *)arg)->fb_depth = adp->va_info.vi_depth;
+ if ((adp->va_info.vi_depth <= 1) || (adp->va_info.vi_depth > 8))
+ ((struct fbtype *)arg)->fb_cmsize = 0;
+ else
+ ((struct fbtype *)arg)->fb_cmsize = 1 << adp->va_info.vi_depth;
+ ((struct fbtype *)arg)->fb_size = adp->va_buffer_size;
+ return 0;
+
+ case FBIOGETCMAP: /* get color palette */
+ return get_palette(adp, ((struct fbcmap *)arg)->index,
+ ((struct fbcmap *)arg)->count,
+ ((struct fbcmap *)arg)->red,
+ ((struct fbcmap *)arg)->green,
+ ((struct fbcmap *)arg)->blue, NULL);
+
+ case FBIOPUTCMAP: /* set color palette */
+ return set_palette(adp, ((struct fbcmap *)arg)->index,
+ ((struct fbcmap *)arg)->count,
+ ((struct fbcmap *)arg)->red,
+ ((struct fbcmap *)arg)->green,
+ ((struct fbcmap *)arg)->blue, NULL);
+
+ default:
+ return fb_commonioctl(adp, cmd, arg);
+ }
+}
+
+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");
+ }
+}
+
+/*
+ * diag():
+ * Print some information about the video adapter and video modes,
+ * with requested level of details.
+ *
+ * all adapters
+ */
+static int
+vga_diag(video_adapter_t *adp, int level)
+{
+ u_char *mp;
+#if FB_DEBUG > 1
+ video_info_t info;
+ int i;
+#endif
+
+ if (!vga_init_done)
+ return ENXIO;
+
+#if FB_DEBUG > 1
+#ifndef VGA_NO_BIOS
+ printf("vga: RTC equip. code:0x%02x, DCC code:0x%02x\n",
+ rtcin(RTC_EQUIPMENT), readb(BIOS_PADDRTOVADDR(0x488)));
+ printf("vga: CRTC:0x%x, video option:0x%02x, ",
+ readw(BIOS_PADDRTOVADDR(0x463)),
+ readb(BIOS_PADDRTOVADDR(0x487)));
+ printf("rows:%d, cols:%d, font height:%d\n",
+ readb(BIOS_PADDRTOVADDR(0x44a)),
+ readb(BIOS_PADDRTOVADDR(0x484)) + 1,
+ readb(BIOS_PADDRTOVADDR(0x485)));
+#endif /* VGA_NO_BIOS */
+#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE)
+ printf("vga: param table EGA/VGA:%p", video_mode_ptr);
+ printf(", CGA/MDA:%p\n", video_mode_ptr2);
+ printf("vga: rows_offset:%d\n", rows_offset);
+#endif
+#endif /* FB_DEBUG > 1 */
+
+ fb_dump_adp_info(VGA_DRIVER_NAME, adp, level);
+
+#if FB_DEBUG > 1
+ if (adp->va_flags & V_ADP_MODECHANGE) {
+ 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;
+ fb_dump_mode_info(VGA_DRIVER_NAME, adp, &bios_vmode[i], level);
+ }
+ } else {
+ vga_get_info(adp, adp->va_initial_mode, &info); /* shouldn't fail */
+ fb_dump_mode_info(VGA_DRIVER_NAME, adp, &info, level);
+ }
+#endif /* FB_DEBUG > 1 */
+
+ if ((adp->va_type != KD_EGA) && (adp->va_type != KD_VGA))
+ return 0;
+#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE)
+ if (video_mode_ptr == NULL)
+ printf("vga%d: %s: WARNING: video mode switching is not "
+ "fully supported on this adapter\n",
+ adp->va_unit, adp->va_name);
+#endif
+ if (level <= 0)
+ return 0;
+
+ if (adp->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", adp->va_initial_mode);
+ dump_buffer(adpstate2.regs, sizeof(adpstate2.regs));
+ }
+
+ mp = get_mode_param(adp->va_initial_mode);
+ if (mp == NULL) /* this shouldn't be happening */
+ return 0;
+ printf("EGA/VGA parameters to be used for mode %d\n", adp->va_initial_mode);
+ dump_buffer(mp, V_MODE_PARAM_SIZE);
+
+ return 0;
+}
+
+#endif /* NVGA > 0 */
diff --git a/sys/dev/fb/vgareg.h b/sys/dev/fb/vgareg.h
index 841408e..e9e9eb2 100644
--- a/sys/dev/fb/vgareg.h
+++ b/sys/dev/fb/vgareg.h
@@ -23,7 +23,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id:$
+ * $Id: vgareg.h,v 1.1 1999/01/09 02:44:49 yokota Exp $
*/
#ifndef _DEV_FB_VGAREG_H_
@@ -60,8 +60,38 @@
#define GDCIDX (IO_VGA + 0x0E) /* graph data controller idx */
#define GDCREG (IO_VGA + 0x0F) /* graph data controller data */
+#define VGA_DRIVER_NAME "vga"
+#define VGA_UNIT(dev) minor(dev)
+#define VGA_MKMINOR(unit) (unit)
+
#ifdef KERNEL
-extern int (*vga_sub_configure)(int flags);
+
+struct video_adapter;
+typedef struct vga_softc {
+ struct video_adapter *adp;
+#ifdef FB_INSTALL_CDEV
+ genfb_softc_t gensc;
#endif
+} vga_softc_t;
+
+int vga_probe_unit(int unit, struct video_adapter *adp, int flags);
+int vga_attach_unit(int unit, vga_softc_t *sc, int flags);
+
+#ifdef FB_INSTALL_CDEV
+int vga_open(dev_t dev, vga_softc_t *sc, int flag, int mode,
+ struct proc *p);
+int vga_close(dev_t dev, vga_softc_t *sc, int flag, int mode,
+ struct proc *p);
+int vga_read(dev_t dev, vga_softc_t *sc, struct uio *uio, int flag);
+int vga_write(dev_t dev, vga_softc_t *sc, struct uio *uio, int flag);
+int vga_ioctl(dev_t dev, vga_softc_t *sc, u_long cmd, caddr_t arg,
+ int flag, struct proc *p);
+int vga_mmap(dev_t dev, vga_softc_t *sc, vm_offset_t offset,
+ int prot);
+#endif
+
+extern int (*vga_sub_configure)(int flags);
+
+#endif /* KERNEL */
#endif /* _DEV_FB_VGAREG_H_ */
diff --git a/sys/dev/sio/sio.c b/sys/dev/sio/sio.c
index c3be310..6c17bc1 100644
--- a/sys/dev/sio/sio.c
+++ b/sys/dev/sio/sio.c
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: sio.c,v 1.248 1999/06/19 08:14:56 grog Exp $
+ * $Id: sio.c,v 1.249 1999/06/20 13:10:09 peter Exp $
* from: @(#)com.c 7.5 (Berkeley) 5/16/91
* from: i386/isa sio.c,v 1.234
*/
@@ -2656,7 +2656,7 @@ static cn_checkc_t siocncheckc;
static cn_getc_t siocngetc;
static cn_putc_t siocnputc;
-CONS_DRIVER(sio, siocnprobe, siocninit, siocngetc, siocncheckc, siocnputc);
+CONS_DRIVER(sio, siocnprobe, siocninit, NULL, siocngetc, siocncheckc, siocnputc);
/* To get the GDB related variables */
#if DDB > 0
@@ -2855,7 +2855,6 @@ siocnprobe(cp)
cp->cn_pri = COM_FORCECONSOLE(flags)
|| boothowto & RB_SERIAL
? CN_REMOTE : CN_NORMAL;
- printf("sio%d: system console\n", unit);
siocniobase = iobase;
siocnunit = unit;
}
@@ -2897,10 +2896,7 @@ siocnprobe(cp)
#ifdef __alpha__
-struct consdev siocons = {
- NULL, NULL, siocngetc, siocncheckc, siocnputc,
- NULL, 0, CN_NORMAL,
-};
+CONS_DRIVER(sio, NULL, NULL, NULL, siocngetc, siocncheckc, siocnputc);
extern struct consdev *cn_tab;
@@ -2915,6 +2911,8 @@ siocnattach(port, speed)
siocniobase = port;
comdefaultrate = speed;
+ sio_consdev.cn_pri = CN_NORMAL;
+ sio_consdev.cn_dev = makedev(CDEV_MAJOR, 0);
s = spltty();
@@ -2938,8 +2936,7 @@ siocnattach(port, speed)
siocnopen(&sp, siocniobase, comdefaultrate);
splx(s);
- siocons.cn_dev = makedev(CDEV_MAJOR, 0);
- cn_tab = &siocons;
+ cn_tab = &sio_consdev;
return 0;
}
diff --git a/sys/dev/syscons/blank/blank_saver.c b/sys/dev/syscons/blank/blank_saver.c
index 89dd199..2979c0d 100644
--- a/sys/dev/syscons/blank/blank_saver.c
+++ b/sys/dev/syscons/blank/blank_saver.c
@@ -25,82 +25,35 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: blank_saver.c,v 1.14 1998/11/04 03:49:38 peter Exp $
+ * $Id: blank_saver.c,v 1.15 1999/01/11 03:18:44 yokota Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/module.h>
+#include <sys/consio.h>
+#include <sys/fbio.h>
-#include <dev/fb/vgareg.h>
-
-#include <i386/isa/isa.h>
-
-#include <saver.h>
+#include <dev/fb/fbreg.h>
+#include <dev/fb/splashreg.h>
+#include <dev/syscons/syscons.h>
static int
blank_saver(video_adapter_t *adp, int blank)
{
- u_char val;
- if (blank) {
- switch (adp->va_type) {
- case KD_VGA:
- outb(TSIDX, 0x01); val = inb(TSREG);
- outb(TSIDX, 0x01); outb(TSREG, val | 0x20);
- break;
- case KD_EGA:
- /* not yet done XXX */
- break;
- case KD_CGA:
- outb(adp->va_crtc_addr + 4, 0x25);
- break;
- case KD_MONO:
- case KD_HERCULES:
- outb(adp->va_crtc_addr + 4, 0x21);
- break;
- default:
- break;
- }
- }
- else {
- switch (adp->va_type) {
- case KD_VGA:
- outb(TSIDX, 0x01); val = inb(TSREG);
- outb(TSIDX, 0x01); outb(TSREG, val & 0xDF);
- break;
- case KD_EGA:
- /* not yet done XXX */
- break;
- case KD_CGA:
- outb(adp->va_crtc_addr + 4, 0x2d);
- break;
- case KD_MONO:
- case KD_HERCULES:
- outb(adp->va_crtc_addr + 4, 0x29);
- break;
- default:
- break;
- }
- }
+ (*vidsw[adp->va_index]->blank_display)(adp,
+ (blank) ? V_DISPLAY_BLANK
+ : V_DISPLAY_ON);
return 0;
}
static int
blank_init(video_adapter_t *adp)
{
- switch (adp->va_type) {
- case KD_MONO:
- case KD_HERCULES:
- case KD_CGA:
- case KD_VGA:
- break;
- case KD_EGA:
- /* EGA is yet to be supported */
- default:
- return ENODEV;
- }
- return 0;
+ if ((*vidsw[adp->va_index]->blank_display)(adp, V_DISPLAY_ON) == 0)
+ return 0;
+ return ENODEV;
}
static int
diff --git a/sys/dev/syscons/daemon/daemon_saver.c b/sys/dev/syscons/daemon/daemon_saver.c
index 423e6c7..ebedfaa 100644
--- a/sys/dev/syscons/daemon/daemon_saver.c
+++ b/sys/dev/syscons/daemon/daemon_saver.c
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: daemon_saver.c,v 1.14 1999/01/17 14:25:08 yokota Exp $
+ * $Id: daemon_saver.c,v 1.15 1999/02/05 12:40:15 des Exp $
*/
#include <sys/param.h>
@@ -34,21 +34,20 @@
#include <sys/malloc.h>
#include <sys/kernel.h>
#include <sys/sysctl.h>
+#include <sys/consio.h>
+#include <sys/fbio.h>
-#include <machine/md_var.h>
#include <machine/pc/display.h>
-#include <saver.h>
-
-#define CONSOLE_VECT(x, y) \
- (window + (y)*cur_console->xsize + (x))
+#include <dev/fb/fbreg.h>
+#include <dev/fb/splashreg.h>
+#include <dev/syscons/syscons.h>
#define DAEMON_MAX_WIDTH 32
#define DAEMON_MAX_HEIGHT 19
static char *message;
static int messagelen;
-static u_short *window;
static int blanked;
/* Who is the author of this ASCII pic? */
@@ -119,20 +118,23 @@ xflip_symbol(char symbol)
}
static void
-clear_daemon(int xpos, int ypos, int dxdir, int xoff, int yoff,
+clear_daemon(sc_softc_t *sc, int xpos, int ypos, int dxdir, int xoff, int yoff,
int xlen, int ylen)
{
int y;
if (xlen <= 0)
return;
- for (y = yoff; y < ylen; y++)
- fillw(((FG_LIGHTGREY|BG_BLACK) << 8) | scr_map[0x20],
- CONSOLE_VECT(xpos + xoff, ypos + y), xlen - xoff);
+ for (y = yoff; y < ylen; y++) {
+ sc_vtb_erase(&sc->cur_scp->scr,
+ (ypos + y)*sc->cur_scp->xsize + xpos + xoff,
+ xlen - xoff,
+ sc->scr_map[0x20], (FG_LIGHTGREY | BG_BLACK) << 8);
+ }
}
static void
-draw_daemon(int xpos, int ypos, int dxdir, int xoff, int yoff,
+draw_daemon(sc_softc_t *sc, int xpos, int ypos, int dxdir, int xoff, int yoff,
int xlen, int ylen)
{
int x, y;
@@ -148,41 +150,60 @@ draw_daemon(int xpos, int ypos, int dxdir, int xoff, int yoff,
continue;
for (x = xoff; (x < xlen) && (daemon_pic[y][px] != '\0'); x++, px++) {
switch (daemon_attr[y][px]) {
+#ifndef PC98
case 'R': attr = (FG_LIGHTRED|BG_BLACK)<<8; break;
case 'Y': attr = (FG_YELLOW|BG_BLACK)<<8; break;
case 'B': attr = (FG_LIGHTBLUE|BG_BLACK)<<8; break;
case 'W': attr = (FG_LIGHTGREY|BG_BLACK)<<8; break;
case 'C': attr = (FG_CYAN|BG_BLACK)<<8; break;
default: attr = (FG_WHITE|BG_BLACK)<<8; break;
+#else /* PC98 */
+ case 'R': attr = (FG_RED|BG_BLACK)<<8; break;
+ case 'Y': attr = (FG_BROWN|BG_BLACK)<<8; break;
+ case 'B': attr = (FG_BLUE|BG_BLACK)<<8; break;
+ case 'W': attr = (FG_LIGHTGREY|BG_BLACK)<<8; break;
+ case 'C': attr = (FG_CYAN|BG_BLACK)<<8; break;
+ default: attr = (FG_LIGHTGREY|BG_BLACK)<<8; break;
+#endif /* PC98 */
}
if (dxdir < 0) { /* Moving left */
- *CONSOLE_VECT(xpos + x, ypos + y) =
- scr_map[daemon_pic[y][px]]|attr;
+ sc_vtb_putc(&sc->cur_scp->scr,
+ (ypos + y)*sc->cur_scp->xsize
+ + xpos + x,
+ sc->scr_map[daemon_pic[y][px]],
+ attr);
} else { /* Moving right */
- *CONSOLE_VECT(xpos + DAEMON_MAX_WIDTH - px - 1, ypos + y) =
- scr_map[xflip_symbol(daemon_pic[y][px])]|attr;
+ sc_vtb_putc(&sc->cur_scp->scr,
+ (ypos + y)*sc->cur_scp->xsize
+ + xpos + DAEMON_MAX_WIDTH
+ - px - 1,
+ sc->scr_map[xflip_symbol(daemon_pic[y][px])],
+ attr);
}
}
}
}
static void
-clear_string(int xpos, int ypos, int xoff, char *s, int len)
+clear_string(sc_softc_t *sc, int xpos, int ypos, int xoff, char *s, int len)
{
if (len <= 0)
return;
- fillw(((FG_LIGHTGREY|BG_BLACK) << 8) | scr_map[0x20],
- CONSOLE_VECT(xpos + xoff, ypos), len - xoff);
+ sc_vtb_erase(&sc->cur_scp->scr,
+ ypos*sc->cur_scp->xsize + xpos + xoff, len - xoff,
+ sc->scr_map[0x20], (FG_LIGHTGREY | BG_BLACK) << 8);
}
static void
-draw_string(int xpos, int ypos, int xoff, char *s, int len)
+draw_string(sc_softc_t *sc, int xpos, int ypos, int xoff, char *s, int len)
{
int x;
- for (x = xoff; x < len; x++)
- *CONSOLE_VECT(xpos + x, ypos) =
- scr_map[s[x]]|(FG_LIGHTGREEN|BG_BLACK)<<8;
+ for (x = xoff; x < len; x++) {
+ sc_vtb_putc(&sc->cur_scp->scr,
+ ypos*sc->cur_scp->xsize + xpos + x,
+ sc->scr_map[s[x]], (FG_LIGHTGREEN | BG_BLACK) << 8);
+ }
}
static int
@@ -195,17 +216,30 @@ daemon_saver(video_adapter_t *adp, int blank)
static int moved_daemon = 0;
static int xoff, yoff, toff;
static int xlen, ylen, tlen;
- scr_stat *scp = cur_console;
+ sc_softc_t *sc;
+ scr_stat *scp;
int min, max;
+ sc = sc_find_softc(adp, NULL);
+ if (sc == NULL)
+ return EAGAIN;
+ scp = sc->cur_scp;
+
if (blank) {
if (adp->va_info.vi_flags & V_INFO_GRAPHICS)
return EAGAIN;
if (blanked == 0) {
- window = (u_short *)adp->va_window;
+#ifdef PC98
+ if (epson_machine_id == 0x20) {
+ outb(0x43f, 0x42);
+ outb(0x0c17, inb(0xc17) & ~0x08);
+ outb(0x43f, 0x40);
+ }
+#endif /* PC98 */
/* clear the screen and set the border color */
- fillw(((FG_LIGHTGREY|BG_BLACK) << 8) | scr_map[0x20],
- window, scp->xsize * scp->ysize);
+ sc_vtb_clear(&scp->scr, sc->scr_map[0x20],
+ (FG_LIGHTGREY | BG_BLACK) << 8);
+ (*vidsw[adp->va_index]->set_hw_cursor)(adp, -1, -1);
set_border(scp, 0);
xlen = ylen = tlen = 0;
}
@@ -213,8 +247,8 @@ daemon_saver(video_adapter_t *adp, int blank)
return 0;
blanked = 1;
- clear_daemon(dxpos, dypos, dxdir, xoff, yoff, xlen, ylen);
- clear_string(txpos, typos, toff, (char *)message, tlen);
+ clear_daemon(sc, dxpos, dypos, dxdir, xoff, yoff, xlen, ylen);
+ clear_string(sc, txpos, typos, toff, (char *)message, tlen);
if (++moved_daemon) {
/*
@@ -319,9 +353,16 @@ daemon_saver(video_adapter_t *adp, int blank)
else if (txpos + tlen > scp->xsize)
tlen = scp->xsize - txpos;
- draw_daemon(dxpos, dypos, dxdir, xoff, yoff, xlen, ylen);
- draw_string(txpos, typos, toff, (char *)message, tlen);
+ draw_daemon(sc, dxpos, dypos, dxdir, xoff, yoff, xlen, ylen);
+ draw_string(sc, txpos, typos, toff, (char *)message, tlen);
} else {
+#ifdef PC98
+ if (epson_machine_id == 0x20) {
+ outb(0x43f, 0x42);
+ outb(0x0c17, inb(0xc17) | 0x08);
+ outb(0x43f, 0x40);
+ }
+#endif /* PC98 */
blanked = 0;
}
return 0;
diff --git a/sys/dev/syscons/fade/fade_saver.c b/sys/dev/syscons/fade/fade_saver.c
index 70d36c9..4a44c85 100644
--- a/sys/dev/syscons/fade/fade_saver.c
+++ b/sys/dev/syscons/fade/fade_saver.c
@@ -25,17 +25,19 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: fade_saver.c,v 1.15 1998/11/04 03:49:38 peter Exp $
+ * $Id: fade_saver.c,v 1.16 1999/01/11 03:18:46 yokota Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/module.h>
+#include <sys/consio.h>
+#include <sys/fbio.h>
-#include <i386/isa/isa.h>
-
-#include <saver.h>
+#include <dev/fb/fbreg.h>
+#include <dev/fb/splashreg.h>
+#include <dev/syscons/syscons.h>
static u_char palette[256*3];
static int blanked;
@@ -49,11 +51,10 @@ fade_saver(video_adapter_t *adp, int blank)
if (blank) {
blanked = TRUE;
- switch (adp->va_type) {
- case KD_VGA:
+ if (ISPALAVAIL(adp->va_flags)) {
if (count <= 0)
save_palette(adp, palette);
- if (count < 64) {
+ if (count < 256) {
pal[0] = pal[1] = pal[2] = 0;
for (i = 3; i < 256*3; i++) {
if (palette[i] - count > 60)
@@ -64,39 +65,17 @@ fade_saver(video_adapter_t *adp, int blank)
load_palette(adp, pal);
count++;
}
- break;
- case KD_EGA:
- /* not yet done XXX */
- break;
- case KD_CGA:
- outb(adp->va_crtc_addr + 4, 0x25);
- break;
- case KD_MONO:
- case KD_HERCULES:
- outb(adp->va_crtc_addr + 4, 0x21);
- break;
- default:
- break;
+ } else {
+ (*vidsw[adp->va_index]->blank_display)(adp,
+ V_DISPLAY_BLANK);
}
- }
- else {
- switch (adp->va_type) {
- case KD_VGA:
+ } else {
+ if (ISPALAVAIL(adp->va_flags)) {
load_palette(adp, palette);
count = 0;
- break;
- case KD_EGA:
- /* not yet done XXX */
- break;
- case KD_CGA:
- outb(adp->va_crtc_addr + 4, 0x2d);
- break;
- case KD_MONO:
- case KD_HERCULES:
- outb(adp->va_crtc_addr + 4, 0x29);
- break;
- default:
- break;
+ } else {
+ (*vidsw[adp->va_index]->blank_display)(adp,
+ V_DISPLAY_ON);
}
blanked = FALSE;
}
@@ -106,21 +85,9 @@ fade_saver(video_adapter_t *adp, int blank)
static int
fade_init(video_adapter_t *adp)
{
- switch (adp->va_type) {
- case KD_MONO:
- case KD_HERCULES:
- case KD_CGA:
- /*
- * `fade' saver is not fully implemented for MDA and CGA.
- * It simply blanks the display instead.
- */
- case KD_VGA:
- break;
- case KD_EGA:
- /* EGA is yet to be supported */
- default:
+ if (!ISPALAVAIL(adp->va_flags)
+ && (*vidsw[adp->va_index]->blank_display)(adp, V_DISPLAY_ON) != 0)
return ENODEV;
- }
blanked = FALSE;
return 0;
}
diff --git a/sys/dev/syscons/fire/fire_saver.c b/sys/dev/syscons/fire/fire_saver.c
index aea36a9..db4b80b 100644
--- a/sys/dev/syscons/fire/fire_saver.c
+++ b/sys/dev/syscons/fire/fire_saver.c
@@ -23,7 +23,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: fire_saver.c,v 1.2.2.1 1999/05/10 15:20:30 des Exp $
+ * $Id: fire_saver.c,v 1.4 1999/05/10 15:25:50 des Exp $
*/
/*
@@ -38,11 +38,14 @@
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/syslog.h>
+#include <sys/consio.h>
+#include <sys/fbio.h>
-#include <machine/md_var.h>
#include <machine/random.h>
-#include <saver.h>
+#include <dev/fb/fbreg.h>
+#include <dev/fb/splashreg.h>
+#include <dev/syscons/syscons.h>
#define X_SIZE 320
#define Y_SIZE 200
diff --git a/sys/dev/syscons/green/green_saver.c b/sys/dev/syscons/green/green_saver.c
index 9decd72..103154b 100644
--- a/sys/dev/syscons/green/green_saver.c
+++ b/sys/dev/syscons/green/green_saver.c
@@ -25,93 +25,35 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: green_saver.c,v 1.14 1998/11/04 03:49:38 peter Exp $
+ * $Id: green_saver.c,v 1.15 1999/01/11 03:18:48 yokota Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/module.h>
+#include <sys/consio.h>
+#include <sys/fbio.h>
-#include <dev/fb/vgareg.h>
-
-#include <i386/isa/isa.h>
-
-#include <saver.h>
+#include <dev/fb/fbreg.h>
+#include <dev/fb/splashreg.h>
+#include <dev/syscons/syscons.h>
static int
green_saver(video_adapter_t *adp, int blank)
{
- int crtc_addr;
- u_char val;
-
- crtc_addr = adp->va_crtc_addr;
- if (blank) {
- switch (adp->va_type) {
- case KD_VGA:
- outb(TSIDX, 0x01); val = inb(TSREG);
- outb(TSIDX, 0x01); outb(TSREG, val | 0x20);
- outb(crtc_addr, 0x17); val = inb(crtc_addr + 1);
- outb(crtc_addr + 1, val & ~0x80);
- break;
- case KD_EGA:
- /* not yet done XXX */
- break;
- case KD_CGA:
- outb(crtc_addr + 4, 0x25);
- break;
- case KD_MONO:
- case KD_HERCULES:
- outb(crtc_addr + 4, 0x21);
- break;
- default:
- break;
- }
- }
- else {
- switch (adp->va_type) {
- case KD_VGA:
- outb(TSIDX, 0x01); val = inb(TSREG);
- outb(TSIDX, 0x01); outb(TSREG, val & 0xDF);
- outb(crtc_addr, 0x17); val = inb(crtc_addr + 1);
- outb(crtc_addr + 1, val | 0x80);
- break;
- case KD_EGA:
- /* not yet done XXX */
- break;
- case KD_CGA:
- outb(crtc_addr + 4, 0x2d);
- break;
- case KD_MONO:
- case KD_HERCULES:
- outb(crtc_addr + 4, 0x29);
- break;
- default:
- break;
- }
- }
+ (*vidsw[adp->va_index]->blank_display)(adp,
+ (blank) ? V_DISPLAY_STAND_BY
+ : V_DISPLAY_ON);
return 0;
}
static int
green_init(video_adapter_t *adp)
{
- switch (adp->va_type) {
- case KD_MONO:
- case KD_HERCULES:
- case KD_CGA:
- /*
- * `green' saver is not fully implemented for MDA and CGA.
- * It simply blanks the display instead.
- */
- case KD_VGA:
- break;
- case KD_EGA:
- /* EGA is yet to be supported */
- default:
- return ENODEV;
- }
- return 0;
+ if ((*vidsw[adp->va_index]->blank_display)(adp, V_DISPLAY_ON) == 0)
+ return 0;
+ return ENODEV;
}
static int
diff --git a/sys/dev/syscons/logo/logo_saver.c b/sys/dev/syscons/logo/logo_saver.c
index b6a46ac..24da964 100644
--- a/sys/dev/syscons/logo/logo_saver.c
+++ b/sys/dev/syscons/logo/logo_saver.c
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: logo_saver.c,v 1.5 1999/02/05 12:40:15 des Exp $
+ * $Id: logo_saver.c,v 1.6 1999/04/12 13:34:57 des Exp $
*/
#include <sys/param.h>
@@ -33,8 +33,12 @@
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/syslog.h>
+#include <sys/consio.h>
+#include <sys/fbio.h>
-#include <saver.h>
+#include <dev/fb/fbreg.h>
+#include <dev/fb/splashreg.h>
+#include <dev/syscons/syscons.h>
static u_char *vid;
static int banksize, scrmode, bpsl, scrw, scrh;
@@ -104,6 +108,7 @@ logo_saver(video_adapter_t *adp, int blank)
#endif
blanked++;
vid = (u_char *)adp->va_window;
+ banksize = adp->va_window_size;
bpsl = adp->va_line_width;
splx(pl);
for (i = 0; i < bpsl*scrh; i += banksize) {
@@ -132,7 +137,6 @@ logo_init(video_adapter_t *adp)
return ENODEV;
}
- banksize = info.vi_window_size;
scrw = info.vi_width;
scrh = info.vi_height;
blanked = 0;
diff --git a/sys/dev/syscons/rain/rain_saver.c b/sys/dev/syscons/rain/rain_saver.c
index 9aa7370..200dc59 100644
--- a/sys/dev/syscons/rain/rain_saver.c
+++ b/sys/dev/syscons/rain/rain_saver.c
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: rain_saver.c,v 1.2 1999/01/11 03:18:50 yokota Exp $
+ * $Id: rain_saver.c,v 1.3 1999/04/12 13:34:57 des Exp $
*/
#include <sys/param.h>
@@ -33,10 +33,14 @@
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/syslog.h>
+#include <sys/consio.h>
+#include <sys/fbio.h>
#include <machine/random.h>
-#include <saver.h>
+#include <dev/fb/fbreg.h>
+#include <dev/fb/splashreg.h>
+#include <dev/syscons/syscons.h>
static u_char *vid;
diff --git a/sys/dev/syscons/scgfbrndr.c b/sys/dev/syscons/scgfbrndr.c
new file mode 100644
index 0000000..16c40e2
--- /dev/null
+++ b/sys/dev/syscons/scgfbrndr.c
@@ -0,0 +1,829 @@
+/*-
+ * Copyright (c) 1999 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 as
+ * the first lines of this file unmodified.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id:$
+ */
+
+#include "sc.h"
+#include "vga.h"
+#include "opt_syscons.h"
+#include "opt_vga.h"
+
+#if NSC > 0 && NVGA > 0
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+
+#include <machine/console.h>
+#include <machine/md_var.h>
+
+#include <dev/fb/fbreg.h>
+#include <dev/fb/vgareg.h>
+#include <dev/syscons/syscons.h>
+
+#include <isa/isareg.h>
+
+#ifndef SC_MOUSE_CHAR
+#define SC_MOUSE_CHAR (0xd0)
+#endif
+
+#ifndef SC_RENDER_DEBUG
+#define SC_RENDER_DEBUG 0
+#endif
+
+static vr_clear_t vga_txtclear;
+static vr_draw_border_t vga_txtborder;
+static vr_draw_t vga_txtdraw;
+static vr_set_cursor_t vga_txtcursor_shape;
+static vr_draw_cursor_t vga_txtcursor;
+static vr_blink_cursor_t vga_txtblink;
+#ifndef SC_NO_CUTPASTE
+static vr_draw_mouse_t vga_txtmouse;
+#else
+#define vga_txtmouse (vr_draw_mouse_t *)vga_nop
+#endif
+
+#ifdef SC_PIXEL_MODE
+static vr_clear_t vga_pxlclear;
+static vr_draw_border_t vga_pxlborder;
+static vr_draw_t vga_egadraw;
+static vr_draw_t vga_vgadraw;
+static vr_set_cursor_t vga_pxlcursor_shape;
+static vr_draw_cursor_t vga_pxlcursor;
+static vr_blink_cursor_t vga_pxlblink;
+#ifndef SC_NO_CUTPASTE
+static vr_draw_mouse_t vga_pxlmouse;
+#else
+#define vga_pxlmouse (vr_draw_mouse_t *)vga_nop
+#endif
+#endif /* SC_PIXEL_MODE */
+
+#ifndef SC_NO_MODE_CHANGE
+static vr_draw_border_t vga_grborder;
+#endif
+
+static void vga_nop(scr_stat *scp, ...);
+
+static sc_rndr_sw_t txtrndrsw = {
+ vga_txtclear,
+ vga_txtborder,
+ vga_txtdraw,
+ vga_txtcursor_shape,
+ vga_txtcursor,
+ vga_txtblink,
+ (vr_set_mouse_t *)vga_nop,
+ vga_txtmouse,
+};
+RENDERER(mda, 0, txtrndrsw);
+RENDERER(cga, 0, txtrndrsw);
+RENDERER(ega, 0, txtrndrsw);
+RENDERER(vga, 0, txtrndrsw);
+
+#ifdef SC_PIXEL_MODE
+static sc_rndr_sw_t egarndrsw = {
+ vga_pxlclear,
+ vga_pxlborder,
+ vga_egadraw,
+ vga_pxlcursor_shape,
+ vga_pxlcursor,
+ vga_pxlblink,
+ (vr_set_mouse_t *)vga_nop,
+ vga_pxlmouse,
+};
+RENDERER(ega, PIXEL_MODE, egarndrsw);
+
+static sc_rndr_sw_t vgarndrsw = {
+ vga_pxlclear,
+ vga_pxlborder,
+ vga_vgadraw,
+ vga_pxlcursor_shape,
+ vga_pxlcursor,
+ vga_pxlblink,
+ (vr_set_mouse_t *)vga_nop,
+ vga_pxlmouse,
+};
+RENDERER(vga, PIXEL_MODE, vgarndrsw);
+#endif /* SC_PIXEL_MODE */
+
+#ifndef SC_NO_MODE_CHANGE
+static sc_rndr_sw_t grrndrsw = {
+ (vr_clear_t *)vga_nop,
+ vga_grborder,
+ (vr_draw_t *)vga_nop,
+ (vr_set_cursor_t *)vga_nop,
+ (vr_draw_cursor_t *)vga_nop,
+ (vr_blink_cursor_t *)vga_nop,
+ (vr_set_mouse_t *)vga_nop,
+ (vr_draw_mouse_t *)vga_nop,
+};
+RENDERER(cga, GRAPHICS_MODE, grrndrsw);
+RENDERER(ega, GRAPHICS_MODE, grrndrsw);
+RENDERER(vga, GRAPHICS_MODE, grrndrsw);
+#endif /* SC_NO_MODE_CHANGE */
+
+#ifndef SC_NO_CUTPASTE
+static u_short mouse_and_mask[16] = {
+ 0xc000, 0xe000, 0xf000, 0xf800, 0xfc00, 0xfe00, 0xff00, 0xff80,
+ 0xfe00, 0x1e00, 0x1f00, 0x0f00, 0x0f00, 0x0000, 0x0000, 0x0000
+};
+static u_short mouse_or_mask[16] = {
+ 0x0000, 0x4000, 0x6000, 0x7000, 0x7800, 0x7c00, 0x7e00, 0x6800,
+ 0x0c00, 0x0c00, 0x0600, 0x0600, 0x0000, 0x0000, 0x0000, 0x0000
+};
+#endif
+
+static void
+vga_nop(scr_stat *scp, ...)
+{
+}
+
+/* text mode renderer */
+
+static void
+vga_txtclear(scr_stat *scp, int c, int attr)
+{
+ sc_vtb_clear(&scp->scr, c, attr);
+}
+
+static void
+vga_txtborder(scr_stat *scp, int color)
+{
+ (*vidsw[scp->sc->adapter]->set_border)(scp->sc->adp, color);
+}
+
+static void
+vga_txtdraw(scr_stat *scp, int from, int count, int flip)
+{
+ vm_offset_t p;
+ int c;
+ int a;
+
+ if (from + count > scp->xsize*scp->ysize)
+ count = scp->xsize*scp->ysize - from;
+
+ if (flip) {
+ for (p = sc_vtb_pointer(&scp->scr, from); count-- > 0; ++from) {
+ c = sc_vtb_getc(&scp->vtb, from);
+ a = sc_vtb_geta(&scp->vtb, from);
+ a = (a & 0x8800) | ((a & 0x7000) >> 4)
+ | ((a & 0x0700) << 4);
+ p = sc_vtb_putchar(&scp->scr, p, c, a);
+ }
+ } else {
+ sc_vtb_copy(&scp->vtb, from, &scp->scr, from, count);
+ }
+}
+
+static void
+vga_txtcursor_shape(scr_stat *scp, int base, int height, int blink)
+{
+ if (base < 0 || base >= scp->font_size)
+ return;
+ /* the caller may set height <= 0 in order to disable the cursor */
+#if 0
+ scp->cursor_base = base;
+ scp->cursor_height = height;
+#endif
+ (*vidsw[scp->sc->adapter]->set_hw_cursor_shape)(scp->sc->adp,
+ base, height,
+ scp->font_size, blink);
+}
+
+static void
+vga_txtcursor(scr_stat *scp, int at, int blink, int on, int flip)
+{
+ video_adapter_t *adp;
+ int cursor_attr;
+
+ if (scp->cursor_height <= 0) /* the text cursor is disabled */
+ return;
+
+ adp = scp->sc->adp;
+ if (blink) {
+ scp->status |= VR_CURSOR_BLINK;
+ if (on) {
+ scp->status |= VR_CURSOR_ON;
+ (*vidsw[adp->va_index]->set_hw_cursor)(adp,
+ at%scp->xsize,
+ at/scp->xsize);
+ } else {
+ if (scp->status & VR_CURSOR_ON)
+ (*vidsw[adp->va_index]->set_hw_cursor)(adp,
+ -1, -1);
+ scp->status &= ~VR_CURSOR_ON;
+ }
+ } else {
+ scp->status &= ~VR_CURSOR_BLINK;
+ if (on) {
+ scp->status |= VR_CURSOR_ON;
+ cursor_attr = sc_vtb_geta(&scp->vtb, at);
+ scp->cursor_saveunder_char = sc_vtb_getc(&scp->scr, at);
+ scp->cursor_saveunder_attr = cursor_attr;
+ if ((cursor_attr & 0x7000) == 0x7000) {
+ cursor_attr &= 0x8f00;
+ if ((cursor_attr & 0x0700) == 0)
+ cursor_attr |= 0x0700;
+ } else {
+ cursor_attr |= 0x7000;
+ if ((cursor_attr & 0x0700) == 0x0700)
+ cursor_attr &= 0xf000;
+ }
+ if (flip)
+ cursor_attr = (cursor_attr & 0x8800)
+ | ((cursor_attr & 0x7000) >> 4)
+ | ((cursor_attr & 0x0700) << 4);
+ sc_vtb_putc(&scp->scr, at,
+ sc_vtb_getc(&scp->scr, at),
+ cursor_attr);
+ } else {
+ cursor_attr = scp->cursor_saveunder_attr;
+ if (flip)
+ cursor_attr = (cursor_attr & 0x8800)
+ | ((cursor_attr & 0x7000) >> 4)
+ | ((cursor_attr & 0x0700) << 4);
+ if (scp->status & VR_CURSOR_ON)
+ sc_vtb_putc(&scp->scr, at,
+ scp->cursor_saveunder_char,
+ cursor_attr);
+ scp->status &= ~VR_CURSOR_ON;
+ }
+ }
+}
+
+static void
+vga_txtblink(scr_stat *scp, int at, int flip)
+{
+}
+
+#ifndef SC_NO_CUTPASTE
+
+static void
+draw_txtmouse(scr_stat *scp, int x, int y)
+{
+#ifndef SC_ALT_MOUSE_IMAGE
+ u_char font_buf[128];
+ u_short cursor[32];
+ int pos;
+ int xoffset, yoffset;
+ int crtc_addr;
+ int i;
+
+ /* prepare mousepointer char's bitmaps */
+ pos = (y/scp->font_size - scp->yoff)*scp->xsize + x/8 - scp->xoff;
+ bcopy(scp->font + sc_vtb_getc(&scp->vtb, pos)*scp->font_size,
+ &font_buf[0], scp->font_size);
+ bcopy(scp->font + sc_vtb_getc(&scp->vtb, pos + 1)*scp->font_size,
+ &font_buf[32], scp->font_size);
+ bcopy(scp->font
+ + sc_vtb_getc(&scp->vtb, pos + scp->xsize)*scp->font_size,
+ &font_buf[64], scp->font_size);
+ bcopy(scp->font
+ + sc_vtb_getc(&scp->vtb, pos + scp->xsize + 1)*scp->font_size,
+ &font_buf[96], scp->font_size);
+ for (i = 0; i < scp->font_size; ++i) {
+ cursor[i] = font_buf[i]<<8 | font_buf[i+32];
+ cursor[i + scp->font_size] = font_buf[i+64]<<8 | font_buf[i+96];
+ }
+
+ /* now and-or in the mousepointer image */
+ xoffset = x%8;
+ yoffset = y%scp->font_size;
+ for (i = 0; i < 16; ++i) {
+ cursor[i + yoffset] =
+ (cursor[i + yoffset] & ~(mouse_and_mask[i] >> xoffset))
+ | (mouse_or_mask[i] >> xoffset);
+ }
+ for (i = 0; i < scp->font_size; ++i) {
+ font_buf[i] = (cursor[i] & 0xff00) >> 8;
+ font_buf[i + 32] = cursor[i] & 0xff;
+ font_buf[i + 64] = (cursor[i + scp->font_size] & 0xff00) >> 8;
+ font_buf[i + 96] = cursor[i + scp->font_size] & 0xff;
+ }
+
+#if 1
+ /* wait for vertical retrace to avoid jitter on some videocards */
+ crtc_addr = scp->sc->adp->va_crtc_addr;
+ while (!(inb(crtc_addr + 6) & 0x08)) /* idle */ ;
+#endif
+ (*vidsw[scp->sc->adapter]->load_font)(scp->sc->adp, 0, 32, font_buf,
+ SC_MOUSE_CHAR, 4);
+
+ sc_vtb_putc(&scp->scr, pos, SC_MOUSE_CHAR, sc_vtb_geta(&scp->scr, pos));
+ /* FIXME: may be out of range! */
+ sc_vtb_putc(&scp->scr, pos + scp->xsize, SC_MOUSE_CHAR + 2,
+ sc_vtb_geta(&scp->scr, pos + scp->xsize));
+ if (x < (scp->xsize - 1)*8) {
+ sc_vtb_putc(&scp->scr, pos + 1, SC_MOUSE_CHAR + 1,
+ sc_vtb_geta(&scp->scr, pos + 1));
+ sc_vtb_putc(&scp->scr, pos + scp->xsize + 1, SC_MOUSE_CHAR + 3,
+ sc_vtb_geta(&scp->scr, pos + scp->xsize + 1));
+ }
+#else /* SC_ALT_MOUSE_IMAGE */
+ /* Red, magenta and brown are mapped to green to to keep it readable */
+ static const int col_conv[16] = {
+ 6, 6, 6, 6, 2, 2, 2, 6, 14, 14, 14, 14, 10, 10, 10, 14
+ };
+ int pos;
+ int color;
+ int a;
+
+ pos = (y/scp->font_size - scp->yoff)*scp->xsize + x/8 - scp->xoff;
+ a = sc_vtb_geta(&scp->scr, pos);
+ if (scp->sc->adp->va_flags & V_ADP_COLOR)
+ color = (col_conv[(a & 0xf000) >> 12] << 12)
+ | ((a & 0x0f00) | 0x0800);
+ else
+ color = ((a & 0xf000) >> 4) | ((a & 0x0f00) << 4);
+ sc_vtb_putc(&scp->scr, pos, sc_vtb_getc(&scp->scr, pos), color);
+#endif /* SC_ALT_MOUSE_IMAGE */
+}
+
+static void
+remove_txtmouse(scr_stat *scp, int x, int y)
+{
+}
+
+static void
+vga_txtmouse(scr_stat *scp, int x, int y, int on)
+{
+ if (on)
+ draw_txtmouse(scp, x, y);
+ else
+ remove_txtmouse(scp, x, y);
+}
+
+#endif /* SC_NO_CUTPASTE */
+
+#ifdef SC_PIXEL_MODE
+
+/* pixel (raster text) mode renderer */
+
+static void
+vga_pxlclear(scr_stat *scp, int c, int attr)
+{
+ vm_offset_t p;
+ int line_width;
+ int lines;
+ int i;
+
+ /* XXX: we are just filling the screen with the background color... */
+ outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */
+ outw(GDCIDX, 0x0003); /* data rotate/function select */
+ outw(GDCIDX, 0x0f01); /* set/reset enable */
+ outw(GDCIDX, 0xff08); /* bit mask */
+ outw(GDCIDX, ((attr & 0xf000) >> 4) | 0x00); /* set/reset */
+ line_width = scp->sc->adp->va_line_width;
+ lines = scp->ysize*scp->font_size;
+ p = scp->sc->adp->va_window + line_width*scp->yoff*scp->font_size
+ + scp->xoff;
+ for (i = 0; i < lines; ++i) {
+ bzero_io((void *)p, scp->xsize);
+ p += line_width;
+ }
+ outw(GDCIDX, 0x0000); /* set/reset */
+ outw(GDCIDX, 0x0001); /* set/reset enable */
+}
+
+static void
+vga_pxlborder(scr_stat *scp, int color)
+{
+ vm_offset_t p;
+ int line_width;
+ int i;
+
+ (*vidsw[scp->sc->adapter]->set_border)(scp->sc->adp, color);
+
+ outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */
+ outw(GDCIDX, 0x0003); /* data rotate/function select */
+ outw(GDCIDX, 0x0f01); /* set/reset enable */
+ outw(GDCIDX, 0xff08); /* bit mask */
+ outw(GDCIDX, (color << 8) | 0x00); /* set/reset */
+ line_width = scp->sc->adp->va_line_width;
+ p = scp->sc->adp->va_window;
+ if (scp->yoff > 0) {
+ bzero_io((void *)p, line_width*scp->yoff*scp->font_size);
+ bzero_io((void *)(p + line_width*(scp->yoff + scp->ysize)
+ *scp->font_size),
+ line_width*(scp->ypixel
+ - (scp->yoff + scp->ysize)*scp->font_size));
+ }
+ if (scp->xoff > 0) {
+ for (i = 0; i < scp->ysize*scp->font_size; ++i) {
+ bzero_io((void *)(p + line_width
+ *(scp->yoff*scp->font_size + i)),
+ scp->xoff);
+ bzero_io((void *)(p + line_width
+ *(scp->yoff*scp->font_size + i)
+ + scp->xoff + scp->xsize),
+ scp->xpixel/8 - scp->xoff - scp->xsize);
+ }
+ }
+ outw(GDCIDX, 0x0000); /* set/reset */
+ outw(GDCIDX, 0x0001); /* set/reset enable */
+}
+
+static void
+vga_egadraw(scr_stat *scp, int from, int count, int flip)
+{
+ vm_offset_t d;
+ vm_offset_t e;
+ u_char *f;
+ u_short bg;
+ u_short col1, col2;
+ int line_width;
+ int i, j;
+ int a;
+ u_char c;
+
+ line_width = scp->sc->adp->va_line_width;
+ d = scp->sc->adp->va_window
+ + scp->xoff
+ + scp->yoff*scp->font_size*line_width
+ + (from%scp->xsize)
+ + scp->font_size*line_width*(from/scp->xsize);
+
+ outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */
+ outw(GDCIDX, 0x0003); /* data rotate/function select */
+ outw(GDCIDX, 0x0f01); /* set/reset enable */
+ bg = -1;
+ if (from + count > scp->xsize*scp->ysize)
+ count = scp->xsize*scp->ysize - from;
+ for (i = from; count-- > 0; ++i) {
+ a = sc_vtb_geta(&scp->vtb, i);
+ if (flip) {
+ col1 = ((a & 0x7000) >> 4) | (a & 0x0800);
+ col2 = ((a & 0x8000) >> 4) | (a & 0x0700);
+ } else {
+ col1 = (a & 0x0f00);
+ col2 = (a & 0xf000) >> 4;
+ }
+ /* set background color in EGA/VGA latch */
+ if (bg != col2) {
+ bg = col2;
+ outw(GDCIDX, bg | 0x00); /* set/reset */
+ outw(GDCIDX, 0xff08); /* bit mask */
+ writeb(d, 0);
+ c = readb(d); /* set bg color in the latch */
+ }
+ /* foreground color */
+ outw(GDCIDX, col1 | 0x00); /* set/reset */
+ e = d;
+ f = &(scp->font[sc_vtb_getc(&scp->vtb, i)*scp->font_size]);
+ for (j = 0; j < scp->font_size; ++j, ++f) {
+ outw(GDCIDX, (*f << 8) | 0x08); /* bit mask */
+ writeb(e, 0);
+ e += line_width;
+ }
+ ++d;
+ if ((i % scp->xsize) == scp->xsize - 1)
+ d += scp->xoff*2
+ + (scp->font_size - 1)*line_width;
+ }
+ outw(GDCIDX, 0x0000); /* set/reset */
+ outw(GDCIDX, 0x0001); /* set/reset enable */
+ outw(GDCIDX, 0xff08); /* bit mask */
+}
+
+static void
+vga_vgadraw(scr_stat *scp, int from, int count, int flip)
+{
+ vm_offset_t d;
+ vm_offset_t e;
+ u_char *f;
+ u_short bg;
+ u_short col1, col2;
+ int line_width;
+ int i, j;
+ int a;
+ u_char c;
+
+ line_width = scp->sc->adp->va_line_width;
+ d = scp->sc->adp->va_window
+ + scp->xoff
+ + scp->yoff*scp->font_size*line_width
+ + (from%scp->xsize)
+ + scp->font_size*line_width*(from/scp->xsize);
+
+ outw(GDCIDX, 0x0305); /* read mode 0, write mode 3 */
+ outw(GDCIDX, 0x0003); /* data rotate/function select */
+ outw(GDCIDX, 0x0f01); /* set/reset enable */
+ outw(GDCIDX, 0xff08); /* bit mask */
+ bg = -1;
+ if (from + count > scp->xsize*scp->ysize)
+ count = scp->xsize*scp->ysize - from;
+ for (i = from; count-- > 0; ++i) {
+ a = sc_vtb_geta(&scp->vtb, i);
+ if (flip) {
+ col1 = ((a & 0x7000) >> 4) | (a & 0x0800);
+ col2 = ((a & 0x8000) >> 4) | (a & 0x0700);
+ } else {
+ col1 = (a & 0x0f00);
+ col2 = (a & 0xf000) >> 4;
+ }
+ /* set background color in EGA/VGA latch */
+ if (bg != col2) {
+ bg = col2;
+ outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */
+ outw(GDCIDX, bg | 0x00); /* set/reset */
+ writeb(d, 0);
+ c = readb(d); /* set bg color in the latch */
+ outw(GDCIDX, 0x0305); /* read mode 0, write mode 3 */
+ }
+ /* foreground color */
+ outw(GDCIDX, col1 | 0x00); /* set/reset */
+ e = d;
+ f = &(scp->font[sc_vtb_getc(&scp->vtb, i)*scp->font_size]);
+ for (j = 0; j < scp->font_size; ++j, ++f) {
+ writeb(e, *f);
+ e += line_width;
+ }
+ ++d;
+ if ((i % scp->xsize) == scp->xsize - 1)
+ d += scp->xoff*2
+ + (scp->font_size - 1)*line_width;
+ }
+ outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */
+ outw(GDCIDX, 0x0000); /* set/reset */
+ outw(GDCIDX, 0x0001); /* set/reset enable */
+}
+
+static void
+vga_pxlcursor_shape(scr_stat *scp, int base, int height, int blink)
+{
+ if (base < 0 || base >= scp->font_size)
+ return;
+ /* the caller may set height <= 0 in order to disable the cursor */
+#if 0
+ scp->cursor_base = base;
+ scp->cursor_height = height;
+#endif
+}
+
+static void
+draw_pxlcursor(scr_stat *scp, int at, int on, int flip)
+{
+ vm_offset_t d;
+ u_char *f;
+ int line_width;
+ int height;
+ int col;
+ int a;
+ int i;
+ u_char c;
+
+ line_width = scp->sc->adp->va_line_width;
+ d = scp->sc->adp->va_window
+ + scp->xoff
+ + scp->yoff*scp->font_size*line_width
+ + (at%scp->xsize)
+ + scp->font_size*line_width*(at/scp->xsize)
+ + (scp->font_size - scp->cursor_base - 1)*line_width;
+
+ outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */
+ outw(GDCIDX, 0x0003); /* data rotate/function select */
+ outw(GDCIDX, 0x0f01); /* set/reset enable */
+ /* set background color in EGA/VGA latch */
+ a = sc_vtb_geta(&scp->vtb, at);
+ if (flip)
+ col = (on) ? ((a & 0xf000) >> 4) : (a & 0x0f00);
+ else
+ col = (on) ? (a & 0x0f00) : ((a & 0xf000) >> 4);
+ outw(GDCIDX, col | 0x00); /* set/reset */
+ outw(GDCIDX, 0xff08); /* bit mask */
+ writeb(d, 0);
+ c = readb(d); /* set bg color in the latch */
+ /* foreground color */
+ if (flip)
+ col = (on) ? (a & 0x0f00) : ((a & 0xf000) >> 4);
+ else
+ col = (on) ? ((a & 0xf000) >> 4) : (a & 0x0f00);
+ outw(GDCIDX, col | 0x00); /* set/reset */
+ f = &(scp->font[sc_vtb_getc(&scp->vtb, at)*scp->font_size
+ + scp->font_size - scp->cursor_base - 1]);
+ height = imin(scp->cursor_height, scp->font_size);
+ for (i = 0; i < height; ++i, --f) {
+ outw(GDCIDX, (*f << 8) | 0x08); /* bit mask */
+ writeb(d, 0);
+ d -= line_width;
+ }
+ outw(GDCIDX, 0x0000); /* set/reset */
+ outw(GDCIDX, 0x0001); /* set/reset enable */
+ outw(GDCIDX, 0xff08); /* bit mask */
+}
+
+static void
+vga_pxlcursor(scr_stat *scp, int at, int blink, int on, int flip)
+{
+ if (scp->cursor_height <= 0) /* the text cursor is disabled */
+ return;
+
+ if (on) {
+ scp->status |= VR_CURSOR_ON;
+ draw_pxlcursor(scp, at, on, flip);
+ } else {
+ if (scp->status & VR_CURSOR_ON)
+ draw_pxlcursor(scp, at, on, flip);
+ scp->status &= ~VR_CURSOR_ON;
+ }
+ if (blink)
+ scp->status |= VR_CURSOR_BLINK;
+ else
+ scp->status &= ~VR_CURSOR_BLINK;
+}
+
+static void
+vga_pxlblink(scr_stat *scp, int at, int flip)
+{
+ static int blinkrate = 0;
+
+ if (!(scp->status & VR_CURSOR_BLINK))
+ return;
+ if (!(++blinkrate & 4))
+ return;
+ blinkrate = 0;
+ scp->status ^= VR_CURSOR_ON;
+ draw_pxlcursor(scp, at, scp->status & VR_CURSOR_ON, flip);
+}
+
+#ifndef SC_NO_CUTPASTE
+
+static void
+draw_pxlmouse(scr_stat *scp, int x, int y)
+{
+ vm_offset_t p;
+ int line_width;
+ int xoff, yoff;
+ int ymax;
+ u_short m;
+ int i, j;
+
+ line_width = scp->sc->adp->va_line_width;
+ xoff = (x - scp->xoff*8)%8;
+ yoff = y - (y/line_width)*line_width;
+ ymax = imin(y + 16, scp->ypixel);
+
+ outw(GDCIDX, 0x0805); /* read mode 1, write mode 0 */
+ outw(GDCIDX, 0x0001); /* set/reset enable */
+ outw(GDCIDX, 0x0002); /* color compare */
+ outw(GDCIDX, 0x0007); /* color don't care */
+ outw(GDCIDX, 0xff08); /* bit mask */
+ outw(GDCIDX, 0x0803); /* data rotate/function select (and) */
+ p = scp->sc->adp->va_window + line_width*y + x/8;
+ if (x < scp->xpixel - 16) {
+ for (i = y, j = 0; i < ymax; ++i, ++j) {
+ m = ~(mouse_and_mask[j] >> xoff);
+#ifdef __i386__
+ *(u_char *)p &= m >> 8;
+ *(u_char *)(p + 1) &= m;
+#elif defined(__alpha__)
+ writeb(p, readb(p) & (m >> 8));
+ writeb(p + 1, readb(p + 1) & (m >> 8));
+#endif
+ p += line_width;
+ }
+ } else {
+ xoff += 8;
+ for (i = y, j = 0; i < ymax; ++i, ++j) {
+ m = ~(mouse_and_mask[j] >> xoff);
+#ifdef __i386__
+ *(u_char *)p &= m;
+#elif defined(__alpha__)
+ writeb(p, readb(p) & (m >> 8));
+#endif
+ p += line_width;
+ }
+ }
+ outw(GDCIDX, 0x1003); /* data rotate/function select (or) */
+ p = scp->sc->adp->va_window + line_width*y + x/8;
+ if (x < scp->xpixel - 16) {
+ for (i = y, j = 0; i < ymax; ++i, ++j) {
+ m = mouse_or_mask[j] >> xoff;
+#ifdef __i386__
+ *(u_char *)p &= m >> 8;
+ *(u_char *)(p + 1) &= m;
+#elif defined(__alpha__)
+ writeb(p, readb(p) & (m >> 8));
+ writeb(p + 1, readb(p + 1) & (m >> 8));
+#endif
+ p += line_width;
+ }
+ } else {
+ for (i = y, j = 0; i < ymax; ++i, ++j) {
+ m = mouse_or_mask[j] >> xoff;
+#ifdef __i386__
+ *(u_char *)p &= m;
+#elif defined(__alpha__)
+ writeb(p, readb(p) & (m >> 8));
+#endif
+ p += line_width;
+ }
+ }
+ outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */
+ outw(GDCIDX, 0x0003); /* data rotate/function select */
+}
+
+static void
+remove_pxlmouse(scr_stat *scp, int x, int y)
+{
+ vm_offset_t p;
+ int col, row;
+ int pos;
+ int line_width;
+ int ymax;
+ int i;
+
+ /* erase the mouse cursor image */
+ col = x/8 - scp->xoff;
+ row = y/scp->font_size - scp->yoff;
+ pos = row*scp->xsize + col;
+ i = (col < scp->xsize - 1) ? 2 : 1;
+ (*scp->rndr->draw)(scp, pos, i, FALSE);
+ if (row < scp->ysize - 1)
+ (*scp->rndr->draw)(scp, pos + scp->xsize, i, FALSE);
+
+ /* paint border if necessary */
+ line_width = scp->sc->adp->va_line_width;
+ outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */
+ outw(GDCIDX, 0x0003); /* data rotate/function select */
+ outw(GDCIDX, 0x0f01); /* set/reset enable */
+ outw(GDCIDX, 0xff08); /* bit mask */
+ outw(GDCIDX, (scp->border << 8) | 0x00); /* set/reset */
+ if (row == scp->ysize - 1) {
+ i = (scp->ysize + scp->yoff)*scp->font_size;
+ ymax = imin(i + scp->font_size, scp->ypixel);
+ p = scp->sc->adp->va_window + i*line_width + scp->xoff + col;
+ if (col < scp->xsize - 1) {
+ for (; i < ymax; ++i) {
+ writeb(p, 0);
+ writeb(p + 1, 0);
+ p += line_width;
+ }
+ } else {
+ for (; i < ymax; ++i) {
+ writeb(p, 0);
+ p += line_width;
+ }
+ }
+ }
+ if ((col == scp->xsize - 1) && (scp->xoff > 0)) {
+ i = (row + scp->yoff)*scp->font_size;
+ ymax = imin(i + scp->font_size*2, scp->ypixel);
+ p = scp->sc->adp->va_window + i*line_width
+ + scp->xoff + scp->xsize;
+ for (; i < ymax; ++i) {
+ writeb(p, 0);
+ p += line_width;
+ }
+ }
+ outw(GDCIDX, 0x0000); /* set/reset */
+ outw(GDCIDX, 0x0001); /* set/reset enable */
+}
+
+static void
+vga_pxlmouse(scr_stat *scp, int x, int y, int on)
+{
+ if (on)
+ draw_pxlmouse(scp, x, y);
+ else
+ remove_pxlmouse(scp, x, y);
+}
+
+#endif /* SC_NO_CUTPASTE */
+#endif /* SC_PIXEL_MODE */
+
+#ifndef SC_NO_MODE_CHANGE
+
+/* graphics mode renderer */
+
+static void
+vga_grborder(scr_stat *scp, int color)
+{
+ (*vidsw[scp->sc->adapter]->set_border)(scp->sc->adp, color);
+}
+
+#endif
+
+#endif /* NSC > 0 && NVGA > 0 */
diff --git a/sys/dev/syscons/schistory.c b/sys/dev/syscons/schistory.c
new file mode 100644
index 0000000..765733c
--- /dev/null
+++ b/sys/dev/syscons/schistory.c
@@ -0,0 +1,222 @@
+/*-
+ * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
+ * 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,
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id:$
+ */
+
+#include "sc.h"
+#include "opt_syscons.h"
+
+#if NSC > 0
+
+#ifndef SC_NO_HISTORY
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/tty.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+
+#include <machine/console.h>
+
+#include <dev/syscons/syscons.h>
+
+#if !defined(SC_MAX_HISTORY_SIZE)
+#define SC_MAX_HISTORY_SIZE (1000 * MAXCONS * NSC)
+#endif
+
+#if !defined(SC_HISTORY_SIZE)
+#define SC_HISTORY_SIZE (ROW * 4)
+#endif
+
+#if (SC_HISTORY_SIZE * MAXCONS * NSC) > SC_MAX_HISTORY_SIZE
+#undef SC_MAX_HISTORY_SIZE
+#define SC_MAX_HISTORY_SIZE (SC_HISTORY_SIZE * MAXCONS * NSC)
+#endif
+
+/* local variables */
+static int extra_history_size
+ = SC_MAX_HISTORY_SIZE - SC_HISTORY_SIZE*MAXCONS;
+
+/* local functions */
+static void history_to_screen(scr_stat *scp);
+
+/* allocate a history buffer */
+int
+sc_alloc_history_buffer(scr_stat *scp, int lines, int wait)
+{
+ /*
+ * 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.
+ */
+ sc_vtb_t *history;
+ int cur_lines; /* current buffer size */
+ int min_lines; /* guaranteed buffer size */
+
+ if (lines <= 0)
+ lines = SC_HISTORY_SIZE; /* use the default value */
+ lines = imax(lines, scp->ysize);
+ min_lines = imax(SC_HISTORY_SIZE, scp->ysize);
+
+ history = scp->history;
+ scp->history = NULL;
+ if (history == NULL) {
+ cur_lines = 0;
+ } else {
+ cur_lines = sc_vtb_rows(history);
+ if (cur_lines > min_lines)
+ extra_history_size += cur_lines - min_lines;
+ sc_vtb_destroy(history);
+ }
+
+ if (lines > min_lines)
+ extra_history_size -= lines - min_lines;
+ history = (sc_vtb_t *)malloc(sizeof(*history),
+ M_DEVBUF, (wait) ? M_WAITOK : M_NOWAIT);
+ if (history != NULL)
+ sc_vtb_init(history, VTB_RINGBUFFER, scp->xsize, lines,
+ NULL, wait);
+ scp->history_pos = 0;
+ scp->history = history;
+
+ return 0;
+}
+
+/* copy entire screen into the top of the history buffer */
+void
+sc_hist_save(scr_stat *scp)
+{
+ sc_vtb_append(&scp->vtb, 0, scp->history, scp->xsize*scp->ysize);
+ scp->history_pos = sc_vtb_tail(scp->history);
+}
+
+/* restore the screen by copying from the history buffer */
+int
+sc_hist_restore(scr_stat *scp)
+{
+ int ret;
+
+ if (scp->history_pos != sc_vtb_tail(scp->history)) {
+ scp->history_pos = sc_vtb_tail(scp->history);
+ history_to_screen(scp);
+ ret = 0;
+ } else {
+ ret = 1;
+ }
+ sc_vtb_seek(scp->history, sc_vtb_pos(scp->history,
+ sc_vtb_tail(scp->history),
+ -scp->xsize*scp->ysize));
+ return ret;
+}
+
+/* copy screen-full of saved lines */
+static void
+history_to_screen(scr_stat *scp)
+{
+ int pos;
+ int i;
+
+ pos = scp->history_pos;
+ for (i = 1; i <= scp->ysize; ++i) {
+ pos = sc_vtb_pos(scp->history, pos, -scp->xsize);
+ sc_vtb_copy(scp->history, pos,
+ &scp->vtb, scp->xsize*(scp->ysize - i),
+ scp->xsize);
+ }
+ mark_all(scp);
+}
+
+/* go to the tail of the history buffer */
+void
+sc_hist_home(scr_stat *scp)
+{
+ scp->history_pos = sc_vtb_tail(scp->history);
+ history_to_screen(scp);
+}
+
+/* go to the top of the history buffer */
+void
+sc_hist_end(scr_stat *scp)
+{
+ scp->history_pos = sc_vtb_pos(scp->history, sc_vtb_tail(scp->history),
+ scp->xsize*scp->ysize);
+ history_to_screen(scp);
+}
+
+/* move one line up */
+int
+sc_hist_up_line(scr_stat *scp)
+{
+ if (sc_vtb_pos(scp->history, scp->history_pos, -(scp->xsize*scp->ysize))
+ == sc_vtb_tail(scp->history))
+ return -1;
+ scp->history_pos = sc_vtb_pos(scp->history, scp->history_pos,
+ -scp->xsize);
+ history_to_screen(scp);
+ return 0;
+}
+
+/* move one line down */
+int
+sc_hist_down_line(scr_stat *scp)
+{
+ if (scp->history_pos == sc_vtb_tail(scp->history))
+ return -1;
+ scp->history_pos = sc_vtb_pos(scp->history, scp->history_pos,
+ scp->xsize);
+ history_to_screen(scp);
+ return 0;
+}
+
+int
+sc_hist_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag,
+ struct proc *p)
+{
+ scr_stat *scp;
+
+ switch (cmd) {
+
+ case CONS_HISTORY: /* set history size */
+ scp = sc_get_scr_stat(tp->t_dev);
+ if (*(int *)data <= 0)
+ return EINVAL;
+ if (scp->status & BUFFER_SAVED)
+ return EBUSY;
+ return sc_alloc_history_buffer(scp,
+ imax(*(int *)data, scp->ysize),
+ TRUE);
+ }
+
+ return ENOIOCTL;
+}
+
+#endif /* SC_NO_HISTORY */
+
+#endif /* NSC */
diff --git a/sys/dev/syscons/scmouse.c b/sys/dev/syscons/scmouse.c
new file mode 100644
index 0000000..8d8dc67
--- /dev/null
+++ b/sys/dev/syscons/scmouse.c
@@ -0,0 +1,1083 @@
+/*-
+ * Copyright (c) 1999 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 as
+ * the first lines of this file unmodified.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id:$
+ */
+
+#include "sc.h"
+#include "opt_syscons.h"
+
+#if NSC > 0
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/conf.h>
+#include <sys/signalvar.h>
+#include <sys/proc.h>
+#include <sys/tty.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+
+#include <machine/console.h>
+#include <machine/mouse.h>
+
+#include <dev/syscons/syscons.h>
+
+#define SC_WAKEUP_DELTA 20
+
+/* for backward compatibility */
+#define OLD_CONS_MOUSECTL _IOWR('c', 10, old_mouse_info_t)
+
+typedef struct old_mouse_data {
+ int x;
+ int y;
+ int buttons;
+} old_mouse_data_t;
+
+typedef struct old_mouse_info {
+ int operation;
+ union {
+ struct old_mouse_data data;
+ struct mouse_mode mode;
+ } u;
+} old_mouse_info_t;
+
+/* local variables */
+#ifndef SC_NO_SYSMOUSE
+static int mouse_level; /* sysmouse protocol level */
+static mousestatus_t mouse_status = { 0, 0, 0, 0, 0, 0 };
+static int cut_buffer_size;
+static u_char *cut_buffer;
+#endif /* SC_NO_SYSMOUE */
+
+/* local functions */
+#ifndef SC_NO_SYSMOUSE
+static void set_mouse_pos(scr_stat *scp);
+#ifndef SC_NO_CUTPASTE
+static int skip_spc_right(scr_stat *scp, int p);
+static int skip_spc_left(scr_stat *scp, int p);
+static void mouse_cut(scr_stat *scp);
+static void mouse_cut_start(scr_stat *scp);
+static void mouse_cut_end(scr_stat *scp);
+static void mouse_cut_word(scr_stat *scp);
+static void mouse_cut_line(scr_stat *scp);
+static void mouse_cut_extend(scr_stat *scp);
+static void mouse_paste(scr_stat *scp);
+#endif /* SC_NO_CUTPASTE */
+#endif /* SC_NO_SYSMOUE */
+
+#ifndef SC_NO_CUTPASTE
+/* allocate a cut buffer */
+void
+sc_alloc_cut_buffer(scr_stat *scp, int wait)
+{
+ u_char *p;
+
+ if ((cut_buffer == NULL)
+ || (cut_buffer_size < scp->xsize * scp->ysize + 1)) {
+ p = cut_buffer;
+ cut_buffer = NULL;
+ if (p != NULL)
+ free(p, M_DEVBUF);
+ cut_buffer_size = scp->xsize * scp->ysize + 1;
+ p = (u_char *)malloc(cut_buffer_size,
+ M_DEVBUF, (wait) ? M_WAITOK : M_NOWAIT);
+ if (p != NULL)
+ p[0] = '\0';
+ cut_buffer = p;
+ }
+}
+#endif /* SC_NO_CUTPASTE */
+
+#ifndef SC_NO_SYSMOUSE
+
+/* modify the sysmouse software level */
+void
+sc_mouse_set_level(int level)
+{
+ mouse_level = level;
+}
+
+/* move mouse */
+void
+sc_mouse_move(scr_stat *scp, int x, int y)
+{
+ int s;
+
+ s = spltty();
+ scp->mouse_xpos = x;
+ scp->mouse_ypos = y;
+ scp->mouse_pos = scp->mouse_oldpos =
+ (y/scp->font_size - scp->yoff)*scp->xsize + x/8 - scp->xoff;
+ splx(s);
+}
+
+/* adjust mouse position */
+static void
+set_mouse_pos(scr_stat *scp)
+{
+ static int last_xpos = -1, last_ypos = -1;
+
+ if (scp->mouse_xpos < scp->xoff*8)
+ scp->mouse_xpos = scp->xoff*8;
+ if (scp->mouse_ypos < scp->yoff*scp->font_size)
+ scp->mouse_ypos = scp->yoff*scp->font_size;
+ if (ISGRAPHSC(scp)) {
+ if (scp->mouse_xpos > scp->xpixel-1)
+ scp->mouse_xpos = scp->xpixel-1;
+ if (scp->mouse_ypos > scp->ypixel-1)
+ scp->mouse_ypos = scp->ypixel-1;
+ return;
+ } else {
+ if (scp->mouse_xpos > (scp->xsize + scp->xoff)*8 - 1)
+ scp->mouse_xpos = (scp->xsize + scp->xoff)*8 - 1;
+ if (scp->mouse_ypos > (scp->ysize + scp->yoff)*scp->font_size - 1)
+ scp->mouse_ypos = (scp->ysize + scp->yoff)*scp->font_size - 1;
+ }
+
+ if (scp->mouse_xpos != last_xpos || scp->mouse_ypos != last_ypos) {
+ scp->status |= MOUSE_MOVED;
+ scp->mouse_pos =
+ (scp->mouse_ypos/scp->font_size - scp->yoff)*scp->xsize
+ + scp->mouse_xpos/8 - scp->xoff;
+#ifndef SC_NO_CUTPASTE
+ if ((scp->status & MOUSE_VISIBLE) && (scp->status & MOUSE_CUTTING))
+ mouse_cut(scp);
+#endif
+ }
+}
+
+#ifndef SC_NO_CUTPASTE
+
+void
+sc_draw_mouse_image(scr_stat *scp)
+{
+ if (ISGRAPHSC(scp))
+ return;
+
+ ++scp->sc->videoio_in_progress;
+ (*scp->rndr->draw_mouse)(scp, scp->mouse_xpos, scp->mouse_ypos, TRUE);
+ scp->mouse_oldpos = scp->mouse_pos;
+ --scp->sc->videoio_in_progress;
+}
+
+void
+sc_remove_mouse_image(scr_stat *scp)
+{
+ int size;
+ int i;
+
+ if (ISGRAPHSC(scp))
+ return;
+
+ ++scp->sc->videoio_in_progress;
+ (*scp->rndr->draw_mouse)(scp,
+ (scp->mouse_oldpos%scp->xsize + scp->xoff)*8,
+ (scp->mouse_oldpos/scp->xsize + scp->yoff)
+ * scp->font_size,
+ FALSE);
+ size = scp->xsize*scp->ysize;
+ i = scp->mouse_oldpos;
+ mark_for_update(scp, i);
+ mark_for_update(scp, i);
+#ifndef PC98
+ if (i + scp->xsize + 1 < size) {
+ mark_for_update(scp, i + scp->xsize + 1);
+ } else if (i + scp->xsize < size) {
+ mark_for_update(scp, i + scp->xsize);
+ } else if (i + 1 < size) {
+ mark_for_update(scp, i + 1);
+ }
+#endif /* PC98 */
+ --scp->sc->videoio_in_progress;
+}
+
+int
+sc_inside_cutmark(scr_stat *scp, int pos)
+{
+ int start;
+ int end;
+
+ if (scp->mouse_cut_end < 0)
+ return FALSE;
+ if (scp->mouse_cut_start <= scp->mouse_cut_end) {
+ start = scp->mouse_cut_start;
+ end = scp->mouse_cut_end;
+ } else {
+ start = scp->mouse_cut_end;
+ end = scp->mouse_cut_start - 1;
+ }
+ return ((start <= pos) && (pos <= end));
+}
+
+void
+sc_remove_cutmarking(scr_stat *scp)
+{
+ int s;
+
+ s = spltty();
+ if (scp->mouse_cut_end >= 0) {
+ mark_for_update(scp, scp->mouse_cut_start);
+ mark_for_update(scp, scp->mouse_cut_end);
+ }
+ scp->mouse_cut_start = scp->xsize*scp->ysize;
+ scp->mouse_cut_end = -1;
+ splx(s);
+ scp->status &= ~MOUSE_CUTTING;
+}
+
+void
+sc_remove_all_cutmarkings(sc_softc_t *sc)
+{
+ int i;
+
+ /* delete cut markings in all vtys */
+ for (i = 0; i < sc->vtys; ++i) {
+ if (sc->console[i] == NULL)
+ continue;
+ sc_remove_cutmarking(sc->console[i]);
+ }
+}
+
+void
+sc_remove_all_mouse(sc_softc_t *sc)
+{
+ int i;
+
+ for (i = 0; i < sc->vtys; ++i) {
+ if (sc->console[i] == NULL)
+ continue;
+ if (sc->console[i]->status & MOUSE_VISIBLE) {
+ sc->console[i]->status &= ~MOUSE_VISIBLE;
+ mark_all(sc->console[i]);
+ }
+ }
+}
+
+#define isspace(c) (((c) & 0xff) == ' ')
+
+/* skip spaces to right */
+static int
+skip_spc_right(scr_stat *scp, int p)
+{
+ int c;
+ int i;
+
+ for (i = p % scp->xsize; i < scp->xsize; ++i) {
+ c = sc_vtb_getc(&scp->vtb, p);
+ if (!isspace(c))
+ break;
+ ++p;
+ }
+ return i;
+}
+
+/* skip spaces to left */
+static int
+skip_spc_left(scr_stat *scp, int p)
+{
+ int c;
+ int i;
+
+ for (i = p-- % scp->xsize - 1; i >= 0; --i) {
+ c = sc_vtb_getc(&scp->vtb, p);
+ if (!isspace(c))
+ break;
+ --p;
+ }
+ return i;
+}
+
+/* copy marked region to the cut buffer */
+static void
+mouse_cut(scr_stat *scp)
+{
+ int start;
+ int end;
+ int from;
+ int to;
+ int blank;
+ int c;
+ int p;
+ int s;
+ int i;
+
+ start = scp->mouse_cut_start;
+ end = scp->mouse_cut_end;
+ if (scp->mouse_pos >= start) {
+ from = start;
+ to = end = scp->mouse_pos;
+ } else {
+ from = end = scp->mouse_pos;
+ to = start - 1;
+ }
+ for (p = from, i = blank = 0; p <= to; ++p) {
+ cut_buffer[i] = sc_vtb_getc(&scp->vtb, p);
+ /* remember the position of the last non-space char */
+ if (!isspace(cut_buffer[i++]))
+ blank = i; /* the first space after the last non-space */
+ /* trim trailing blank when crossing lines */
+ if ((p % scp->xsize) == (scp->xsize - 1)) {
+ cut_buffer[blank] = '\r';
+ i = blank + 1;
+ }
+ }
+ cut_buffer[i] = '\0';
+
+ /* scan towards the end of the last line */
+ --p;
+ for (i = p % scp->xsize; i < scp->xsize; ++i) {
+ c = sc_vtb_getc(&scp->vtb, p);
+ if (!isspace(c))
+ break;
+ ++p;
+ }
+ /* if there is nothing but blank chars, trim them, but mark towards eol */
+ if (i >= scp->xsize) {
+ if (end >= start)
+ to = end = p - 1;
+ else
+ to = start = p;
+ cut_buffer[blank++] = '\r';
+ cut_buffer[blank] = '\0';
+ }
+
+ /* remove the current marking */
+ s = spltty();
+ if (scp->mouse_cut_start <= scp->mouse_cut_end) {
+ mark_for_update(scp, scp->mouse_cut_start);
+ mark_for_update(scp, scp->mouse_cut_end);
+ } else if (scp->mouse_cut_end >= 0) {
+ mark_for_update(scp, scp->mouse_cut_end);
+ mark_for_update(scp, scp->mouse_cut_start);
+ }
+
+ /* mark the new region */
+ scp->mouse_cut_start = start;
+ scp->mouse_cut_end = end;
+ mark_for_update(scp, from);
+ mark_for_update(scp, to);
+ splx(s);
+}
+
+/* a mouse button is pressed, start cut operation */
+static void
+mouse_cut_start(scr_stat *scp)
+{
+ int i;
+ int j;
+ int s;
+
+ if (scp->status & MOUSE_VISIBLE) {
+ i = scp->mouse_cut_start;
+ j = scp->mouse_cut_end;
+ sc_remove_all_cutmarkings(scp->sc);
+ if (scp->mouse_pos == i && i == j) {
+ cut_buffer[0] = '\0';
+ } else if (skip_spc_right(scp, scp->mouse_pos) >= scp->xsize) {
+ /* if the pointer is on trailing blank chars, mark towards eol */
+ i = skip_spc_left(scp, scp->mouse_pos) + 1;
+ s = spltty();
+ scp->mouse_cut_start =
+ (scp->mouse_pos / scp->xsize) * scp->xsize + i;
+ scp->mouse_cut_end =
+ (scp->mouse_pos / scp->xsize + 1) * scp->xsize - 1;
+ splx(s);
+ cut_buffer[0] = '\r';
+ cut_buffer[1] = '\0';
+ scp->status |= MOUSE_CUTTING;
+ } else {
+ s = spltty();
+ scp->mouse_cut_start = scp->mouse_pos;
+ scp->mouse_cut_end = scp->mouse_cut_start;
+ splx(s);
+ cut_buffer[0] = sc_vtb_getc(&scp->vtb, scp->mouse_cut_start);
+ cut_buffer[1] = '\0';
+ scp->status |= MOUSE_CUTTING;
+ }
+ mark_all(scp); /* this is probably overkill XXX */
+ }
+}
+
+/* end of cut operation */
+static void
+mouse_cut_end(scr_stat *scp)
+{
+ if (scp->status & MOUSE_VISIBLE)
+ scp->status &= ~MOUSE_CUTTING;
+}
+
+/* copy a word under the mouse pointer */
+static void
+mouse_cut_word(scr_stat *scp)
+{
+ int start;
+ int end;
+ int sol;
+ int eol;
+ int c;
+ int s;
+ int i;
+ int j;
+
+ /*
+ * Because we don't have locale information in the kernel,
+ * we only distinguish space char and non-space chars. Punctuation
+ * chars, symbols and other regular chars are all treated alike.
+ */
+ if (scp->status & MOUSE_VISIBLE) {
+ /* remove the current cut mark */
+ s = spltty();
+ if (scp->mouse_cut_start <= scp->mouse_cut_end) {
+ mark_for_update(scp, scp->mouse_cut_start);
+ mark_for_update(scp, scp->mouse_cut_end);
+ } else if (scp->mouse_cut_end >= 0) {
+ mark_for_update(scp, scp->mouse_cut_end);
+ mark_for_update(scp, scp->mouse_cut_start);
+ }
+ scp->mouse_cut_start = scp->xsize*scp->ysize;
+ scp->mouse_cut_end = -1;
+ splx(s);
+
+ sol = (scp->mouse_pos / scp->xsize) * scp->xsize;
+ eol = sol + scp->xsize;
+ c = sc_vtb_getc(&scp->vtb, scp->mouse_pos);
+ if (isspace(c)) {
+ /* blank space */
+ for (j = scp->mouse_pos; j >= sol; --j) {
+ c = sc_vtb_getc(&scp->vtb, j);
+ if (!isspace(c))
+ break;
+ }
+ start = ++j;
+ for (j = scp->mouse_pos; j < eol; ++j) {
+ c = sc_vtb_getc(&scp->vtb, j);
+ if (!isspace(c))
+ break;
+ }
+ end = j - 1;
+ } else {
+ /* non-space word */
+ for (j = scp->mouse_pos; j >= sol; --j) {
+ c = sc_vtb_getc(&scp->vtb, j);
+ if (isspace(c))
+ break;
+ }
+ start = ++j;
+ for (j = scp->mouse_pos; j < eol; ++j) {
+ c = sc_vtb_getc(&scp->vtb, j);
+ if (isspace(c))
+ break;
+ }
+ end = j - 1;
+ }
+
+ /* copy the found word */
+ for (i = 0, j = start; j <= end; ++j)
+ cut_buffer[i++] = sc_vtb_getc(&scp->vtb, j);
+ cut_buffer[i] = '\0';
+ scp->status |= MOUSE_CUTTING;
+
+ /* mark the region */
+ s = spltty();
+ scp->mouse_cut_start = start;
+ scp->mouse_cut_end = end;
+ mark_for_update(scp, start);
+ mark_for_update(scp, end);
+ splx(s);
+ }
+}
+
+/* copy a line under the mouse pointer */
+static void
+mouse_cut_line(scr_stat *scp)
+{
+ int s;
+ int i;
+ int j;
+
+ if (scp->status & MOUSE_VISIBLE) {
+ /* remove the current cut mark */
+ s = spltty();
+ if (scp->mouse_cut_start <= scp->mouse_cut_end) {
+ mark_for_update(scp, scp->mouse_cut_start);
+ mark_for_update(scp, scp->mouse_cut_end);
+ } else if (scp->mouse_cut_end >= 0) {
+ mark_for_update(scp, scp->mouse_cut_end);
+ mark_for_update(scp, scp->mouse_cut_start);
+ }
+
+ /* mark the entire line */
+ scp->mouse_cut_start =
+ (scp->mouse_pos / scp->xsize) * scp->xsize;
+ scp->mouse_cut_end = scp->mouse_cut_start + scp->xsize - 1;
+ mark_for_update(scp, scp->mouse_cut_start);
+ mark_for_update(scp, scp->mouse_cut_end);
+ splx(s);
+
+ /* copy the line into the cut buffer */
+ for (i = 0, j = scp->mouse_cut_start; j <= scp->mouse_cut_end; ++j)
+ cut_buffer[i++] = sc_vtb_getc(&scp->vtb, j);
+ cut_buffer[i++] = '\r';
+ cut_buffer[i] = '\0';
+ scp->status |= MOUSE_CUTTING;
+ }
+}
+
+/* extend the marked region to the mouse pointer position */
+static void
+mouse_cut_extend(scr_stat *scp)
+{
+ int start;
+ int end;
+ int s;
+
+ if ((scp->status & MOUSE_VISIBLE) && !(scp->status & MOUSE_CUTTING)
+ && (scp->mouse_cut_end >= 0)) {
+ if (scp->mouse_cut_start <= scp->mouse_cut_end) {
+ start = scp->mouse_cut_start;
+ end = scp->mouse_cut_end;
+ } else {
+ start = scp->mouse_cut_end;
+ end = scp->mouse_cut_start - 1;
+ }
+ s = spltty();
+ if (scp->mouse_pos > end) {
+ scp->mouse_cut_start = start;
+ scp->mouse_cut_end = end;
+ } else if (scp->mouse_pos < start) {
+ scp->mouse_cut_start = end + 1;
+ scp->mouse_cut_end = start;
+ } else {
+ if (scp->mouse_pos - start > end + 1 - scp->mouse_pos) {
+ scp->mouse_cut_start = start;
+ scp->mouse_cut_end = end;
+ } else {
+ scp->mouse_cut_start = end + 1;
+ scp->mouse_cut_end = start;
+ }
+ }
+ splx(s);
+ mouse_cut(scp);
+ scp->status |= MOUSE_CUTTING;
+ }
+}
+
+/* paste cut buffer contents into the current vty */
+static void
+mouse_paste(scr_stat *scp)
+{
+ if (scp->status & MOUSE_VISIBLE)
+ sc_paste(scp, cut_buffer, strlen(cut_buffer));
+}
+
+#endif /* SC_NO_CUTPASTE */
+
+int
+sc_mouse_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag,
+ struct proc *p)
+{
+
+ scr_stat *scp;
+ int s;
+ int i;
+
+ /* scp == NULL, if tp == sc_get_mouse_tty() (/dev/sysmouse) */
+ scp = sc_get_scr_stat(tp->t_dev);
+
+ switch (cmd) {
+
+ case CONS_MOUSECTL: /* control mouse arrow */
+ case OLD_CONS_MOUSECTL:
+ {
+ /* MOUSE_BUTTON?DOWN -> MOUSE_MSC_BUTTON?UP */
+ static int butmap[8] = {
+ MOUSE_MSC_BUTTON1UP | MOUSE_MSC_BUTTON2UP | MOUSE_MSC_BUTTON3UP,
+ MOUSE_MSC_BUTTON2UP | MOUSE_MSC_BUTTON3UP,
+ MOUSE_MSC_BUTTON1UP | MOUSE_MSC_BUTTON3UP,
+ MOUSE_MSC_BUTTON3UP,
+ MOUSE_MSC_BUTTON1UP | MOUSE_MSC_BUTTON2UP,
+ MOUSE_MSC_BUTTON2UP,
+ MOUSE_MSC_BUTTON1UP,
+ 0,
+ };
+ mouse_info_t *mouse = (mouse_info_t*)data;
+ mouse_info_t buf;
+ scr_stat *cur_scp;
+ struct tty *mtty;
+
+ if (scp == NULL)
+ return ENOTTY;
+
+ if (cmd == OLD_CONS_MOUSECTL) {
+ static u_char swapb[] = { 0, 4, 2, 6, 1, 5, 3, 7 };
+ old_mouse_info_t *old_mouse = (old_mouse_info_t *)data;
+
+ mouse = &buf;
+ mouse->operation = old_mouse->operation;
+ switch (mouse->operation) {
+ case MOUSE_MODE:
+ mouse->u.mode = old_mouse->u.mode;
+ break;
+ case MOUSE_SHOW:
+ case MOUSE_HIDE:
+ break;
+ case MOUSE_MOVEABS:
+ case MOUSE_MOVEREL:
+ case MOUSE_ACTION:
+ mouse->u.data.x = old_mouse->u.data.x;
+ mouse->u.data.y = old_mouse->u.data.y;
+ mouse->u.data.z = 0;
+ mouse->u.data.buttons = swapb[old_mouse->u.data.buttons & 0x7];
+ break;
+ case MOUSE_GETINFO:
+ old_mouse->u.data.x = scp->mouse_xpos;
+ old_mouse->u.data.y = scp->mouse_ypos;
+ old_mouse->u.data.buttons = swapb[scp->mouse_buttons & 0x7];
+ break;
+ default:
+ return EINVAL;
+ }
+ }
+
+ cur_scp = scp->sc->cur_scp;
+
+ switch (mouse->operation) {
+ case MOUSE_MODE:
+ if (ISSIGVALID(mouse->u.mode.signal)) {
+ scp->mouse_signal = mouse->u.mode.signal;
+ scp->mouse_proc = p;
+ scp->mouse_pid = p->p_pid;
+ }
+ else {
+ scp->mouse_signal = 0;
+ scp->mouse_proc = NULL;
+ scp->mouse_pid = 0;
+ }
+ return 0;
+
+ case MOUSE_SHOW:
+ if (!ISMOUSEAVAIL(scp->sc->adp->va_flags))
+ return EINVAL;
+ s = spltty();
+ if (!(scp->sc->flags & SC_MOUSE_ENABLED)) {
+ scp->sc->flags |= SC_MOUSE_ENABLED;
+ if (!ISGRAPHSC(cur_scp)) {
+ cur_scp->status |= MOUSE_VISIBLE;
+ mark_all(cur_scp);
+ }
+ splx(s);
+ return 0;
+ } else {
+ splx(s);
+ return EINVAL;
+ }
+ break;
+#if 0
+ if (!(scp->status & MOUSE_ENABLED)) {
+ scp->mouse_oldpos = scp->mouse_pos;
+ scp->status |= MOUSE_ENABLED;
+ if (!ISGRAPHSC(scp))
+ scp->status |= MOUSE_VISIBLE;
+ splx(s);
+ mark_all(scp);
+ return 0;
+ } else {
+ splx(s);
+ return EINVAL;
+ }
+ break;
+#endif
+
+ case MOUSE_HIDE:
+ s = spltty();
+ if (scp->sc->flags & SC_MOUSE_ENABLED) {
+ scp->sc->flags &= ~SC_MOUSE_ENABLED;
+ sc_remove_all_mouse(scp->sc);
+ splx(s);
+ return 0;
+ } else {
+ splx(s);
+ return EINVAL;
+ }
+ break;
+#if 0
+ if (scp->status & MOUSE_ENABLED) {
+ scp->status &= ~(MOUSE_ENABLED | MOUSE_VISIBLE);
+ mark_all(scp);
+ splx(s);
+ return 0;
+ } else {
+ splx(s);
+ return EINVAL;
+ }
+ break;
+#endif
+
+ case MOUSE_MOVEABS:
+ s = spltty();
+ scp->mouse_xpos = mouse->u.data.x;
+ scp->mouse_ypos = mouse->u.data.y;
+ set_mouse_pos(scp);
+ splx(s);
+ break;
+
+ case MOUSE_MOVEREL:
+ s = spltty();
+ scp->mouse_xpos += mouse->u.data.x;
+ scp->mouse_ypos += mouse->u.data.y;
+ set_mouse_pos(scp);
+ splx(s);
+ break;
+
+ case MOUSE_GETINFO:
+ mouse->u.data.x = scp->mouse_xpos;
+ mouse->u.data.y = scp->mouse_ypos;
+ mouse->u.data.z = 0;
+ mouse->u.data.buttons = scp->mouse_buttons;
+ return 0;
+
+ case MOUSE_ACTION:
+ case MOUSE_MOTION_EVENT:
+ /* send out mouse event on /dev/sysmouse */
+#if 0
+ /* this should maybe only be settable from /dev/consolectl SOS */
+ if (SC_VTY(tp->t_dev) != SC_CONSOLECTL)
+ return ENOTTY;
+#endif
+ mouse_status.dx += mouse->u.data.x;
+ mouse_status.dy += mouse->u.data.y;
+ mouse_status.dz += mouse->u.data.z;
+ if (mouse->operation == MOUSE_ACTION)
+ mouse_status.button = mouse->u.data.buttons;
+ mouse_status.flags |=
+ ((mouse->u.data.x || mouse->u.data.y || mouse->u.data.z) ?
+ MOUSE_POSCHANGED : 0)
+ | (mouse_status.obutton ^ mouse_status.button);
+ if (mouse_status.flags == 0)
+ return 0;
+
+ mtty = sc_get_mouse_tty();
+ if (mtty->t_state & TS_ISOPEN) {
+ u_char buf[MOUSE_SYS_PACKETSIZE];
+
+ /* the first five bytes are compatible with MouseSystems' */
+ buf[0] = MOUSE_MSC_SYNC
+ | butmap[mouse_status.button & MOUSE_STDBUTTONS];
+ i = imax(imin(mouse->u.data.x, 255), -256);
+ buf[1] = i >> 1;
+ buf[3] = i - buf[1];
+ i = -imax(imin(mouse->u.data.y, 255), -256);
+ buf[2] = i >> 1;
+ buf[4] = i - buf[2];
+ for (i = 0; i < MOUSE_MSC_PACKETSIZE; i++)
+ (*linesw[mtty->t_line].l_rint)(buf[i], mtty);
+ if (mouse_level >= 1) { /* extended part */
+ i = imax(imin(mouse->u.data.z, 127), -128);
+ buf[5] = (i >> 1) & 0x7f;
+ buf[6] = (i - (i >> 1)) & 0x7f;
+ /* buttons 4-10 */
+ buf[7] = (~mouse_status.button >> 3) & 0x7f;
+ for (i = MOUSE_MSC_PACKETSIZE;
+ i < MOUSE_SYS_PACKETSIZE; i++)
+ (*linesw[mtty->t_line].l_rint)(buf[i], mtty);
+ }
+ }
+
+ if (cur_scp->mouse_signal) {
+ cur_scp->mouse_buttons = mouse->u.data.buttons;
+ /* has controlling process died? */
+ if (cur_scp->mouse_proc &&
+ (cur_scp->mouse_proc != pfind(cur_scp->mouse_pid))){
+ cur_scp->mouse_signal = 0;
+ cur_scp->mouse_proc = NULL;
+ cur_scp->mouse_pid = 0;
+ }
+ else
+ psignal(cur_scp->mouse_proc, cur_scp->mouse_signal);
+ break;
+ }
+
+ /*
+ * If any buttons are down or the mouse has moved a lot,
+ * stop the screen saver.
+ */
+ if (((mouse->operation == MOUSE_ACTION) && mouse->u.data.buttons)
+ || (mouse->u.data.x*mouse->u.data.x
+ + mouse->u.data.y*mouse->u.data.y
+ >= SC_WAKEUP_DELTA*SC_WAKEUP_DELTA)) {
+ sc_touch_scrn_saver();
+ }
+
+ if (ISGRAPHSC(cur_scp) || (cut_buffer == NULL))
+ break;
+
+#ifndef SC_NO_CUTPASTE
+ if (cur_scp->sc->flags & SC_MOUSE_ENABLED)
+ cur_scp->status |= MOUSE_VISIBLE;
+
+ if (mouse->operation == MOUSE_ACTION) {
+ /* process button presses */
+ if (cur_scp->mouse_buttons ^ mouse->u.data.buttons) {
+ cur_scp->mouse_buttons = mouse->u.data.buttons;
+ if (cur_scp->mouse_buttons & MOUSE_BUTTON1DOWN)
+ mouse_cut_start(cur_scp);
+ else
+ mouse_cut_end(cur_scp);
+ if (cur_scp->mouse_buttons & MOUSE_BUTTON2DOWN ||
+ cur_scp->mouse_buttons & MOUSE_BUTTON3DOWN)
+ mouse_paste(cur_scp);
+ }
+ }
+#else /* SC_NO_CUTPASTE */
+ if (mouse->operation == MOUSE_ACTION)
+ cur_scp->mouse_buttons = mouse->u.data.buttons;
+#endif /* SC_NO_CUTPASTE */
+
+ if (mouse->u.data.x != 0 || mouse->u.data.y != 0) {
+ s = spltty();
+ cur_scp->mouse_xpos += mouse->u.data.x;
+ cur_scp->mouse_ypos += mouse->u.data.y;
+ set_mouse_pos(cur_scp);
+ splx(s);
+ }
+ break;
+
+ case MOUSE_BUTTON_EVENT:
+ if ((mouse->u.event.id & MOUSE_BUTTONS) == 0)
+ return EINVAL;
+ if (mouse->u.event.value < 0)
+ return EINVAL;
+#if 0
+ /* this should maybe only be settable from /dev/consolectl SOS */
+ if (SC_VTY(tp->t_dev) != SC_CONSOLECTL)
+ return ENOTTY;
+#endif
+ if (mouse->u.event.value > 0) {
+ cur_scp->mouse_buttons |= mouse->u.event.id;
+ mouse_status.button |= mouse->u.event.id;
+ } else {
+ cur_scp->mouse_buttons &= ~mouse->u.event.id;
+ mouse_status.button &= ~mouse->u.event.id;
+ }
+ mouse_status.flags |= mouse_status.obutton ^ mouse_status.button;
+ if (mouse_status.flags == 0)
+ return 0;
+
+ mtty = sc_get_mouse_tty();
+ if (mtty->t_state & TS_ISOPEN) {
+ u_char buf[MOUSE_SYS_PACKETSIZE];
+
+ buf[0] = MOUSE_MSC_SYNC
+ | butmap[mouse_status.button & MOUSE_STDBUTTONS];
+ buf[7] = (~mouse_status.button >> 3) & 0x7f;
+ buf[1] = buf[2] = buf[3] = buf[4] = buf[5] = buf[6] = 0;
+ for (i = 0;
+ i < ((mouse_level >= 1) ? MOUSE_SYS_PACKETSIZE
+ : MOUSE_MSC_PACKETSIZE); i++)
+ (*linesw[mtty->t_line].l_rint)(buf[i], mtty);
+ }
+
+ if (cur_scp->mouse_signal) {
+ if (cur_scp->mouse_proc &&
+ (cur_scp->mouse_proc != pfind(cur_scp->mouse_pid))){
+ cur_scp->mouse_signal = 0;
+ cur_scp->mouse_proc = NULL;
+ cur_scp->mouse_pid = 0;
+ }
+ else
+ psignal(cur_scp->mouse_proc, cur_scp->mouse_signal);
+ break;
+ }
+
+ /* if a button is held down, stop the screen saver */
+ if (mouse->u.event.value > 0)
+ sc_touch_scrn_saver();
+
+ if (ISGRAPHSC(cur_scp) || (cut_buffer == NULL))
+ break;
+
+#ifndef SC_NO_CUTPASTE
+ if (cur_scp->sc->flags & SC_MOUSE_ENABLED)
+ cur_scp->status |= MOUSE_VISIBLE;
+
+ switch (mouse->u.event.id) {
+ case MOUSE_BUTTON1DOWN:
+ switch (mouse->u.event.value % 4) {
+ case 0: /* up */
+ mouse_cut_end(cur_scp);
+ break;
+ case 1: /* single click: start cut operation */
+ mouse_cut_start(cur_scp);
+ break;
+ case 2: /* double click: cut a word */
+ mouse_cut_word(cur_scp);
+ mouse_cut_end(cur_scp);
+ break;
+ case 3: /* triple click: cut a line */
+ mouse_cut_line(cur_scp);
+ mouse_cut_end(cur_scp);
+ break;
+ }
+ break;
+ case MOUSE_BUTTON2DOWN:
+ switch (mouse->u.event.value) {
+ case 0: /* up */
+ break;
+ default:
+ mouse_paste(cur_scp);
+ break;
+ }
+ break;
+ case MOUSE_BUTTON3DOWN:
+ switch (mouse->u.event.value) {
+ case 0: /* up */
+ if (!(cur_scp->mouse_buttons & MOUSE_BUTTON1DOWN))
+ mouse_cut_end(cur_scp);
+ break;
+ default:
+ mouse_cut_extend(cur_scp);
+ break;
+ }
+ break;
+ }
+#endif /* SC_NO_CUTPASTE */
+ break;
+
+ default:
+ return EINVAL;
+ }
+
+ return 0;
+ }
+
+ /* MOUSE_XXX: /dev/sysmouse ioctls */
+ case MOUSE_GETHWINFO: /* get device information */
+ {
+ mousehw_t *hw = (mousehw_t *)data;
+
+ if (tp != sc_get_mouse_tty())
+ return ENOTTY;
+ hw->buttons = 10; /* XXX unknown */
+ hw->iftype = MOUSE_IF_SYSMOUSE;
+ hw->type = MOUSE_MOUSE;
+ hw->model = MOUSE_MODEL_GENERIC;
+ hw->hwid = 0;
+ return 0;
+ }
+
+ case MOUSE_GETMODE: /* get protocol/mode */
+ {
+ mousemode_t *mode = (mousemode_t *)data;
+
+ if (tp != sc_get_mouse_tty())
+ return ENOTTY;
+ mode->level = mouse_level;
+ switch (mode->level) {
+ case 0:
+ /* at this level, sysmouse emulates MouseSystems protocol */
+ mode->protocol = MOUSE_PROTO_MSC;
+ mode->rate = -1; /* unknown */
+ mode->resolution = -1; /* unknown */
+ mode->accelfactor = 0; /* disabled */
+ mode->packetsize = MOUSE_MSC_PACKETSIZE;
+ mode->syncmask[0] = MOUSE_MSC_SYNCMASK;
+ mode->syncmask[1] = MOUSE_MSC_SYNC;
+ break;
+
+ case 1:
+ /* at this level, sysmouse uses its own protocol */
+ mode->protocol = MOUSE_PROTO_SYSMOUSE;
+ mode->rate = -1;
+ mode->resolution = -1;
+ mode->accelfactor = 0;
+ mode->packetsize = MOUSE_SYS_PACKETSIZE;
+ mode->syncmask[0] = MOUSE_SYS_SYNCMASK;
+ mode->syncmask[1] = MOUSE_SYS_SYNC;
+ break;
+ }
+ return 0;
+ }
+
+ case MOUSE_SETMODE: /* set protocol/mode */
+ {
+ mousemode_t *mode = (mousemode_t *)data;
+
+ if (tp != sc_get_mouse_tty())
+ return ENOTTY;
+ if ((mode->level < 0) || (mode->level > 1))
+ return EINVAL;
+ sc_mouse_set_level(mode->level);
+ return 0;
+ }
+
+ case MOUSE_GETLEVEL: /* get operation level */
+ if (tp != sc_get_mouse_tty())
+ return ENOTTY;
+ *(int *)data = mouse_level;
+ return 0;
+
+ case MOUSE_SETLEVEL: /* set operation level */
+ if (tp != sc_get_mouse_tty())
+ return ENOTTY;
+ if ((*(int *)data < 0) || (*(int *)data > 1))
+ return EINVAL;
+ sc_mouse_set_level(*(int *)data);
+ return 0;
+
+ case MOUSE_GETSTATUS: /* get accumulated mouse events */
+ if (tp != sc_get_mouse_tty())
+ return ENOTTY;
+ s = spltty();
+ *(mousestatus_t *)data = mouse_status;
+ mouse_status.flags = 0;
+ mouse_status.obutton = mouse_status.button;
+ mouse_status.dx = 0;
+ mouse_status.dy = 0;
+ mouse_status.dz = 0;
+ splx(s);
+ return 0;
+
+#if notyet
+ case MOUSE_GETVARS: /* get internal mouse variables */
+ case MOUSE_SETVARS: /* set internal mouse variables */
+ if (tp != sc_get_mouse_tty())
+ return ENOTTY;
+ return ENODEV;
+#endif
+
+ case MOUSE_READSTATE: /* read status from the device */
+ case MOUSE_READDATA: /* read data from the device */
+ if (tp != sc_get_mouse_tty())
+ return ENOTTY;
+ return ENODEV;
+ }
+
+ return ENOIOCTL;
+}
+
+#endif /* SC_NO_SYSMOUSE */
+
+#endif /* NSC */
diff --git a/sys/dev/syscons/scvesactl.c b/sys/dev/syscons/scvesactl.c
index b71f071..114c5ec 100644
--- a/sys/dev/syscons/scvesactl.c
+++ b/sys/dev/syscons/scvesactl.c
@@ -23,7 +23,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: scvesactl.c,v 1.9 1999/01/11 03:18:26 yokota Exp $
+ * $Id: scvesactl.c,v 1.10 1999/06/01 18:17:31 jlemon Exp $
*/
#include "sc.h"
@@ -44,7 +44,6 @@
#include <sys/tty.h>
#include <sys/kernel.h>
-#include <machine/apm_bios.h>
#include <machine/console.h>
#include <machine/pc/vesa.h>
@@ -71,7 +70,7 @@ vesa_ioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
case SW_TEXT_132x25: case SW_TEXT_132x30:
case SW_TEXT_132x43: case SW_TEXT_132x50:
case SW_TEXT_132x60:
- if (!(scp->adp->va_flags & V_ADP_MODECHANGE))
+ if (!(scp->sc->adp->va_flags & V_ADP_MODECHANGE))
return ENODEV;
return sc_set_text_mode(scp, tp, cmd & 0xff, 0, 0, 0);
@@ -81,7 +80,7 @@ vesa_ioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
case SW_VESA_C132x43:
case SW_VESA_C132x50:
case SW_VESA_C132x60:
- if (!(scp->adp->va_flags & V_ADP_MODECHANGE))
+ if (!(scp->sc->adp->va_flags & V_ADP_MODECHANGE))
return ENODEV;
mode = (cmd & 0xff) + M_VESA_BASE;
return sc_set_text_mode(scp, tp, mode, 0, 0, 0);
@@ -107,7 +106,7 @@ vesa_ioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
case SW_VESA_1280x1024: case SW_VESA_CG1280x1024:
case SW_VESA_32K_1280: case SW_VESA_64K_1280:
case SW_VESA_FULL_1280:
- if (!(scp->adp->va_flags & V_ADP_MODECHANGE))
+ if (!(scp->sc->adp->va_flags & V_ADP_MODECHANGE))
return ENODEV;
mode = (cmd & 0xff) + M_VESA_BASE;
return sc_set_graphics_mode(scp, tp, mode);
diff --git a/sys/dev/syscons/scvgarndr.c b/sys/dev/syscons/scvgarndr.c
new file mode 100644
index 0000000..16c40e2
--- /dev/null
+++ b/sys/dev/syscons/scvgarndr.c
@@ -0,0 +1,829 @@
+/*-
+ * Copyright (c) 1999 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 as
+ * the first lines of this file unmodified.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id:$
+ */
+
+#include "sc.h"
+#include "vga.h"
+#include "opt_syscons.h"
+#include "opt_vga.h"
+
+#if NSC > 0 && NVGA > 0
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+
+#include <machine/console.h>
+#include <machine/md_var.h>
+
+#include <dev/fb/fbreg.h>
+#include <dev/fb/vgareg.h>
+#include <dev/syscons/syscons.h>
+
+#include <isa/isareg.h>
+
+#ifndef SC_MOUSE_CHAR
+#define SC_MOUSE_CHAR (0xd0)
+#endif
+
+#ifndef SC_RENDER_DEBUG
+#define SC_RENDER_DEBUG 0
+#endif
+
+static vr_clear_t vga_txtclear;
+static vr_draw_border_t vga_txtborder;
+static vr_draw_t vga_txtdraw;
+static vr_set_cursor_t vga_txtcursor_shape;
+static vr_draw_cursor_t vga_txtcursor;
+static vr_blink_cursor_t vga_txtblink;
+#ifndef SC_NO_CUTPASTE
+static vr_draw_mouse_t vga_txtmouse;
+#else
+#define vga_txtmouse (vr_draw_mouse_t *)vga_nop
+#endif
+
+#ifdef SC_PIXEL_MODE
+static vr_clear_t vga_pxlclear;
+static vr_draw_border_t vga_pxlborder;
+static vr_draw_t vga_egadraw;
+static vr_draw_t vga_vgadraw;
+static vr_set_cursor_t vga_pxlcursor_shape;
+static vr_draw_cursor_t vga_pxlcursor;
+static vr_blink_cursor_t vga_pxlblink;
+#ifndef SC_NO_CUTPASTE
+static vr_draw_mouse_t vga_pxlmouse;
+#else
+#define vga_pxlmouse (vr_draw_mouse_t *)vga_nop
+#endif
+#endif /* SC_PIXEL_MODE */
+
+#ifndef SC_NO_MODE_CHANGE
+static vr_draw_border_t vga_grborder;
+#endif
+
+static void vga_nop(scr_stat *scp, ...);
+
+static sc_rndr_sw_t txtrndrsw = {
+ vga_txtclear,
+ vga_txtborder,
+ vga_txtdraw,
+ vga_txtcursor_shape,
+ vga_txtcursor,
+ vga_txtblink,
+ (vr_set_mouse_t *)vga_nop,
+ vga_txtmouse,
+};
+RENDERER(mda, 0, txtrndrsw);
+RENDERER(cga, 0, txtrndrsw);
+RENDERER(ega, 0, txtrndrsw);
+RENDERER(vga, 0, txtrndrsw);
+
+#ifdef SC_PIXEL_MODE
+static sc_rndr_sw_t egarndrsw = {
+ vga_pxlclear,
+ vga_pxlborder,
+ vga_egadraw,
+ vga_pxlcursor_shape,
+ vga_pxlcursor,
+ vga_pxlblink,
+ (vr_set_mouse_t *)vga_nop,
+ vga_pxlmouse,
+};
+RENDERER(ega, PIXEL_MODE, egarndrsw);
+
+static sc_rndr_sw_t vgarndrsw = {
+ vga_pxlclear,
+ vga_pxlborder,
+ vga_vgadraw,
+ vga_pxlcursor_shape,
+ vga_pxlcursor,
+ vga_pxlblink,
+ (vr_set_mouse_t *)vga_nop,
+ vga_pxlmouse,
+};
+RENDERER(vga, PIXEL_MODE, vgarndrsw);
+#endif /* SC_PIXEL_MODE */
+
+#ifndef SC_NO_MODE_CHANGE
+static sc_rndr_sw_t grrndrsw = {
+ (vr_clear_t *)vga_nop,
+ vga_grborder,
+ (vr_draw_t *)vga_nop,
+ (vr_set_cursor_t *)vga_nop,
+ (vr_draw_cursor_t *)vga_nop,
+ (vr_blink_cursor_t *)vga_nop,
+ (vr_set_mouse_t *)vga_nop,
+ (vr_draw_mouse_t *)vga_nop,
+};
+RENDERER(cga, GRAPHICS_MODE, grrndrsw);
+RENDERER(ega, GRAPHICS_MODE, grrndrsw);
+RENDERER(vga, GRAPHICS_MODE, grrndrsw);
+#endif /* SC_NO_MODE_CHANGE */
+
+#ifndef SC_NO_CUTPASTE
+static u_short mouse_and_mask[16] = {
+ 0xc000, 0xe000, 0xf000, 0xf800, 0xfc00, 0xfe00, 0xff00, 0xff80,
+ 0xfe00, 0x1e00, 0x1f00, 0x0f00, 0x0f00, 0x0000, 0x0000, 0x0000
+};
+static u_short mouse_or_mask[16] = {
+ 0x0000, 0x4000, 0x6000, 0x7000, 0x7800, 0x7c00, 0x7e00, 0x6800,
+ 0x0c00, 0x0c00, 0x0600, 0x0600, 0x0000, 0x0000, 0x0000, 0x0000
+};
+#endif
+
+static void
+vga_nop(scr_stat *scp, ...)
+{
+}
+
+/* text mode renderer */
+
+static void
+vga_txtclear(scr_stat *scp, int c, int attr)
+{
+ sc_vtb_clear(&scp->scr, c, attr);
+}
+
+static void
+vga_txtborder(scr_stat *scp, int color)
+{
+ (*vidsw[scp->sc->adapter]->set_border)(scp->sc->adp, color);
+}
+
+static void
+vga_txtdraw(scr_stat *scp, int from, int count, int flip)
+{
+ vm_offset_t p;
+ int c;
+ int a;
+
+ if (from + count > scp->xsize*scp->ysize)
+ count = scp->xsize*scp->ysize - from;
+
+ if (flip) {
+ for (p = sc_vtb_pointer(&scp->scr, from); count-- > 0; ++from) {
+ c = sc_vtb_getc(&scp->vtb, from);
+ a = sc_vtb_geta(&scp->vtb, from);
+ a = (a & 0x8800) | ((a & 0x7000) >> 4)
+ | ((a & 0x0700) << 4);
+ p = sc_vtb_putchar(&scp->scr, p, c, a);
+ }
+ } else {
+ sc_vtb_copy(&scp->vtb, from, &scp->scr, from, count);
+ }
+}
+
+static void
+vga_txtcursor_shape(scr_stat *scp, int base, int height, int blink)
+{
+ if (base < 0 || base >= scp->font_size)
+ return;
+ /* the caller may set height <= 0 in order to disable the cursor */
+#if 0
+ scp->cursor_base = base;
+ scp->cursor_height = height;
+#endif
+ (*vidsw[scp->sc->adapter]->set_hw_cursor_shape)(scp->sc->adp,
+ base, height,
+ scp->font_size, blink);
+}
+
+static void
+vga_txtcursor(scr_stat *scp, int at, int blink, int on, int flip)
+{
+ video_adapter_t *adp;
+ int cursor_attr;
+
+ if (scp->cursor_height <= 0) /* the text cursor is disabled */
+ return;
+
+ adp = scp->sc->adp;
+ if (blink) {
+ scp->status |= VR_CURSOR_BLINK;
+ if (on) {
+ scp->status |= VR_CURSOR_ON;
+ (*vidsw[adp->va_index]->set_hw_cursor)(adp,
+ at%scp->xsize,
+ at/scp->xsize);
+ } else {
+ if (scp->status & VR_CURSOR_ON)
+ (*vidsw[adp->va_index]->set_hw_cursor)(adp,
+ -1, -1);
+ scp->status &= ~VR_CURSOR_ON;
+ }
+ } else {
+ scp->status &= ~VR_CURSOR_BLINK;
+ if (on) {
+ scp->status |= VR_CURSOR_ON;
+ cursor_attr = sc_vtb_geta(&scp->vtb, at);
+ scp->cursor_saveunder_char = sc_vtb_getc(&scp->scr, at);
+ scp->cursor_saveunder_attr = cursor_attr;
+ if ((cursor_attr & 0x7000) == 0x7000) {
+ cursor_attr &= 0x8f00;
+ if ((cursor_attr & 0x0700) == 0)
+ cursor_attr |= 0x0700;
+ } else {
+ cursor_attr |= 0x7000;
+ if ((cursor_attr & 0x0700) == 0x0700)
+ cursor_attr &= 0xf000;
+ }
+ if (flip)
+ cursor_attr = (cursor_attr & 0x8800)
+ | ((cursor_attr & 0x7000) >> 4)
+ | ((cursor_attr & 0x0700) << 4);
+ sc_vtb_putc(&scp->scr, at,
+ sc_vtb_getc(&scp->scr, at),
+ cursor_attr);
+ } else {
+ cursor_attr = scp->cursor_saveunder_attr;
+ if (flip)
+ cursor_attr = (cursor_attr & 0x8800)
+ | ((cursor_attr & 0x7000) >> 4)
+ | ((cursor_attr & 0x0700) << 4);
+ if (scp->status & VR_CURSOR_ON)
+ sc_vtb_putc(&scp->scr, at,
+ scp->cursor_saveunder_char,
+ cursor_attr);
+ scp->status &= ~VR_CURSOR_ON;
+ }
+ }
+}
+
+static void
+vga_txtblink(scr_stat *scp, int at, int flip)
+{
+}
+
+#ifndef SC_NO_CUTPASTE
+
+static void
+draw_txtmouse(scr_stat *scp, int x, int y)
+{
+#ifndef SC_ALT_MOUSE_IMAGE
+ u_char font_buf[128];
+ u_short cursor[32];
+ int pos;
+ int xoffset, yoffset;
+ int crtc_addr;
+ int i;
+
+ /* prepare mousepointer char's bitmaps */
+ pos = (y/scp->font_size - scp->yoff)*scp->xsize + x/8 - scp->xoff;
+ bcopy(scp->font + sc_vtb_getc(&scp->vtb, pos)*scp->font_size,
+ &font_buf[0], scp->font_size);
+ bcopy(scp->font + sc_vtb_getc(&scp->vtb, pos + 1)*scp->font_size,
+ &font_buf[32], scp->font_size);
+ bcopy(scp->font
+ + sc_vtb_getc(&scp->vtb, pos + scp->xsize)*scp->font_size,
+ &font_buf[64], scp->font_size);
+ bcopy(scp->font
+ + sc_vtb_getc(&scp->vtb, pos + scp->xsize + 1)*scp->font_size,
+ &font_buf[96], scp->font_size);
+ for (i = 0; i < scp->font_size; ++i) {
+ cursor[i] = font_buf[i]<<8 | font_buf[i+32];
+ cursor[i + scp->font_size] = font_buf[i+64]<<8 | font_buf[i+96];
+ }
+
+ /* now and-or in the mousepointer image */
+ xoffset = x%8;
+ yoffset = y%scp->font_size;
+ for (i = 0; i < 16; ++i) {
+ cursor[i + yoffset] =
+ (cursor[i + yoffset] & ~(mouse_and_mask[i] >> xoffset))
+ | (mouse_or_mask[i] >> xoffset);
+ }
+ for (i = 0; i < scp->font_size; ++i) {
+ font_buf[i] = (cursor[i] & 0xff00) >> 8;
+ font_buf[i + 32] = cursor[i] & 0xff;
+ font_buf[i + 64] = (cursor[i + scp->font_size] & 0xff00) >> 8;
+ font_buf[i + 96] = cursor[i + scp->font_size] & 0xff;
+ }
+
+#if 1
+ /* wait for vertical retrace to avoid jitter on some videocards */
+ crtc_addr = scp->sc->adp->va_crtc_addr;
+ while (!(inb(crtc_addr + 6) & 0x08)) /* idle */ ;
+#endif
+ (*vidsw[scp->sc->adapter]->load_font)(scp->sc->adp, 0, 32, font_buf,
+ SC_MOUSE_CHAR, 4);
+
+ sc_vtb_putc(&scp->scr, pos, SC_MOUSE_CHAR, sc_vtb_geta(&scp->scr, pos));
+ /* FIXME: may be out of range! */
+ sc_vtb_putc(&scp->scr, pos + scp->xsize, SC_MOUSE_CHAR + 2,
+ sc_vtb_geta(&scp->scr, pos + scp->xsize));
+ if (x < (scp->xsize - 1)*8) {
+ sc_vtb_putc(&scp->scr, pos + 1, SC_MOUSE_CHAR + 1,
+ sc_vtb_geta(&scp->scr, pos + 1));
+ sc_vtb_putc(&scp->scr, pos + scp->xsize + 1, SC_MOUSE_CHAR + 3,
+ sc_vtb_geta(&scp->scr, pos + scp->xsize + 1));
+ }
+#else /* SC_ALT_MOUSE_IMAGE */
+ /* Red, magenta and brown are mapped to green to to keep it readable */
+ static const int col_conv[16] = {
+ 6, 6, 6, 6, 2, 2, 2, 6, 14, 14, 14, 14, 10, 10, 10, 14
+ };
+ int pos;
+ int color;
+ int a;
+
+ pos = (y/scp->font_size - scp->yoff)*scp->xsize + x/8 - scp->xoff;
+ a = sc_vtb_geta(&scp->scr, pos);
+ if (scp->sc->adp->va_flags & V_ADP_COLOR)
+ color = (col_conv[(a & 0xf000) >> 12] << 12)
+ | ((a & 0x0f00) | 0x0800);
+ else
+ color = ((a & 0xf000) >> 4) | ((a & 0x0f00) << 4);
+ sc_vtb_putc(&scp->scr, pos, sc_vtb_getc(&scp->scr, pos), color);
+#endif /* SC_ALT_MOUSE_IMAGE */
+}
+
+static void
+remove_txtmouse(scr_stat *scp, int x, int y)
+{
+}
+
+static void
+vga_txtmouse(scr_stat *scp, int x, int y, int on)
+{
+ if (on)
+ draw_txtmouse(scp, x, y);
+ else
+ remove_txtmouse(scp, x, y);
+}
+
+#endif /* SC_NO_CUTPASTE */
+
+#ifdef SC_PIXEL_MODE
+
+/* pixel (raster text) mode renderer */
+
+static void
+vga_pxlclear(scr_stat *scp, int c, int attr)
+{
+ vm_offset_t p;
+ int line_width;
+ int lines;
+ int i;
+
+ /* XXX: we are just filling the screen with the background color... */
+ outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */
+ outw(GDCIDX, 0x0003); /* data rotate/function select */
+ outw(GDCIDX, 0x0f01); /* set/reset enable */
+ outw(GDCIDX, 0xff08); /* bit mask */
+ outw(GDCIDX, ((attr & 0xf000) >> 4) | 0x00); /* set/reset */
+ line_width = scp->sc->adp->va_line_width;
+ lines = scp->ysize*scp->font_size;
+ p = scp->sc->adp->va_window + line_width*scp->yoff*scp->font_size
+ + scp->xoff;
+ for (i = 0; i < lines; ++i) {
+ bzero_io((void *)p, scp->xsize);
+ p += line_width;
+ }
+ outw(GDCIDX, 0x0000); /* set/reset */
+ outw(GDCIDX, 0x0001); /* set/reset enable */
+}
+
+static void
+vga_pxlborder(scr_stat *scp, int color)
+{
+ vm_offset_t p;
+ int line_width;
+ int i;
+
+ (*vidsw[scp->sc->adapter]->set_border)(scp->sc->adp, color);
+
+ outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */
+ outw(GDCIDX, 0x0003); /* data rotate/function select */
+ outw(GDCIDX, 0x0f01); /* set/reset enable */
+ outw(GDCIDX, 0xff08); /* bit mask */
+ outw(GDCIDX, (color << 8) | 0x00); /* set/reset */
+ line_width = scp->sc->adp->va_line_width;
+ p = scp->sc->adp->va_window;
+ if (scp->yoff > 0) {
+ bzero_io((void *)p, line_width*scp->yoff*scp->font_size);
+ bzero_io((void *)(p + line_width*(scp->yoff + scp->ysize)
+ *scp->font_size),
+ line_width*(scp->ypixel
+ - (scp->yoff + scp->ysize)*scp->font_size));
+ }
+ if (scp->xoff > 0) {
+ for (i = 0; i < scp->ysize*scp->font_size; ++i) {
+ bzero_io((void *)(p + line_width
+ *(scp->yoff*scp->font_size + i)),
+ scp->xoff);
+ bzero_io((void *)(p + line_width
+ *(scp->yoff*scp->font_size + i)
+ + scp->xoff + scp->xsize),
+ scp->xpixel/8 - scp->xoff - scp->xsize);
+ }
+ }
+ outw(GDCIDX, 0x0000); /* set/reset */
+ outw(GDCIDX, 0x0001); /* set/reset enable */
+}
+
+static void
+vga_egadraw(scr_stat *scp, int from, int count, int flip)
+{
+ vm_offset_t d;
+ vm_offset_t e;
+ u_char *f;
+ u_short bg;
+ u_short col1, col2;
+ int line_width;
+ int i, j;
+ int a;
+ u_char c;
+
+ line_width = scp->sc->adp->va_line_width;
+ d = scp->sc->adp->va_window
+ + scp->xoff
+ + scp->yoff*scp->font_size*line_width
+ + (from%scp->xsize)
+ + scp->font_size*line_width*(from/scp->xsize);
+
+ outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */
+ outw(GDCIDX, 0x0003); /* data rotate/function select */
+ outw(GDCIDX, 0x0f01); /* set/reset enable */
+ bg = -1;
+ if (from + count > scp->xsize*scp->ysize)
+ count = scp->xsize*scp->ysize - from;
+ for (i = from; count-- > 0; ++i) {
+ a = sc_vtb_geta(&scp->vtb, i);
+ if (flip) {
+ col1 = ((a & 0x7000) >> 4) | (a & 0x0800);
+ col2 = ((a & 0x8000) >> 4) | (a & 0x0700);
+ } else {
+ col1 = (a & 0x0f00);
+ col2 = (a & 0xf000) >> 4;
+ }
+ /* set background color in EGA/VGA latch */
+ if (bg != col2) {
+ bg = col2;
+ outw(GDCIDX, bg | 0x00); /* set/reset */
+ outw(GDCIDX, 0xff08); /* bit mask */
+ writeb(d, 0);
+ c = readb(d); /* set bg color in the latch */
+ }
+ /* foreground color */
+ outw(GDCIDX, col1 | 0x00); /* set/reset */
+ e = d;
+ f = &(scp->font[sc_vtb_getc(&scp->vtb, i)*scp->font_size]);
+ for (j = 0; j < scp->font_size; ++j, ++f) {
+ outw(GDCIDX, (*f << 8) | 0x08); /* bit mask */
+ writeb(e, 0);
+ e += line_width;
+ }
+ ++d;
+ if ((i % scp->xsize) == scp->xsize - 1)
+ d += scp->xoff*2
+ + (scp->font_size - 1)*line_width;
+ }
+ outw(GDCIDX, 0x0000); /* set/reset */
+ outw(GDCIDX, 0x0001); /* set/reset enable */
+ outw(GDCIDX, 0xff08); /* bit mask */
+}
+
+static void
+vga_vgadraw(scr_stat *scp, int from, int count, int flip)
+{
+ vm_offset_t d;
+ vm_offset_t e;
+ u_char *f;
+ u_short bg;
+ u_short col1, col2;
+ int line_width;
+ int i, j;
+ int a;
+ u_char c;
+
+ line_width = scp->sc->adp->va_line_width;
+ d = scp->sc->adp->va_window
+ + scp->xoff
+ + scp->yoff*scp->font_size*line_width
+ + (from%scp->xsize)
+ + scp->font_size*line_width*(from/scp->xsize);
+
+ outw(GDCIDX, 0x0305); /* read mode 0, write mode 3 */
+ outw(GDCIDX, 0x0003); /* data rotate/function select */
+ outw(GDCIDX, 0x0f01); /* set/reset enable */
+ outw(GDCIDX, 0xff08); /* bit mask */
+ bg = -1;
+ if (from + count > scp->xsize*scp->ysize)
+ count = scp->xsize*scp->ysize - from;
+ for (i = from; count-- > 0; ++i) {
+ a = sc_vtb_geta(&scp->vtb, i);
+ if (flip) {
+ col1 = ((a & 0x7000) >> 4) | (a & 0x0800);
+ col2 = ((a & 0x8000) >> 4) | (a & 0x0700);
+ } else {
+ col1 = (a & 0x0f00);
+ col2 = (a & 0xf000) >> 4;
+ }
+ /* set background color in EGA/VGA latch */
+ if (bg != col2) {
+ bg = col2;
+ outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */
+ outw(GDCIDX, bg | 0x00); /* set/reset */
+ writeb(d, 0);
+ c = readb(d); /* set bg color in the latch */
+ outw(GDCIDX, 0x0305); /* read mode 0, write mode 3 */
+ }
+ /* foreground color */
+ outw(GDCIDX, col1 | 0x00); /* set/reset */
+ e = d;
+ f = &(scp->font[sc_vtb_getc(&scp->vtb, i)*scp->font_size]);
+ for (j = 0; j < scp->font_size; ++j, ++f) {
+ writeb(e, *f);
+ e += line_width;
+ }
+ ++d;
+ if ((i % scp->xsize) == scp->xsize - 1)
+ d += scp->xoff*2
+ + (scp->font_size - 1)*line_width;
+ }
+ outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */
+ outw(GDCIDX, 0x0000); /* set/reset */
+ outw(GDCIDX, 0x0001); /* set/reset enable */
+}
+
+static void
+vga_pxlcursor_shape(scr_stat *scp, int base, int height, int blink)
+{
+ if (base < 0 || base >= scp->font_size)
+ return;
+ /* the caller may set height <= 0 in order to disable the cursor */
+#if 0
+ scp->cursor_base = base;
+ scp->cursor_height = height;
+#endif
+}
+
+static void
+draw_pxlcursor(scr_stat *scp, int at, int on, int flip)
+{
+ vm_offset_t d;
+ u_char *f;
+ int line_width;
+ int height;
+ int col;
+ int a;
+ int i;
+ u_char c;
+
+ line_width = scp->sc->adp->va_line_width;
+ d = scp->sc->adp->va_window
+ + scp->xoff
+ + scp->yoff*scp->font_size*line_width
+ + (at%scp->xsize)
+ + scp->font_size*line_width*(at/scp->xsize)
+ + (scp->font_size - scp->cursor_base - 1)*line_width;
+
+ outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */
+ outw(GDCIDX, 0x0003); /* data rotate/function select */
+ outw(GDCIDX, 0x0f01); /* set/reset enable */
+ /* set background color in EGA/VGA latch */
+ a = sc_vtb_geta(&scp->vtb, at);
+ if (flip)
+ col = (on) ? ((a & 0xf000) >> 4) : (a & 0x0f00);
+ else
+ col = (on) ? (a & 0x0f00) : ((a & 0xf000) >> 4);
+ outw(GDCIDX, col | 0x00); /* set/reset */
+ outw(GDCIDX, 0xff08); /* bit mask */
+ writeb(d, 0);
+ c = readb(d); /* set bg color in the latch */
+ /* foreground color */
+ if (flip)
+ col = (on) ? (a & 0x0f00) : ((a & 0xf000) >> 4);
+ else
+ col = (on) ? ((a & 0xf000) >> 4) : (a & 0x0f00);
+ outw(GDCIDX, col | 0x00); /* set/reset */
+ f = &(scp->font[sc_vtb_getc(&scp->vtb, at)*scp->font_size
+ + scp->font_size - scp->cursor_base - 1]);
+ height = imin(scp->cursor_height, scp->font_size);
+ for (i = 0; i < height; ++i, --f) {
+ outw(GDCIDX, (*f << 8) | 0x08); /* bit mask */
+ writeb(d, 0);
+ d -= line_width;
+ }
+ outw(GDCIDX, 0x0000); /* set/reset */
+ outw(GDCIDX, 0x0001); /* set/reset enable */
+ outw(GDCIDX, 0xff08); /* bit mask */
+}
+
+static void
+vga_pxlcursor(scr_stat *scp, int at, int blink, int on, int flip)
+{
+ if (scp->cursor_height <= 0) /* the text cursor is disabled */
+ return;
+
+ if (on) {
+ scp->status |= VR_CURSOR_ON;
+ draw_pxlcursor(scp, at, on, flip);
+ } else {
+ if (scp->status & VR_CURSOR_ON)
+ draw_pxlcursor(scp, at, on, flip);
+ scp->status &= ~VR_CURSOR_ON;
+ }
+ if (blink)
+ scp->status |= VR_CURSOR_BLINK;
+ else
+ scp->status &= ~VR_CURSOR_BLINK;
+}
+
+static void
+vga_pxlblink(scr_stat *scp, int at, int flip)
+{
+ static int blinkrate = 0;
+
+ if (!(scp->status & VR_CURSOR_BLINK))
+ return;
+ if (!(++blinkrate & 4))
+ return;
+ blinkrate = 0;
+ scp->status ^= VR_CURSOR_ON;
+ draw_pxlcursor(scp, at, scp->status & VR_CURSOR_ON, flip);
+}
+
+#ifndef SC_NO_CUTPASTE
+
+static void
+draw_pxlmouse(scr_stat *scp, int x, int y)
+{
+ vm_offset_t p;
+ int line_width;
+ int xoff, yoff;
+ int ymax;
+ u_short m;
+ int i, j;
+
+ line_width = scp->sc->adp->va_line_width;
+ xoff = (x - scp->xoff*8)%8;
+ yoff = y - (y/line_width)*line_width;
+ ymax = imin(y + 16, scp->ypixel);
+
+ outw(GDCIDX, 0x0805); /* read mode 1, write mode 0 */
+ outw(GDCIDX, 0x0001); /* set/reset enable */
+ outw(GDCIDX, 0x0002); /* color compare */
+ outw(GDCIDX, 0x0007); /* color don't care */
+ outw(GDCIDX, 0xff08); /* bit mask */
+ outw(GDCIDX, 0x0803); /* data rotate/function select (and) */
+ p = scp->sc->adp->va_window + line_width*y + x/8;
+ if (x < scp->xpixel - 16) {
+ for (i = y, j = 0; i < ymax; ++i, ++j) {
+ m = ~(mouse_and_mask[j] >> xoff);
+#ifdef __i386__
+ *(u_char *)p &= m >> 8;
+ *(u_char *)(p + 1) &= m;
+#elif defined(__alpha__)
+ writeb(p, readb(p) & (m >> 8));
+ writeb(p + 1, readb(p + 1) & (m >> 8));
+#endif
+ p += line_width;
+ }
+ } else {
+ xoff += 8;
+ for (i = y, j = 0; i < ymax; ++i, ++j) {
+ m = ~(mouse_and_mask[j] >> xoff);
+#ifdef __i386__
+ *(u_char *)p &= m;
+#elif defined(__alpha__)
+ writeb(p, readb(p) & (m >> 8));
+#endif
+ p += line_width;
+ }
+ }
+ outw(GDCIDX, 0x1003); /* data rotate/function select (or) */
+ p = scp->sc->adp->va_window + line_width*y + x/8;
+ if (x < scp->xpixel - 16) {
+ for (i = y, j = 0; i < ymax; ++i, ++j) {
+ m = mouse_or_mask[j] >> xoff;
+#ifdef __i386__
+ *(u_char *)p &= m >> 8;
+ *(u_char *)(p + 1) &= m;
+#elif defined(__alpha__)
+ writeb(p, readb(p) & (m >> 8));
+ writeb(p + 1, readb(p + 1) & (m >> 8));
+#endif
+ p += line_width;
+ }
+ } else {
+ for (i = y, j = 0; i < ymax; ++i, ++j) {
+ m = mouse_or_mask[j] >> xoff;
+#ifdef __i386__
+ *(u_char *)p &= m;
+#elif defined(__alpha__)
+ writeb(p, readb(p) & (m >> 8));
+#endif
+ p += line_width;
+ }
+ }
+ outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */
+ outw(GDCIDX, 0x0003); /* data rotate/function select */
+}
+
+static void
+remove_pxlmouse(scr_stat *scp, int x, int y)
+{
+ vm_offset_t p;
+ int col, row;
+ int pos;
+ int line_width;
+ int ymax;
+ int i;
+
+ /* erase the mouse cursor image */
+ col = x/8 - scp->xoff;
+ row = y/scp->font_size - scp->yoff;
+ pos = row*scp->xsize + col;
+ i = (col < scp->xsize - 1) ? 2 : 1;
+ (*scp->rndr->draw)(scp, pos, i, FALSE);
+ if (row < scp->ysize - 1)
+ (*scp->rndr->draw)(scp, pos + scp->xsize, i, FALSE);
+
+ /* paint border if necessary */
+ line_width = scp->sc->adp->va_line_width;
+ outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */
+ outw(GDCIDX, 0x0003); /* data rotate/function select */
+ outw(GDCIDX, 0x0f01); /* set/reset enable */
+ outw(GDCIDX, 0xff08); /* bit mask */
+ outw(GDCIDX, (scp->border << 8) | 0x00); /* set/reset */
+ if (row == scp->ysize - 1) {
+ i = (scp->ysize + scp->yoff)*scp->font_size;
+ ymax = imin(i + scp->font_size, scp->ypixel);
+ p = scp->sc->adp->va_window + i*line_width + scp->xoff + col;
+ if (col < scp->xsize - 1) {
+ for (; i < ymax; ++i) {
+ writeb(p, 0);
+ writeb(p + 1, 0);
+ p += line_width;
+ }
+ } else {
+ for (; i < ymax; ++i) {
+ writeb(p, 0);
+ p += line_width;
+ }
+ }
+ }
+ if ((col == scp->xsize - 1) && (scp->xoff > 0)) {
+ i = (row + scp->yoff)*scp->font_size;
+ ymax = imin(i + scp->font_size*2, scp->ypixel);
+ p = scp->sc->adp->va_window + i*line_width
+ + scp->xoff + scp->xsize;
+ for (; i < ymax; ++i) {
+ writeb(p, 0);
+ p += line_width;
+ }
+ }
+ outw(GDCIDX, 0x0000); /* set/reset */
+ outw(GDCIDX, 0x0001); /* set/reset enable */
+}
+
+static void
+vga_pxlmouse(scr_stat *scp, int x, int y, int on)
+{
+ if (on)
+ draw_pxlmouse(scp, x, y);
+ else
+ remove_pxlmouse(scp, x, y);
+}
+
+#endif /* SC_NO_CUTPASTE */
+#endif /* SC_PIXEL_MODE */
+
+#ifndef SC_NO_MODE_CHANGE
+
+/* graphics mode renderer */
+
+static void
+vga_grborder(scr_stat *scp, int color)
+{
+ (*vidsw[scp->sc->adapter]->set_border)(scp->sc->adp, color);
+}
+
+#endif
+
+#endif /* NSC > 0 && NVGA > 0 */
diff --git a/sys/dev/syscons/scvidctl.c b/sys/dev/syscons/scvidctl.c
index 732f386c..f84b14d 100644
--- a/sys/dev/syscons/scvidctl.c
+++ b/sys/dev/syscons/scvidctl.c
@@ -23,7 +23,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: scvidctl.c,v 1.7 1999/01/19 11:31:16 yokota Exp $
+ * $Id: $
*/
#include "sc.h"
@@ -37,19 +37,21 @@
#include <sys/tty.h>
#include <sys/kernel.h>
-#ifdef __i386__
-#include <machine/apm_bios.h>
-#endif
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
#include <machine/console.h>
#include <dev/fb/fbreg.h>
#include <dev/syscons/syscons.h>
/* for compatibility with previous versions */
+/* 3.0-RELEASE used the following structure */
typedef struct old_video_adapter {
int va_index;
int va_type;
int va_flags;
+/* flag bits are the same as the -CURRENT
#define V_ADP_COLOR (1<<0)
#define V_ADP_MODECHANGE (1<<1)
#define V_ADP_STATESAVE (1<<2)
@@ -58,6 +60,7 @@ typedef struct old_video_adapter {
#define V_ADP_PALETTE (1<<5)
#define V_ADP_BORDER (1<<6)
#define V_ADP_VESA (1<<7)
+*/
int va_crtc_addr;
u_int va_window; /* virtual address */
size_t va_window_size;
@@ -71,39 +74,100 @@ typedef struct old_video_adapter {
#define OLD_CONS_ADPINFO _IOWR('c', 101, old_video_adapter_t)
-/* variables */
-extern scr_stat *cur_console;
-extern int fonts_loaded;
-extern int sc_history_size;
-extern u_char palette[];
+/* 3.1-RELEASE used the following structure */
+typedef struct old_video_adapter_info {
+ int va_index;
+ int va_type;
+ char va_name[16];
+ int va_unit;
+ int va_flags;
+ int va_io_base;
+ int va_io_size;
+ int va_crtc_addr;
+ int va_mem_base;
+ int va_mem_size;
+ u_int va_window; /* virtual address */
+ size_t va_window_size;
+ size_t va_window_gran;
+ u_int va_buffer;;
+ size_t va_buffer_size;
+ int va_initial_mode;
+ int va_initial_bios_mode;
+ int va_mode;
+ int va_line_width;
+} old_video_adapter_info_t;
+
+#define OLD_CONS_ADPINFO2 _IOWR('c', 101, old_video_adapter_info_t)
+
+/* 3.0-RELEASE and 3.1-RELEASE used the following structure */
+typedef struct old_video_info {
+ int vi_mode;
+ int vi_flags;
+/* flag bits are the same as the -CURRENT
+#define V_INFO_COLOR (1<<0)
+#define V_INFO_GRAPHICS (1<<1)
+#define V_INFO_LINEAR (1<<2)
+#define V_INFO_VESA (1<<3)
+*/
+ int vi_width;
+ int vi_height;
+ int vi_cwidth;
+ int vi_cheight;
+ int vi_depth;
+ int vi_planes;
+ u_int vi_window; /* physical address */
+ size_t vi_window_size;
+ size_t vi_window_gran;
+ u_int vi_buffer; /* physical address */
+ size_t vi_buffer_size;
+} old_video_info_t;
+
+#define OLD_CONS_MODEINFO _IOWR('c', 102, old_video_info_t)
+#define OLD_CONS_FINDMODE _IOWR('c', 103, old_video_info_t)
int
sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, int xsize, int ysize,
int fontsize)
{
video_info_t info;
+ sc_rndr_sw_t *rndr;
+ u_char *font;
int error;
int s;
- int i;
- if ((*vidsw[scp->ad]->get_info)(scp->adp, mode, &info))
+ if ((*vidsw[scp->sc->adapter]->get_info)(scp->sc->adp, mode, &info))
return ENODEV;
-
+
/* adjust argument values */
if (fontsize <= 0)
fontsize = info.vi_cheight;
if (fontsize < 14) {
fontsize = 8;
- if (!(fonts_loaded & FONT_8))
+#ifndef SC_NO_FONT_LOADING
+ if (!(scp->sc->fonts_loaded & FONT_8))
return EINVAL;
+ font = scp->sc->font_8;
+#else
+ font = NULL;
+#endif
} else if (fontsize >= 16) {
fontsize = 16;
- if (!(fonts_loaded & FONT_16))
+#ifndef SC_NO_FONT_LOADING
+ if (!(scp->sc->fonts_loaded & FONT_16))
return EINVAL;
+ font = scp->sc->font_16;
+#else
+ font = NULL;
+#endif
} else {
fontsize = 14;
- if (!(fonts_loaded & FONT_14))
+#ifndef SC_NO_FONT_LOADING
+ if (!(scp->sc->fonts_loaded & FONT_14))
return EINVAL;
+ font = scp->sc->font_14;
+#else
+ font = NULL;
+#endif
}
if ((xsize <= 0) || (xsize > info.vi_width))
xsize = info.vi_width;
@@ -117,12 +181,13 @@ sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, int xsize, int ysize,
return error;
}
+ rndr = sc_render_match(scp, scp->sc->adp, 0);
+ if (rndr == NULL) {
+ splx(s);
+ return ENODEV;
+ }
+
/* 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
@@ -130,22 +195,27 @@ sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, int xsize, int ysize,
scp->status |= UNKNOWN_MODE;
scp->status &= ~(GRAPHICS_MODE | PIXEL_MODE);
scp->mode = mode;
- scp->font_size = fontsize;
scp->xsize = xsize;
scp->ysize = ysize;
scp->xoff = 0;
scp->yoff = 0;
scp->xpixel = scp->xsize*8;
scp->ypixel = scp->ysize*fontsize;
+ scp->font = font;
+ scp->font_size = fontsize;
/* allocate buffers */
sc_alloc_scr_buffer(scp, TRUE, TRUE);
- if (ISMOUSEAVAIL(scp->adp->va_flags))
- sc_alloc_cut_buffer(scp, FALSE);
- sc_alloc_history_buffer(scp, sc_history_size, i, FALSE);
+#ifndef SC_NO_CUTPASTE
+ sc_alloc_cut_buffer(scp, FALSE);
+#endif
+#ifndef SC_NO_HISTORY
+ sc_alloc_history_buffer(scp, 0, FALSE);
+#endif
+ scp->rndr = rndr;
splx(s);
- if (scp == cur_console)
+ if (scp == scp->sc->cur_scp)
set_mode(scp);
scp->status &= ~UNKNOWN_MODE;
@@ -164,11 +234,15 @@ sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, int xsize, int ysize,
int
sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode)
{
+#ifdef SC_NO_MODE_CHANGE
+ return ENODEV;
+#else
video_info_t info;
+ sc_rndr_sw_t *rndr;
int error;
int s;
- if ((*vidsw[scp->ad]->get_info)(scp->adp, mode, &info))
+ if ((*vidsw[scp->sc->adapter]->get_info)(scp->sc->adp, mode, &info))
return ENODEV;
/* stop screen saver, etc */
@@ -178,22 +252,32 @@ sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode)
return error;
}
+ rndr = sc_render_match(scp, scp->sc->adp, GRAPHICS_MODE);
+ if (rndr == NULL) {
+ splx(s);
+ return ENODEV;
+ }
+
/* set up scp */
scp->status |= (UNKNOWN_MODE | GRAPHICS_MODE);
scp->status &= ~PIXEL_MODE;
scp->mode = mode;
+ scp->xsize = info.vi_width/8;
+ scp->ysize = info.vi_height/info.vi_cheight;
scp->xoff = 0;
scp->yoff = 0;
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 = NULL;
scp->font_size = FONT_NONE;
+#ifndef SC_NO_SYSMOUSE
/* move the mouse cursor at the center of the screen */
- sc_move_mouse(scp, scp->xpixel / 2, scp->ypixel / 2);
+ sc_mouse_move(scp, scp->xpixel / 2, scp->ypixel / 2);
+#endif
+ scp->rndr = rndr;
splx(s);
- if (scp == cur_console)
+ if (scp == scp->sc->cur_scp)
set_mode(scp);
/* clear_graphics();*/
scp->status &= ~UNKNOWN_MODE;
@@ -208,18 +292,23 @@ sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode)
}
return 0;
+#endif /* SC_NO_MODE_CHANGE */
}
int
sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize,
int fontsize)
{
+#ifndef SC_PIXEL_MODE
+ return ENODEV;
+#else
video_info_t info;
+ sc_rndr_sw_t *rndr;
+ u_char *font;
int error;
int s;
- int i;
- if ((*vidsw[scp->ad]->get_info)(scp->adp, scp->mode, &info))
+ if ((*vidsw[scp->sc->adapter]->get_info)(scp->sc->adp, scp->mode, &info))
return ENODEV; /* this shouldn't happen */
#ifdef SC_VIDEO_DEBUG
@@ -234,16 +323,31 @@ sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize,
fontsize = info.vi_cheight;
if (fontsize < 14) {
fontsize = 8;
- if (!(fonts_loaded & FONT_8))
+#ifndef SC_NO_FONT_LOADING
+ if (!(scp->sc->fonts_loaded & FONT_8))
return EINVAL;
+ font = scp->sc->font_8;
+#else
+ font = NULL;
+#endif
} else if (fontsize >= 16) {
fontsize = 16;
- if (!(fonts_loaded & FONT_16))
+#ifndef SC_NO_FONT_LOADING
+ if (!(scp->sc->fonts_loaded & FONT_16))
return EINVAL;
+ font = scp->sc->font_16;
+#else
+ font = NULL;
+#endif
} else {
fontsize = 14;
- if (!(fonts_loaded & FONT_14))
+#ifndef SC_NO_FONT_LOADING
+ if (!(scp->sc->fonts_loaded & FONT_14))
return EINVAL;
+ font = scp->sc->font_14;
+#else
+ font = NULL;
+#endif
}
if (xsize <= 0)
xsize = info.vi_width/8;
@@ -254,8 +358,8 @@ sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize,
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(): window:%x, %dx%d, xoff:%d, yoff:%d\n",
- scp->adp->va_window, info.vi_width, info.vi_height,
+ printf("set_pixel_mode(): window:%p, %dx%d, xoff:%d, yoff:%d\n",
+ (void *)scp->sc->adp->va_window, info.vi_width, info.vi_height,
(info.vi_width/8 - xsize)/2,
(info.vi_height/fontsize - ysize)/2);
}
@@ -283,29 +387,37 @@ sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize,
return error;
}
+ rndr = sc_render_match(scp, scp->sc->adp, PIXEL_MODE);
+ if (rndr == NULL) {
+ splx(s);
+ return ENODEV;
+ }
+
/* 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->status &= ~GRAPHICS_MODE;
scp->xsize = xsize;
scp->ysize = ysize;
- scp->font_size = fontsize;
scp->xoff = (scp->xpixel/8 - xsize)/2;
scp->yoff = (scp->ypixel/fontsize - ysize)/2;
+ scp->font = font;
+ scp->font_size = fontsize;
/* allocate buffers */
sc_alloc_scr_buffer(scp, TRUE, TRUE);
- if (ISMOUSEAVAIL(scp->adp->va_flags))
- sc_alloc_cut_buffer(scp, FALSE);
- sc_alloc_history_buffer(scp, sc_history_size, i, FALSE);
+#ifndef SC_NO_CUTPASTE
+ sc_alloc_cut_buffer(scp, FALSE);
+#endif
+#ifndef SC_NO_HISTORY
+ sc_alloc_history_buffer(scp, 0, FALSE);
+#endif
+ scp->rndr = rndr;
splx(s);
- if (scp == cur_console)
+ if (scp == scp->sc->cur_scp) {
set_border(scp, scp->border);
+ sc_set_cursor_image(scp);
+ }
scp->status &= ~UNKNOWN_MODE;
@@ -323,99 +435,182 @@ sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize,
}
return 0;
+#endif /* SC_PIXEL_MODE */
+}
+
+sc_rndr_sw_t
+*sc_render_match(scr_stat *scp, video_adapter_t *adp, int mode)
+{
+ const sc_renderer_t **list;
+ const sc_renderer_t *p;
+
+ list = (const sc_renderer_t **)scrndr_set.ls_items;
+ while ((p = *list++) != NULL) {
+ if ((strcmp(p->name, adp->va_name) == 0)
+ && (mode == p->mode)) {
+ scp->status &= ~(VR_CURSOR_ON | VR_CURSOR_BLINK);
+ return p->rndrsw;
+ }
+ }
+
+ return NULL;
}
+#define fb_ioctl(a, c, d) \
+ (((a) == NULL) ? ENODEV : \
+ (*vidsw[(a)->va_index]->ioctl)((a), (c), (caddr_t)(d)))
+
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;
+ video_info_t info;
+ video_adapter_info_t adp_info;
int error;
int s;
scp = sc_get_scr_stat(tp->t_dev);
+ if (scp == NULL) /* tp == SC_MOUSE */
+ return ENOIOCTL;
+ adp = scp->sc->adp;
+ if (adp == NULL) /* shouldn't happen??? */
+ return ENODEV;
switch (cmd) {
- case CONS_CURRENT: /* get current adapter type */
- if (scp->adp == NULL)
- return ENODEV;
- *(int *)data = scp->adp->va_type;
- return 0;
-
case CONS_CURRENTADP: /* get current adapter index */
- *(int *)data = scp->ad;
- return 0;
+ case FBIO_ADAPTER:
+ return fb_ioctl(adp, FBIO_ADAPTER, data);
- case OLD_CONS_ADPINFO: /* adapter information */
- if (scp->adp == NULL)
- return ENODEV;
- ((old_video_adapter_t *)data)->va_index = scp->adp->va_index;
- ((old_video_adapter_t *)data)->va_type = scp->adp->va_type;
- ((old_video_adapter_t *)data)->va_flags = scp->adp->va_flags;
- ((old_video_adapter_t *)data)->va_crtc_addr = scp->adp->va_crtc_addr;
- ((old_video_adapter_t *)data)->va_window = scp->adp->va_window;
- ((old_video_adapter_t *)data)->va_window_size
- = scp->adp->va_window_size;
- ((old_video_adapter_t *)data)->va_window_gran
- = scp->adp->va_window_gran;
- ((old_video_adapter_t *)data)->va_buffer = scp->adp->va_buffer;
- ((old_video_adapter_t *)data)->va_buffer_size
- = scp->adp->va_buffer_size;
- ((old_video_adapter_t *)data)->va_mode = scp->adp->va_mode;
- ((old_video_adapter_t *)data)->va_initial_mode
- = scp->adp->va_initial_mode;
+ case CONS_CURRENT: /* get current adapter type */
+ case FBIO_ADPTYPE:
+ return fb_ioctl(adp, FBIO_ADPTYPE, data);
+
+ case OLD_CONS_ADPINFO: /* adapter information (old interface) */
+ if (((old_video_adapter_t *)data)->va_index >= 0) {
+ adp = vid_get_adapter(((old_video_adapter_t *)data)->va_index);
+ if (adp == NULL)
+ return ENODEV;
+ }
+ ((old_video_adapter_t *)data)->va_index = adp->va_index;
+ ((old_video_adapter_t *)data)->va_type = adp->va_type;
+ ((old_video_adapter_t *)data)->va_flags = adp->va_flags;
+ ((old_video_adapter_t *)data)->va_crtc_addr = adp->va_crtc_addr;
+ ((old_video_adapter_t *)data)->va_window = adp->va_window;
+ ((old_video_adapter_t *)data)->va_window_size = adp->va_window_size;
+ ((old_video_adapter_t *)data)->va_window_gran = adp->va_window_gran;
+ ((old_video_adapter_t *)data)->va_buffer = adp->va_buffer;
+ ((old_video_adapter_t *)data)->va_buffer_size = adp->va_buffer_size;
+ ((old_video_adapter_t *)data)->va_mode = adp->va_mode;
+ ((old_video_adapter_t *)data)->va_initial_mode = adp->va_initial_mode;
((old_video_adapter_t *)data)->va_initial_bios_mode
- = scp->adp->va_initial_bios_mode;
+ = adp->va_initial_bios_mode;
return 0;
+ case OLD_CONS_ADPINFO2: /* adapter information (yet another old I/F) */
+ adp_info.va_index = ((old_video_adapter_info_t *)data)->va_index;
+ if (adp_info.va_index >= 0) {
+ adp = vid_get_adapter(adp_info.va_index);
+ if (adp == NULL)
+ return ENODEV;
+ }
+ error = fb_ioctl(adp, FBIO_ADPINFO, &adp_info);
+ if (error == 0)
+ bcopy(&adp_info, data, sizeof(old_video_adapter_info_t));
+ return error;
+
case CONS_ADPINFO: /* adapter information */
- if (scp->adp == NULL)
- return ENODEV;
- ((video_adapter_info_t *)data)->va_index = scp->adp->va_index;
- ((video_adapter_info_t *)data)->va_type = scp->adp->va_type;
- bcopy(scp->adp->va_name, ((video_adapter_info_t *)data)->va_name,
- imin(strlen(scp->adp->va_name) + 1,
- sizeof(((video_adapter_info_t *)data)->va_name)));
- ((video_adapter_info_t *)data)->va_unit = scp->adp->va_unit;
- ((video_adapter_info_t *)data)->va_flags = scp->adp->va_flags;
- ((video_adapter_info_t *)data)->va_io_base = scp->adp->va_io_base;
- ((video_adapter_info_t *)data)->va_io_size = scp->adp->va_io_size;
- ((video_adapter_info_t *)data)->va_crtc_addr = scp->adp->va_crtc_addr;
- ((video_adapter_info_t *)data)->va_mem_base = scp->adp->va_mem_base;
- ((video_adapter_info_t *)data)->va_mem_size = scp->adp->va_mem_size;
- ((video_adapter_info_t *)data)->va_window = scp->adp->va_window;
- ((video_adapter_info_t *)data)->va_window_size
- = scp->adp->va_window_size;
- ((video_adapter_info_t *)data)->va_window_gran
- = scp->adp->va_window_gran;
- ((video_adapter_info_t *)data)->va_buffer = scp->adp->va_buffer;
- ((video_adapter_info_t *)data)->va_buffer_size
- = scp->adp->va_buffer_size;
- ((video_adapter_info_t *)data)->va_mode = scp->adp->va_mode;
- ((video_adapter_info_t *)data)->va_initial_mode
- = scp->adp->va_initial_mode;
- ((video_adapter_info_t *)data)->va_initial_bios_mode
- = scp->adp->va_initial_bios_mode;
- ((video_adapter_info_t *)data)->va_line_width = scp->adp->va_line_width;
- return 0;
+ case FBIO_ADPINFO:
+ if (((video_adapter_info_t *)data)->va_index >= 0) {
+ adp = vid_get_adapter(((video_adapter_info_t *)data)->va_index);
+ if (adp == NULL)
+ return ENODEV;
+ }
+ return fb_ioctl(adp, FBIO_ADPINFO, data);
case CONS_GET: /* get current video mode */
+ case FBIO_GETMODE:
*(int *)data = scp->mode;
return 0;
+#ifndef SC_NO_MODE_CHANGE
+ case FBIO_SETMODE: /* set video mode */
+ if (!(adp->va_flags & V_ADP_MODECHANGE))
+ return ENODEV;
+ info.vi_mode = *(int *)data;
+ error = fb_ioctl(adp, FBIO_MODEINFO, &info);
+ if (error)
+ return error;
+ if (info.vi_flags & V_INFO_GRAPHICS)
+ return sc_set_graphics_mode(scp, tp, *(int *)data);
+ else
+ return sc_set_text_mode(scp, tp, *(int *)data, 0, 0, 0);
+#endif /* SC_NO_MODE_CHANGE */
+
+ case OLD_CONS_MODEINFO: /* get mode information (old infterface) */
+ info.vi_mode = ((old_video_info_t *)data)->vi_mode;
+ error = fb_ioctl(adp, FBIO_MODEINFO, &info);
+ if (error == 0)
+ bcopy(&info, (old_video_info_t *)data, sizeof(old_video_info_t));
+ return error;
+
case CONS_MODEINFO: /* get mode information */
- return ((*vidsw[scp->ad]->get_info)(scp->adp,
- ((video_info_t *)data)->vi_mode, (video_info_t *)data)
- ? ENODEV : 0);
+ case FBIO_MODEINFO:
+ return fb_ioctl(adp, FBIO_MODEINFO, data);
+
+ case OLD_CONS_FINDMODE: /* find a matching video mode (old interface) */
+ bzero(&info, sizeof(info));
+ bcopy((old_video_info_t *)data, &info, sizeof(old_video_info_t));
+ error = fb_ioctl(adp, FBIO_FINDMODE, &info);
+ if (error == 0)
+ bcopy(&info, (old_video_info_t *)data, sizeof(old_video_info_t));
+ return error;
case CONS_FINDMODE: /* find a matching video mode */
- return ((*vidsw[scp->ad]->query_mode)(scp->adp, (video_info_t *)data)
- ? ENODEV : 0);
-
- case CONS_SETWINORG:
- return ((*vidsw[scp->ad]->set_win_org)(scp->adp, *(u_int *)data)
- ? ENODEV : 0);
+ case FBIO_FINDMODE:
+ return fb_ioctl(adp, FBIO_FINDMODE, data);
+
+ case CONS_SETWINORG: /* set frame buffer window origin */
+ case FBIO_SETWINORG:
+ if (scp != scp->sc->cur_scp)
+ return ENODEV; /* XXX */
+ return fb_ioctl(adp, FBIO_SETWINORG, data);
+
+ case FBIO_GETWINORG: /* get frame buffer window origin */
+ if (scp != scp->sc->cur_scp)
+ return ENODEV; /* XXX */
+ return fb_ioctl(adp, FBIO_GETWINORG, data);
+
+ case FBIO_GETDISPSTART:
+ case FBIO_SETDISPSTART:
+ case FBIO_GETLINEWIDTH:
+ case FBIO_SETLINEWIDTH:
+ if (scp != scp->sc->cur_scp)
+ return ENODEV; /* XXX */
+ return fb_ioctl(adp, cmd, data);
+
+ /* XXX */
+ case FBIO_GETPALETTE:
+ case FBIO_SETPALETTE:
+ case FBIOPUTCMAP:
+ case FBIOGETCMAP:
+ return ENODEV;
+ case FBIOGTYPE:
+ case FBIOGATTR:
+ case FBIOSVIDEO:
+ case FBIOGVIDEO:
+ case FBIOSCURSOR:
+ case FBIOGCURSOR:
+ case FBIOSCURPOS:
+ case FBIOGCURPOS:
+ case FBIOGCURMAX:
+ if (scp != scp->sc->cur_scp)
+ return ENODEV; /* XXX */
+ return fb_ioctl(adp, cmd, data);
+
+#ifndef SC_NO_MODE_CHANGE
/* generic text modes */
case SW_TEXT_80x25: case SW_TEXT_80x30:
case SW_TEXT_80x43: case SW_TEXT_80x50:
@@ -428,6 +623,11 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p)
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_VGA_C90x25: case SW_VGA_M90x25:
+ case SW_VGA_C90x30: case SW_VGA_M90x30:
+ case SW_VGA_C90x43: case SW_VGA_M90x43:
+ case SW_VGA_C90x50: case SW_VGA_M90x50:
+ case SW_VGA_C90x60: case SW_VGA_M90x60:
case SW_B40x25: case SW_C40x25:
case SW_B80x25: case SW_C80x25:
case SW_ENH_B40x25: case SW_ENH_C40x25:
@@ -440,7 +640,7 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p)
case SW_PC98_80x25:
case SW_PC98_80x30:
#endif
- if (!(scp->adp->va_flags & V_ADP_MODECHANGE))
+ if (!(adp->va_flags & V_ADP_MODECHANGE))
return ENODEV;
return sc_set_text_mode(scp, tp, cmd & 0xff, 0, 0, 0);
@@ -450,9 +650,10 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p)
case SW_CG640x350: case SW_ENH_CG640:
case SW_BG640x480: case SW_CG640x480: case SW_VGA_CG320:
case SW_VGA_MODEX:
- if (!(scp->adp->va_flags & V_ADP_MODECHANGE))
+ if (!(adp->va_flags & V_ADP_MODECHANGE))
return ENODEV;
return sc_set_graphics_mode(scp, tp, cmd & 0xff);
+#endif /* SC_NO_MODE_CHANGE */
case KDSETMODE: /* set current mode of this (virtual) console */
switch (*(int *)data) {
@@ -465,24 +666,31 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p)
return EINVAL;
/* restore fonts & palette ! */
#if 0
- if (ISFONTAVAIL(scp->adp->va_flags)
+#ifndef SC_NO_FONT_LOADING
+ 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);
+ if (scp->sc->fonts_loaded & FONT_8)
+ copy_font(scp, LOAD, 8, scp->sc->font_8);
+ if (scp->sc->fonts_loaded & FONT_14)
+ copy_font(scp, LOAD, 14, scp->sc->font_14);
+ if (scp->sc->fonts_loaded & FONT_16)
+ copy_font(scp, LOAD, 16, scp->sc->font_16);
}
+#endif /* SC_NO_FONT_LOADING */
#endif
- load_palette(scp->adp, palette);
+#ifndef SC_NO_PALETTE_LOADING
+ load_palette(adp, scp->sc->palette);
+#endif
+
+#ifndef PC98
/* move hardware cursor out of the way */
- (*vidsw[scp->ad]->set_hw_cursor)(scp->adp, -1, -1);
+ (*vidsw[adp->va_index]->set_hw_cursor)(adp, -1, -1);
+#endif
/* FALL THROUGH */
@@ -502,20 +710,21 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p)
scp->status |= UNKNOWN_MODE;
splx(s);
/* no restore fonts & palette */
- if (scp == cur_console)
+ if (scp == scp->sc->cur_scp)
set_mode(scp);
sc_clear_screen(scp);
scp->status &= ~UNKNOWN_MODE;
#else /* PC98 */
scp->status &= ~UNKNOWN_MODE;
/* no restore fonts & palette */
- if (scp == cur_console)
+ if (scp == scp->sc->cur_scp)
set_mode(scp);
sc_clear_screen(scp);
splx(s);
#endif /* PC98 */
return 0;
+#ifdef SC_PIXEL_MODE
case KD_PIXEL: /* pixel (raster) display */
if (!(scp->status & (GRAPHICS_MODE | PIXEL_MODE)))
return EINVAL;
@@ -529,13 +738,16 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p)
}
scp->status |= (UNKNOWN_MODE | PIXEL_MODE);
splx(s);
- if (scp == cur_console) {
+ if (scp == scp->sc->cur_scp) {
set_mode(scp);
- load_palette(scp->adp, palette);
+#ifndef SC_NO_PALETTE_LOADING
+ load_palette(adp, scp->sc->palette);
+#endif
}
sc_clear_screen(scp);
scp->status &= ~UNKNOWN_MODE;
return 0;
+#endif /* SC_PIXEL_MODE */
case KD_GRAPHICS: /* switch to GRAPHICS (unknown) mode */
s = spltty();
@@ -546,7 +758,7 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p)
scp->status |= UNKNOWN_MODE;
splx(s);
#ifdef PC98
- if (scp == cur_console)
+ if (scp == scp->sc->cur_scp)
set_mode(scp);
#endif
return 0;
@@ -556,11 +768,13 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p)
}
/* NOT REACHED */
+#ifdef SC_PIXEL_MODE
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]);
+#endif /* SC_PIXEL_MODE */
case KDGETMODE: /* get current mode of this (virtual) console */
/*
@@ -572,7 +786,7 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p)
case KDSBORDER: /* set border color of this (virtual) console */
scp->border = *data;
- if (scp == cur_console)
+ if (scp == scp->sc->cur_scp)
set_border(scp, scp->border);
return 0;
}
diff --git a/sys/dev/syscons/scvtb.c b/sys/dev/syscons/scvtb.c
new file mode 100644
index 0000000..a7d1a71
--- /dev/null
+++ b/sys/dev/syscons/scvtb.c
@@ -0,0 +1,283 @@
+/*-
+ * Copyright (c) 1999 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 as
+ * the first lines of this file unmodified.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id:$
+ */
+
+#include "sc.h"
+#include "opt_syscons.h"
+
+#if NSC > 0
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+
+#include <machine/console.h>
+#include <machine/md_var.h>
+
+#include <dev/fb/fbreg.h>
+#include <dev/syscons/syscons.h>
+
+#define vtb_wrap(vtb, at, offset) \
+ (((at) + (offset) + (vtb)->vtb_size)%(vtb)->vtb_size)
+
+void
+sc_vtb_init(sc_vtb_t *vtb, int type, int cols, int rows, void *buf, int wait)
+{
+ vtb->vtb_flags = 0;
+ vtb->vtb_type = type;
+ vtb->vtb_cols = cols;
+ vtb->vtb_rows = rows;
+ vtb->vtb_size = cols*rows;
+ vtb->vtb_buffer = NULL;
+ vtb->vtb_tail = 0;
+
+ switch (type) {
+ case VTB_MEMORY:
+ case VTB_RINGBUFFER:
+ if ((buf == NULL) && (cols*rows != 0)) {
+ vtb->vtb_buffer =
+ (vm_offset_t)malloc(cols*rows*sizeof(u_int16_t),
+ M_DEVBUF,
+ (wait) ? M_WAITOK : M_NOWAIT);
+ if (vtb->vtb_buffer != NULL)
+ bzero((void *)sc_vtb_pointer(vtb, 0),
+ cols*rows*sizeof(u_int16_t));
+ } else {
+ vtb->vtb_buffer = (vm_offset_t)buf;
+ }
+ vtb->vtb_flags |= VTB_VALID;
+ break;
+ case VTB_FRAMEBUFFER:
+ vtb->vtb_buffer = (vm_offset_t)buf;
+ vtb->vtb_flags |= VTB_VALID;
+ break;
+ default:
+ break;
+ }
+}
+
+void
+sc_vtb_destroy(sc_vtb_t *vtb)
+{
+ vm_offset_t p;
+
+ vtb->vtb_flags = 0;
+ vtb->vtb_cols = 0;
+ vtb->vtb_rows = 0;
+ vtb->vtb_size = 0;
+ vtb->vtb_tail = 0;
+
+ p = vtb->vtb_buffer;
+ vtb->vtb_buffer = NULL;
+ switch (vtb->vtb_type) {
+ case VTB_MEMORY:
+ case VTB_RINGBUFFER:
+ if (p != NULL)
+ free((void *)p, M_DEVBUF);
+ break;
+ default:
+ break;
+ }
+ vtb->vtb_type = VTB_INVALID;
+}
+
+size_t
+sc_vtb_size(int cols, int rows)
+{
+ return (size_t)(cols*rows*sizeof(u_int16_t));
+}
+
+int
+sc_vtb_getc(sc_vtb_t *vtb, int at)
+{
+ if (vtb->vtb_type == VTB_FRAMEBUFFER)
+ return (readw(sc_vtb_pointer(vtb, at)) & 0x00ff);
+ else
+ return (*(u_int16_t *)sc_vtb_pointer(vtb, at) & 0x00ff);
+}
+
+int
+sc_vtb_geta(sc_vtb_t *vtb, int at)
+{
+ if (vtb->vtb_type == VTB_FRAMEBUFFER)
+ return (readw(sc_vtb_pointer(vtb, at)) & 0xff00);
+ else
+ return (*(u_int16_t *)sc_vtb_pointer(vtb, at) & 0xff00);
+}
+
+void
+sc_vtb_putc(sc_vtb_t *vtb, int at, int c, int a)
+{
+ if (vtb->vtb_type == VTB_FRAMEBUFFER)
+ writew(sc_vtb_pointer(vtb, at), a | c);
+ else
+ *(u_int16_t *)sc_vtb_pointer(vtb, at) = a | c;
+}
+
+vm_offset_t
+sc_vtb_putchar(sc_vtb_t *vtb, vm_offset_t p, int c, int a)
+{
+ if (vtb->vtb_type == VTB_FRAMEBUFFER)
+ writew(p, a | c);
+ else
+ *(u_int16_t *)p = a | c;
+ return (p + sizeof(u_int16_t));
+}
+
+vm_offset_t
+sc_vtb_pointer(sc_vtb_t *vtb, int at)
+{
+ return (vtb->vtb_buffer + sizeof(u_int16_t)*(at));
+}
+
+int
+sc_vtb_pos(sc_vtb_t *vtb, int pos, int offset)
+{
+ return ((pos + offset + vtb->vtb_size)%vtb->vtb_size);
+}
+
+void
+sc_vtb_clear(sc_vtb_t *vtb, int c, int attr)
+{
+ if (vtb->vtb_type == VTB_FRAMEBUFFER)
+ fillw_io(attr | c, sc_vtb_pointer(vtb, 0), vtb->vtb_size);
+ else
+ fillw(attr | c, (void *)sc_vtb_pointer(vtb, 0), vtb->vtb_size);
+}
+
+void
+sc_vtb_copy(sc_vtb_t *vtb1, int from, sc_vtb_t *vtb2, int to, int count)
+{
+ /* XXX if both are VTB_VRAMEBUFFER... */
+ if (vtb2->vtb_type == VTB_FRAMEBUFFER) {
+ bcopy_toio(sc_vtb_pointer(vtb1, from),
+ sc_vtb_pointer(vtb2, to),
+ count*sizeof(u_int16_t));
+ } else if (vtb1->vtb_type == VTB_FRAMEBUFFER) {
+ bcopy_fromio(sc_vtb_pointer(vtb1, from),
+ sc_vtb_pointer(vtb2, to),
+ count*sizeof(u_int16_t));
+ } else {
+ bcopy((void *)sc_vtb_pointer(vtb1, from),
+ (void *)sc_vtb_pointer(vtb2, to),
+ count*sizeof(u_int16_t));
+ }
+}
+
+void
+sc_vtb_append(sc_vtb_t *vtb1, int from, sc_vtb_t *vtb2, int count)
+{
+ int len;
+
+ if (vtb2->vtb_type != VTB_RINGBUFFER)
+ return;
+
+ while (count > 0) {
+ len = imin(count, vtb2->vtb_size - vtb2->vtb_tail);
+ if (vtb1->vtb_type == VTB_FRAMEBUFFER) {
+ bcopy_fromio(sc_vtb_pointer(vtb1, from),
+ sc_vtb_pointer(vtb2, vtb2->vtb_tail),
+ len*sizeof(u_int16_t));
+ } else {
+ bcopy((void *)sc_vtb_pointer(vtb1, from),
+ (void *)sc_vtb_pointer(vtb2, vtb2->vtb_tail),
+ len*sizeof(u_int16_t));
+ }
+ from += len;
+ count -= len;
+ vtb2->vtb_tail = vtb_wrap(vtb2, vtb2->vtb_tail, len);
+ }
+}
+
+void
+sc_vtb_seek(sc_vtb_t *vtb, int pos)
+{
+ vtb->vtb_tail = pos%vtb->vtb_size;
+}
+
+void
+sc_vtb_erase(sc_vtb_t *vtb, int at, int count, int c, int attr)
+{
+ if (at + count > vtb->vtb_size)
+ count = vtb->vtb_size - at;
+ if (vtb->vtb_type == VTB_FRAMEBUFFER)
+ fillw_io(attr | c, sc_vtb_pointer(vtb, at), count);
+ else
+ fillw(attr | c, (void *)sc_vtb_pointer(vtb, at), count);
+}
+
+void
+sc_vtb_delete(sc_vtb_t *vtb, int at, int count, int c, int attr)
+{
+ int len;
+
+ if (at + count > vtb->vtb_size)
+ count = vtb->vtb_size - at;
+ len = vtb->vtb_size - at - count;
+ if (len > 0) {
+ if (vtb->vtb_type == VTB_FRAMEBUFFER) {
+ bcopy_io(sc_vtb_pointer(vtb, at + count),
+ sc_vtb_pointer(vtb, at),
+ len*sizeof(u_int16_t));
+ } else {
+ bcopy((void *)sc_vtb_pointer(vtb, at + count),
+ (void *)sc_vtb_pointer(vtb, at),
+ len*sizeof(u_int16_t));
+ }
+ }
+ if (vtb->vtb_type == VTB_FRAMEBUFFER)
+ fillw_io(attr | c, sc_vtb_pointer(vtb, at + len),
+ vtb->vtb_size - at - len);
+ else
+ fillw(attr | c, (void *)sc_vtb_pointer(vtb, at + len),
+ vtb->vtb_size - at - len);
+}
+
+void
+sc_vtb_ins(sc_vtb_t *vtb, int at, int count, int c, int attr)
+{
+ if (at + count > vtb->vtb_size) {
+ count = vtb->vtb_size - at;
+ } else {
+ if (vtb->vtb_type == VTB_FRAMEBUFFER) {
+ bcopy_io(sc_vtb_pointer(vtb, at),
+ sc_vtb_pointer(vtb, at + count),
+ (vtb->vtb_size - at - count)*sizeof(u_int16_t));
+ } else {
+ bcopy((void *)sc_vtb_pointer(vtb, at),
+ (void *)sc_vtb_pointer(vtb, at + count),
+ (vtb->vtb_size - at - count)*sizeof(u_int16_t));
+ }
+ }
+ if (vtb->vtb_type == VTB_FRAMEBUFFER)
+ fillw_io(attr | c, sc_vtb_pointer(vtb, at), count);
+ else
+ fillw(attr | c, (void *)sc_vtb_pointer(vtb, at), count);
+}
+
+#endif /* NSC */
diff --git a/sys/dev/syscons/snake/snake_saver.c b/sys/dev/syscons/snake/snake_saver.c
index ef64741..51e1746 100644
--- a/sys/dev/syscons/snake/snake_saver.c
+++ b/sys/dev/syscons/snake/snake_saver.c
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: snake_saver.c,v 1.22 1999/01/17 14:25:19 yokota Exp $
+ * $Id: snake_saver.c,v 1.23 1999/02/05 12:40:15 des Exp $
*/
#include <sys/param.h>
@@ -34,16 +34,18 @@
#include <sys/malloc.h>
#include <sys/kernel.h>
#include <sys/sysctl.h>
+#include <sys/consio.h>
+#include <sys/fbio.h>
-#include <machine/md_var.h>
#include <machine/pc/display.h>
-#include <saver.h>
+#include <dev/fb/fbreg.h>
+#include <dev/fb/splashreg.h>
+#include <dev/syscons/syscons.h>
static char *message;
-static u_char **messagep;
+static int *messagep;
static int messagelen;
-static u_short *window;
static int blanked;
static int
@@ -51,36 +53,50 @@ snake_saver(video_adapter_t *adp, int blank)
{
static int dirx, diry;
int f;
- scr_stat *scp = cur_console;
+ sc_softc_t *sc;
+ scr_stat *scp;
/* XXX hack for minimal changes. */
#define save message
#define savs messagep
+ sc = sc_find_softc(adp, NULL);
+ if (sc == NULL)
+ return EAGAIN;
+ scp = sc->cur_scp;
+
if (blank) {
if (adp->va_info.vi_flags & V_INFO_GRAPHICS)
return EAGAIN;
if (blanked <= 0) {
- window = (u_short *)adp->va_window;
- fillw(((FG_LIGHTGREY|BG_BLACK)<<8) | scr_map[0x20],
- window, scp->xsize * scp->ysize);
+#ifdef PC98
+ if (epson_machine_id == 0x20) {
+ outb(0x43f, 0x42);
+ outb(0x0c17, inb(0xc17) & ~0x08);
+ outb(0x43f, 0x40);
+ }
+#endif /* PC98 */
+ sc_vtb_clear(&scp->scr, sc->scr_map[0x20],
+ (FG_LIGHTGREY | BG_BLACK) << 8);
+ (*vidsw[adp->va_index]->set_hw_cursor)(adp, -1, -1);
set_border(scp, 0);
dirx = (scp->xpos ? 1 : -1);
diry = (scp->ypos ?
scp->xsize : -scp->xsize);
for (f=0; f< messagelen; f++)
- savs[f] = (u_char *)window + 2 *
- (scp->xpos+scp->ypos*scp->xsize);
- *(savs[0]) = scr_map[*save];
+ savs[f] = scp->xpos + scp->ypos*scp->xsize;
+ sc_vtb_putc(&scp->scr, savs[0], sc->scr_map[*save],
+ (FG_LIGHTGREY | BG_BLACK) << 8);
blanked = 1;
}
if (blanked++ < 4)
return 0;
blanked = 1;
- *(savs[messagelen-1]) = scr_map[0x20];
+ sc_vtb_putc(&scp->scr, savs[messagelen - 1], sc->scr_map[0x20],
+ (FG_LIGHTGREY | BG_BLACK) << 8);
for (f=messagelen-1; f > 0; f--)
savs[f] = savs[f-1];
- f = (savs[0] - (u_char *)window) / 2;
+ f = savs[0];
if ((f % scp->xsize) == 0 ||
(f % scp->xsize) == scp->xsize - 1 ||
(random() % 50) == 0)
@@ -89,11 +105,19 @@ snake_saver(video_adapter_t *adp, int blank)
(f / scp->xsize) == scp->ysize - 1 ||
(random() % 20) == 0)
diry = -diry;
- savs[0] += 2*dirx + 2*diry;
+ savs[0] += dirx + diry;
for (f=messagelen-1; f>=0; f--)
- *(savs[f]) = scr_map[save[f]];
+ sc_vtb_putc(&scp->scr, savs[f], sc->scr_map[save[f]],
+ (FG_LIGHTGREY | BG_BLACK) << 8);
}
else {
+#ifdef PC98
+ if (epson_machine_id == 0x20) {
+ outb(0x43f, 0x42);
+ outb(0x0c17, inb(0xc17) | 0x08);
+ outb(0x43f, 0x40);
+ }
+#endif /* PC98 */
blanked = 0;
}
return 0;
diff --git a/sys/dev/syscons/star/star_saver.c b/sys/dev/syscons/star/star_saver.c
index aaa23fb..56408dc 100644
--- a/sys/dev/syscons/star/star_saver.c
+++ b/sys/dev/syscons/star/star_saver.c
@@ -25,22 +25,24 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: star_saver.c,v 1.19 1999/01/17 14:25:19 yokota Exp $
+ * $Id: star_saver.c,v 1.20 1999/02/05 12:40:16 des Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/module.h>
+#include <sys/consio.h>
+#include <sys/fbio.h>
-#include <machine/md_var.h>
#include <machine/pc/display.h>
-#include <saver.h>
+#include <dev/fb/fbreg.h>
+#include <dev/fb/splashreg.h>
+#include <dev/syscons/syscons.h>
#define NUM_STARS 50
-static u_short *window;
static int blanked;
/*
@@ -50,21 +52,39 @@ static int blanked;
static int
star_saver(video_adapter_t *adp, int blank)
{
- scr_stat *scp = cur_console;
+ sc_softc_t *sc;
+ scr_stat *scp;
int cell, i;
char pattern[] = {"...........++++*** "};
+#ifndef PC98
char colors[] = {FG_DARKGREY, FG_LIGHTGREY,
FG_WHITE, FG_LIGHTCYAN};
+#else
+ char colors[] = {FG_BLUE, FG_LIGHTGREY,
+ FG_LIGHTGREY, FG_CYAN};
+#endif /* PC98 */
static u_short stars[NUM_STARS][2];
+ sc = sc_find_softc(adp, NULL);
+ if (sc == NULL)
+ return EAGAIN;
+ scp = sc->cur_scp;
+
if (blank) {
if (adp->va_info.vi_flags & V_INFO_GRAPHICS)
return EAGAIN;
if (!blanked) {
- window = (u_short *)adp->va_window;
+#ifdef PC98
+ if (epson_machine_id == 0x20) {
+ outb(0x43f, 0x42);
+ outb(0x0c17, inb(0xc17) & ~0x08);
+ outb(0x43f, 0x40);
+ }
+#endif /* PC98 */
/* clear the screen and set the border color */
- fillw(((FG_LIGHTGREY|BG_BLACK) << 8) | scr_map[0x20],
- window, scp->xsize * scp->ysize);
+ sc_vtb_clear(&scp->scr, sc->scr_map[0x20],
+ (FG_LIGHTGREY | BG_BLACK) << 8);
+ (*vidsw[adp->va_index]->set_hw_cursor)(adp, -1, -1);
set_border(scp, 0);
blanked = TRUE;
for(i=0; i<NUM_STARS; i++) {
@@ -74,15 +94,22 @@ star_saver(video_adapter_t *adp, int blank)
}
}
cell = random() % NUM_STARS;
- *((u_short*)(window + stars[cell][0])) =
- scr_map[pattern[stars[cell][1]]] |
- colors[random()%sizeof(colors)] << 8;
+ sc_vtb_putc(&scp->scr, stars[cell][0],
+ sc->scr_map[pattern[stars[cell][1]]],
+ colors[random()%sizeof(colors)] << 8);
if ((stars[cell][1]+=(random()%4)) >= sizeof(pattern)-1) {
stars[cell][0] = random() % (scp->xsize*scp->ysize);
stars[cell][1] = 0;
}
}
else {
+#ifdef PC98
+ if (epson_machine_id == 0x20) {
+ outb(0x43f, 0x42);
+ outb(0x0c17, inb(0xc17) | 0x08);
+ outb(0x43f, 0x40);
+ }
+#endif /* PC98 */
blanked = FALSE;
}
return 0;
diff --git a/sys/dev/syscons/syscons.c b/sys/dev/syscons/syscons.c
index df527fc..937dcbc 100644
--- a/sys/dev/syscons/syscons.c
+++ b/sys/dev/syscons/syscons.c
@@ -30,15 +30,12 @@
#include "sc.h"
#include "splash.h"
-#ifdef __i386__
-#include "apm.h"
-#endif
+#include "opt_syscons.h"
#include "opt_ddb.h"
#include "opt_devfs.h"
#ifdef __i386__
-#include "opt_vesa.h"
+#include "apm.h"
#endif
-#include "opt_syscons.h"
#if NSC > 0
#include <sys/param.h>
@@ -54,308 +51,158 @@
#include <sys/devfsext.h>
#endif
-#include <machine/bootinfo.h>
#include <machine/clock.h>
#include <machine/cons.h>
#include <machine/console.h>
-#include <machine/mouse.h>
-#include <machine/md_var.h>
#include <machine/psl.h>
-#include <machine/frame.h>
#include <machine/pc/display.h>
#ifdef __i386__
-#include <machine/pc/vesa.h>
#include <machine/apm_bios.h>
+#include <machine/frame.h>
#include <machine/random.h>
#endif
-#include <vm/vm.h>
-#include <vm/vm_param.h>
-#include <vm/pmap.h>
-
#include <dev/kbd/kbdreg.h>
#include <dev/fb/fbreg.h>
-#include <dev/fb/vgareg.h>
#include <dev/fb/splashreg.h>
#include <dev/syscons/syscons.h>
-#ifndef __i386__
-#include <isa/isareg.h>
-#else
-#include <i386/isa/isa.h>
-#include <i386/isa/isa_device.h>
-#include <i386/isa/timerreg.h>
-#endif
-
-#if !defined(MAXCONS)
-#define MAXCONS 16
-#endif
-
-#if !defined(SC_MAX_HISTORY_SIZE)
-#define SC_MAX_HISTORY_SIZE (1000 * MAXCONS)
-#endif
-
-#if !defined(SC_HISTORY_SIZE)
-#define SC_HISTORY_SIZE (ROW * 4)
-#endif
-
-#if (SC_HISTORY_SIZE * MAXCONS) > SC_MAX_HISTORY_SIZE
-#undef SC_MAX_HISTORY_SIZE
-#define SC_MAX_HISTORY_SIZE (SC_HISTORY_SIZE * MAXCONS)
-#endif
-
-#if !defined(SC_MOUSE_CHAR)
-#define SC_MOUSE_CHAR (0xd0)
-#endif
-
#define COLD 0
#define WARM 1
#define DEFAULT_BLANKTIME (5*60) /* 5 minutes */
#define MAX_BLANKTIME (7*24*60*60) /* 7 days!? */
-/* for backward compatibility */
-#define OLD_CONS_MOUSECTL _IOWR('c', 10, old_mouse_info_t)
-
-typedef struct old_mouse_data {
- int x;
- int y;
- int buttons;
-} old_mouse_data_t;
-
-typedef struct old_mouse_info {
- int operation;
- union {
- struct old_mouse_data data;
- struct mouse_mode mode;
- } u;
-} old_mouse_info_t;
+#define KEYCODE_BS 0x0e /* "<-- Backspace" key, XXX */
static default_attr user_default = {
- (FG_LIGHTGREY | BG_BLACK) << 8,
- (FG_BLACK | BG_LIGHTGREY) << 8
+ SC_NORM_ATTR << 8,
+ SC_NORM_REV_ATTR << 8,
};
static default_attr kernel_default = {
- (FG_WHITE | BG_BLACK) << 8,
- (FG_BLACK | BG_LIGHTGREY) << 8
+ SC_KERNEL_CONS_ATTR << 8,
+ SC_KERNEL_CONS_REV_ATTR << 8,
};
-static scr_stat main_console;
-static scr_stat *console[MAXCONS];
+static int sc_console_unit = -1;
+static scr_stat *sc_console;
#ifdef DEVFS
-static void *sc_devfs_token[MAXCONS];
static void *sc_mouse_devfs_token;
static void *sc_console_devfs_token;
#endif
- scr_stat *cur_console;
-static scr_stat *new_scp, *old_scp;
static term_stat kernel_console;
static default_attr *current_default;
-static int sc_flags;
+
static char init_done = COLD;
-static u_short sc_buffer[ROW*COL];
static char shutdown_in_progress = FALSE;
-static char font_loading_in_progress = FALSE;
-static char switch_in_progress = FALSE;
-static char write_in_progress = FALSE;
-static char blink_in_progress = FALSE;
-static int blinkrate = 0;
-static int adapter = -1;
-static int keyboard = -1;
-static keyboard_t *kbd;
-static int delayed_next_scr = FALSE;
-static long scrn_blank_time = 0; /* screen saver timeout value */
-static int scrn_blanked = FALSE; /* screen saver active flag */
-static long scrn_time_stamp;
+static char sc_malloc = FALSE;
+
static int saver_mode = CONS_LKM_SAVER; /* LKM/user saver */
static int run_scrn_saver = FALSE; /* should run the saver? */
-static int scrn_idle = FALSE; /* about to run the saver */
-#if NSPLASH > 0
-static int scrn_saver_failed;
-#endif
- u_char scr_map[256];
- u_char scr_rmap[256];
-static int initial_video_mode; /* initial video mode # */
- int fonts_loaded = 0
-#ifdef STD8X16FONT
- | FONT_16
-#endif
- ;
+static long scrn_blank_time = 0; /* screen saver timeout value */
+static int scrn_blanked; /* # of blanked screen */
+static int sticky_splash = FALSE;
- u_char font_8[256*8];
- u_char font_14[256*14];
-#ifdef STD8X16FONT
-extern
+static void none_saver(sc_softc_t *sc, int blank) { }
+static void (*current_saver)(sc_softc_t *, int) = none_saver;
+
+#if !defined(SC_NO_FONT_LOADING) && defined(SC_DFLT_FONT)
+#include "font.h"
#endif
- u_char font_16[256*16];
- u_char palette[256*3];
-static u_char *cut_buffer;
-static int cut_buffer_size;
-static int mouse_level; /* sysmouse protocol level */
-static mousestatus_t mouse_status = { 0, 0, 0, 0, 0, 0 };
-static u_short mouse_and_mask[16] = {
- 0xc000, 0xe000, 0xf000, 0xf800,
- 0xfc00, 0xfe00, 0xff00, 0xff80,
- 0xfe00, 0x1e00, 0x1f00, 0x0f00,
- 0x0f00, 0x0000, 0x0000, 0x0000
- };
-static u_short mouse_or_mask[16] = {
- 0x0000, 0x4000, 0x6000, 0x7000,
- 0x7800, 0x7c00, 0x7e00, 0x6800,
- 0x0c00, 0x0c00, 0x0600, 0x0600,
- 0x0000, 0x0000, 0x0000, 0x0000
- };
-
- 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;
+
d_ioctl_t *sc_user_ioctl;
-static int sticky_splash = FALSE;
-static struct {
- u_int8_t cursor_start;
- u_int8_t cursor_end;
- u_int8_t shift_state;
- } bios_value;
-
-/* OS specific stuff */
-#ifdef not_yet_done
-#define VIRTUAL_TTY(x) (sccons[x] = ttymalloc(sccons[x]))
-struct CONSOLE_TTY (sccons[MAXCONS] = ttymalloc(sccons[MAXCONS]))
-struct MOUSE_TTY (sccons[MAXCONS+1] = ttymalloc(sccons[MAXCONS+1]))
-struct tty *sccons[MAXCONS+2];
-#else
-#define VIRTUAL_TTY(x) &sccons[x]
-#define CONSOLE_TTY &sccons[MAXCONS]
-#define MOUSE_TTY &sccons[MAXCONS+1]
-static struct tty sccons[MAXCONS+2];
-#endif
+static bios_values_t bios_value;
+
+static struct tty sccons[2];
#define SC_MOUSE 128
-#define SC_CONSOLE 255
-static const int nsccons = MAXCONS+2;
-
-#define WRAPHIST(scp, pointer, offset) \
- ((scp)->history + ((((pointer) - (scp)->history) + (scp)->history_size \
- + (offset)) % (scp)->history_size))
-#define ISSIGVALID(sig) ((sig) > 0 && (sig) < NSIG)
-
-/* some useful macros */
-#define kbd_read_char(kbd, wait) \
- (*kbdsw[(kbd)->kb_index]->read_char)((kbd), (wait))
-#define kbd_check_char(kbd) \
- (*kbdsw[(kbd)->kb_index]->check_char)((kbd))
-#define kbd_enable(kbd) \
- (*kbdsw[(kbd)->kb_index]->enable)((kbd))
-#define kbd_disable(kbd) \
- (*kbdsw[(kbd)->kb_index]->disable)((kbd))
-#define kbd_lock(kbd, lockf) \
- (*kbdsw[(kbd)->kb_index]->lock)((kbd), (lockf))
-#define kbd_ioctl(kbd, cmd, arg) \
- (((kbd) == NULL) ? \
- ENODEV : (*kbdsw[(kbd)->kb_index]->ioctl)((kbd), (cmd), (arg)))
-#define kbd_clear_state(kbd) \
- (*kbdsw[(kbd)->kb_index]->clear_state)((kbd))
-#define kbd_get_fkeystr(kbd, fkey, len) \
- (*kbdsw[(kbd)->kb_index]->get_fkeystr)((kbd), (fkey), (len))
-#define kbd_poll(kbd, on) \
- (*kbdsw[(kbd)->kb_index]->poll)((kbd), (on))
+#define SC_CONSOLECTL 255
+
+#define VIRTUAL_TTY(sc, x) (&((sc)->tty[(x) - (sc)->first_vty]))
+#define CONSOLE_TTY (&sccons[0])
+#define MOUSE_TTY (&sccons[1])
+
+#define debugger FALSE
+
+#ifdef __i386__
+#ifdef DDB
+extern int in_Debugger;
+#undef debugger
+#define debugger in_Debugger
+#endif /* DDB */
+#endif /* __i386__ */
/* prototypes */
-static kbd_callback_func_t sckbdevent;
-static int scparam(struct tty *tp, struct termios *t);
static int scvidprobe(int unit, int flags, int cons);
static int sckbdprobe(int unit, int flags, int cons);
+static void scmeminit(void *arg);
+static int scdevtounit(dev_t dev);
+static kbd_callback_func_t sckbdevent;
+static int scparam(struct tty *tp, struct termios *t);
static void scstart(struct tty *tp);
static void scmousestart(struct tty *tp);
-static void scinit(void);
+static void scinit(int unit, int flags);
+static void scterm(int unit, int flags);
static void scshutdown(int howto, void *arg);
-static u_int scgetc(keyboard_t *kbd, u_int flags);
+static u_int scgetc(sc_softc_t *sc, u_int flags);
#define SCGETC_CN 1
#define SCGETC_NONBLOCK 2
static int sccngetch(int flags);
static void sccnupdate(scr_stat *scp);
-static scr_stat *alloc_scp(void);
-static void init_scp(scr_stat *scp);
-static void get_bios_values(void);
-static void sc_bcopy(scr_stat *scp, u_short *p, int from, int to, int mark);
-static int get_scr_num(void);
+static scr_stat *alloc_scp(sc_softc_t *sc, int vty);
+static void init_scp(sc_softc_t *sc, int vty, scr_stat *scp);
static timeout_t scrn_timer;
+static int and_region(int *s1, int *e1, int s2, int e2);
static void scrn_update(scr_stat *scp, int show_cursor);
+
#if NSPLASH > 0
-static int scsplash_callback(int);
-static void scsplash_saver(int show);
-static int add_scrn_saver(void (*this_saver)(int));
-static int remove_scrn_saver(void (*this_saver)(int));
+static int scsplash_callback(int event, void *arg);
+static void scsplash_saver(sc_softc_t *sc, int show);
+static int add_scrn_saver(void (*this_saver)(sc_softc_t *, int));
+static int remove_scrn_saver(void (*this_saver)(sc_softc_t *, int));
static int set_scrn_saver_mode(scr_stat *scp, int mode, u_char *pal, int border);
static int restore_scrn_saver_mode(scr_stat *scp, int changemode);
-static void stop_scrn_saver(void (*saver)(int));
-static int wait_scrn_saver_stop(void);
+static void stop_scrn_saver(sc_softc_t *sc, void (*saver)(sc_softc_t *, int));
+static int wait_scrn_saver_stop(sc_softc_t *sc);
#define scsplash_stick(stick) (sticky_splash = (stick))
#else /* !NSPLASH */
-#define stop_scrn_saver(saver)
-#define wait_scrn_saver_stop() 0
#define scsplash_stick(stick)
#endif /* NSPLASH */
-static int switch_scr(scr_stat *scp, u_int next_scr);
-static void exchange_scr(void);
+
+static int switch_scr(sc_softc_t *sc, u_int next_scr);
+static int do_switch_scr(sc_softc_t *sc, int s);
+static int vt_proc_alive(scr_stat *scp);
+static int signal_vt_rel(scr_stat *scp);
+static int signal_vt_acq(scr_stat *scp);
+static void exchange_scr(sc_softc_t *sc);
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 draw_cursor_image(scr_stat *scp);
+static void remove_cursor_image(scr_stat *scp);
+static void update_cursor_image(scr_stat *scp);
static void move_crsr(scr_stat *scp, int x, int y);
-static void history_to_screen(scr_stat *scp);
-static int history_up_line(scr_stat *scp);
-static int history_down_line(scr_stat *scp);
static int mask2attr(struct term_stat *term);
static int save_kbd_state(scr_stat *scp);
-static int update_kbd_state(int state, int mask);
-static int update_kbd_leds(int which);
-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);
-static int skip_spc_left(scr_stat *scp, u_short *p);
-static void mouse_cut(scr_stat *scp);
-static void mouse_cut_start(scr_stat *scp);
-static void mouse_cut_end(scr_stat *scp);
-static void mouse_cut_word(scr_stat *scp);
-static void mouse_cut_line(scr_stat *scp);
-static void mouse_cut_extend(scr_stat *scp);
-static void mouse_paste(scr_stat *scp);
-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 int update_kbd_state(scr_stat *scp, int state, int mask);
+static int update_kbd_leds(scr_stat *scp, int which);
static void do_bell(scr_stat *scp, int pitch, int duration);
static timeout_t blink_screen;
#define CDEV_MAJOR 12
-#ifdef __i386__
-
static cn_probe_t sccnprobe;
static cn_init_t sccninit;
static cn_getc_t sccngetc;
static cn_checkc_t sccncheckc;
static cn_putc_t sccnputc;
+static cn_term_t sccnterm;
-CONS_DRIVER(sc, sccnprobe, sccninit, sccngetc, sccncheckc, sccnputc);
-
-#else /* !__i386__ */
-
-static cn_getc_t sccngetc;
-static cn_checkc_t sccncheckc;
-static cn_putc_t sccnputc;
-
-struct consdev sc_cons = {
- NULL, NULL, sccngetc, sccncheckc, sccnputc,
- NULL, 0, CN_NORMAL,
-};
+#if __alpha__
+void sccnattach(void);
+#endif
-#endif /* __i386__ */
+CONS_DRIVER(sc, sccnprobe, sccninit, sccnterm, sccngetc, sccncheckc, sccnputc);
static d_open_t scopen;
static d_close_t scclose;
@@ -386,118 +233,6 @@ static struct cdevsw sc_cdevsw = {
/* bmaj */ -1
};
-#ifdef __i386__
-
-#define fillw_io(p, b, c) fillw((p), (void *)(b), (c))
-
-#endif
-
-#ifdef __alpha__
-
-static void
-fillw(int pat, void *base, size_t cnt)
-{
- u_short *sp = base;
- while (cnt--)
- *sp++ = pat;
-}
-
-static void
-fillw_io(int pat, u_int32_t base, size_t cnt)
-{
- while (cnt--) {
- writew(base, pat);
- base += 2;
- }
-}
-
-#endif
-
-static void
-draw_cursor_image(scr_stat *scp)
-{
- u_short cursor_image;
- vm_offset_t ptr;
- u_short prev_image;
-
- if (ISPIXELSC(scp)) {
- sc_bcopy(scp, scp->scr_buf, scp->cursor_pos - scp->scr_buf,
- scp->cursor_pos - scp->scr_buf, 1);
- return;
- }
-
- ptr = scp->adp->va_window + 2*(scp->cursor_pos - scp->scr_buf);
-
- /* do we have a destructive cursor ? */
- if (sc_flags & CHAR_CURSOR) {
- prev_image = scp->cursor_saveunder;
- cursor_image = readw(ptr) & 0x00ff;
- if (cursor_image == DEAD_CHAR)
- cursor_image = prev_image & 0x00ff;
- cursor_image |= *(scp->cursor_pos) & 0xff00;
- scp->cursor_saveunder = cursor_image;
- /* update the cursor bitmap if the char under the cursor has changed */
- if (prev_image != cursor_image)
- set_destructive_cursor(scp);
- /* modify cursor_image */
- if (!(sc_flags & BLINK_CURSOR)||((sc_flags & BLINK_CURSOR)&&(blinkrate & 4))){
- /*
- * When the mouse pointer is at the same position as the cursor,
- * the cursor bitmap needs to be updated even if the char under
- * the cursor hasn't changed, because the mouse pionter may
- * have moved by a few dots within the cursor cel.
- */
- if ((prev_image == cursor_image)
- && (cursor_image != *(scp->cursor_pos)))
- set_destructive_cursor(scp);
- cursor_image &= 0xff00;
- cursor_image |= DEAD_CHAR;
- }
- } else {
- cursor_image = (readw(ptr) & 0x00ff) | (*(scp->cursor_pos) & 0xff00);
- scp->cursor_saveunder = cursor_image;
- if (!(sc_flags & BLINK_CURSOR)||((sc_flags & BLINK_CURSOR)&&(blinkrate & 4))){
- if ((cursor_image & 0x7000) == 0x7000) {
- cursor_image &= 0x8fff;
- if(!(cursor_image & 0x0700))
- cursor_image |= 0x0700;
- } else {
- cursor_image |= 0x7000;
- if ((cursor_image & 0x0700) == 0x0700)
- cursor_image &= 0xf0ff;
- }
- }
- }
- writew(ptr, cursor_image);
-}
-
-static void
-remove_cursor_image(scr_stat *scp)
-{
- if (ISPIXELSC(scp))
- sc_bcopy(scp, scp->scr_buf, scp->cursor_oldpos - scp->scr_buf,
- scp->cursor_oldpos - scp->scr_buf, 0);
- else
- writew(scp->adp->va_window + 2*(scp->cursor_oldpos - scp->scr_buf),
- scp->cursor_saveunder);
-}
-
-static void
-move_crsr(scr_stat *scp, int x, int y)
-{
- if (x < 0)
- x = 0;
- if (y < 0)
- y = 0;
- if (x >= scp->xsize)
- x = scp->xsize-1;
- if (y >= scp->ysize)
- y = scp->ysize-1;
- scp->xpos = x;
- scp->ypos = y;
- scp->cursor_pos = scp->scr_buf + scp->ypos * scp->xsize + scp->xpos;
-}
-
int
sc_probe_unit(int unit, int flags)
{
@@ -514,8 +249,6 @@ sc_probe_unit(int unit, int flags)
static int
scvidprobe(int unit, int flags, int cons)
{
- video_adapter_t *adp;
-
/*
* Access the video adapter driver through the back door!
* Video adapter drivers need to be configured before syscons.
@@ -525,17 +258,7 @@ scvidprobe(int unit, int flags, int cons)
*/
vid_configure(cons ? VIO_PROBE_ONLY : 0);
- /* allocate a frame buffer */
- if (adapter < 0) {
- adapter = vid_allocate("*", -1, (void *)&adapter);
- if (adapter < 0)
- return FALSE;
- }
- adp = vid_get_adapter(adapter); /* shouldn't fail */
-
- initial_video_mode = adp->va_initial_mode;
-
- return TRUE;
+ return (vid_find_adapter("*", unit) >= 0);
}
/* probe the keyboard, return TRUE if found */
@@ -545,169 +268,241 @@ sckbdprobe(int unit, int flags, int cons)
/* access the keyboard driver through the backdoor! */
kbd_configure(cons ? KB_CONF_PROBE_ONLY : 0);
- /* allocate a keyboard and register the keyboard event handler */
- if (keyboard < 0) {
- keyboard = kbd_allocate("*", -1, (void *)&keyboard, sckbdevent, NULL);
- if (keyboard < 0)
- return FALSE;
- }
- kbd = kbd_get_keyboard(keyboard); /* shouldn't fail */
-
- return TRUE;
-}
+ return (kbd_find_keyboard("*", unit) >= 0);
+}
+
+static char
+*adapter_name(video_adapter_t *adp)
+{
+ static struct {
+ int type;
+ char *name[2];
+ } names[] = {
+ { KD_MONO, { "MDA", "MDA" } },
+ { KD_HERCULES, { "Hercules", "Hercules" } },
+ { KD_CGA, { "CGA", "CGA" } },
+ { KD_EGA, { "EGA", "EGA (mono)" } },
+ { KD_VGA, { "VGA", "VGA (mono)" } },
+ { KD_PC98, { "PC-98x1", "PC-98x1" } },
+ { KD_TGA, { "TGA", "TGA" } },
+ { -1, { "Unknown", "Unknown" } },
+ };
+ int i;
-#if NAPM > 0
-static int
-scresume(void *dummy)
-{
- if (kbd != NULL)
- kbd_clear_state(kbd);
- return 0;
+ for (i = 0; names[i].type != -1; ++i)
+ if (names[i].type == adp->va_type)
+ break;
+ return names[i].name[(adp->va_flags & V_ADP_COLOR) ? 0 : 1];
}
-#endif
int
sc_attach_unit(int unit, int flags)
{
+ sc_softc_t *sc;
scr_stat *scp;
-#if defined(VESA)
+#ifdef SC_PIXEL_MODE
video_info_t info;
#endif
#ifdef DEVFS
int vc;
#endif
- scinit();
- scp = console[0];
- sc_flags = flags;
- if (!ISFONTAVAIL(scp->adp->va_flags))
- sc_flags &= ~CHAR_CURSOR;
-
- /* copy temporary buffer to final buffer */
- scp->scr_buf = NULL;
- sc_alloc_scr_buffer(scp, FALSE, FALSE);
- bcopy(sc_buffer, scp->scr_buf, scp->xsize*scp->ysize*sizeof(u_short));
-
- /* cut buffer is available only when the mouse pointer is used */
- if (ISMOUSEAVAIL(scp->adp->va_flags))
- sc_alloc_cut_buffer(scp, FALSE);
-
- /* initialize history buffer & pointers */
- sc_alloc_history_buffer(scp, sc_history_size, 0, FALSE);
-
-#if defined(VESA)
- if ((sc_flags & VESA800X600)
- && ((*vidsw[scp->ad]->get_info)(scp->adp, M_VESA_800x600, &info) == 0)) {
+ scmeminit(NULL); /* XXX */
+
+ flags &= ~SC_KERNEL_CONSOLE;
+ if (sc_console_unit == unit)
+ flags |= SC_KERNEL_CONSOLE;
+ scinit(unit, flags);
+ sc = sc_get_softc(unit, flags & SC_KERNEL_CONSOLE);
+ sc->config = flags;
+ scp = sc->console[0];
+ if (sc_console == NULL) /* sc_console_unit < 0 */
+ sc_console = scp;
+
+#ifdef SC_PIXEL_MODE
+ if ((sc->config & SC_VESA800X600)
+ && ((*vidsw[sc->adapter]->get_info)(sc->adp, M_VESA_800x600, &info) == 0)) {
#if NSPLASH > 0
- splash_term(scp->adp);
+ if (sc->flags & SC_SPLASH_SCRN)
+ splash_term(sc->adp);
#endif
sc_set_graphics_mode(scp, NULL, M_VESA_800x600);
sc_set_pixel_mode(scp, NULL, COL, ROW, 16);
- initial_video_mode = M_VESA_800x600;
+ sc->initial_mode = M_VESA_800x600;
#if NSPLASH > 0
/* put up the splash again! */
- splash_init(scp->adp, scsplash_callback);
+ if (sc->flags & SC_SPLASH_SCRN)
+ splash_init(sc->adp, scsplash_callback, sc);
#endif
}
-#endif /* VESA */
+#endif /* SC_PIXEL_MODE */
- /* initialize cursor stuff */
+ /* initialize cursor */
if (!ISGRAPHSC(scp))
- draw_cursor_image(scp);
+ update_cursor_image(scp);
/* get screen update going */
- scrn_timer((void *)TRUE);
+ scrn_timer(sc);
/* set up the keyboard */
- kbd_ioctl(kbd, KDSKBMODE, (caddr_t)&scp->kbd_mode);
- update_kbd_state(scp->status, LOCK_MASK);
+ kbd_ioctl(sc->kbd, KDSKBMODE, (caddr_t)&scp->kbd_mode);
+ update_kbd_state(scp, scp->status, LOCK_MASK);
+ printf("sc%d: %s <%d virtual consoles, flags=0x%x>\n",
+ unit, adapter_name(sc->adp), sc->vtys, sc->config);
if (bootverbose) {
printf("sc%d:", unit);
- if (adapter >= 0)
- printf(" fb%d", adapter);
- if (keyboard >= 0)
- printf(" kbd%d", keyboard);
+ if (sc->adapter >= 0)
+ printf(" fb%d", sc->adapter);
+ if (sc->keyboard >= 0)
+ printf(" kbd%d", sc->keyboard);
printf("\n");
}
- printf("sc%d: ", unit);
- switch(scp->adp->va_type) {
- case KD_VGA:
- printf("VGA %s", (scp->adp->va_flags & V_ADP_COLOR) ? "color" : "mono");
- break;
- case KD_EGA:
- printf("EGA %s", (scp->adp->va_flags & V_ADP_COLOR) ? "color" : "mono");
- break;
- case KD_CGA:
- printf("CGA");
- break;
- case KD_MONO:
- case KD_HERCULES:
- default:
- printf("MDA/Hercules");
- break;
- }
- printf(" <%d virtual consoles, flags=0x%x>\n", MAXCONS, sc_flags);
-
-#if NAPM > 0
- scp->r_hook.ah_fun = scresume;
- scp->r_hook.ah_arg = NULL;
- scp->r_hook.ah_name = "system keyboard";
- scp->r_hook.ah_order = APM_MID_ORDER;
- apm_hook_establish(APM_HOOK_RESUME , &scp->r_hook);
-#endif
- at_shutdown(scshutdown, NULL, SHUTDOWN_PRE_SYNC);
+ /* register a shutdown callback for the kernel console */
+ if (sc_console_unit == unit)
+ at_shutdown(scshutdown, (void *)unit, SHUTDOWN_PRE_SYNC);
- cdevsw_add(&sc_cdevsw);
+ /*
+ * syscons's cdevsw must be registered from here. As syscons and
+ * pcvt share the same major number, their cdevsw cannot be
+ * registered at module loading/initialization time or by SYSINIT.
+ */
+ cdevsw_add(&sc_cdevsw); /* XXX do this just once... */
#ifdef DEVFS
- for (vc = 0; vc < MAXCONS; vc++)
- sc_devfs_token[vc] = devfs_add_devswf(&sc_cdevsw, vc, DV_CHR,
- UID_ROOT, GID_WHEEL, 0600, "ttyv%r", vc);
- 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(&sc_cdevsw, SC_CONSOLE, DV_CHR,
- UID_ROOT, GID_WHEEL, 0600, "consolectl");
+ for (vc = sc->first_vty; vc < sc->first_vty + sc->vtys; vc++)
+ sc->devfs_token[vc] = devfs_add_devswf(&sc_cdevsw, vc,
+ DV_CHR, UID_ROOT, GID_WHEEL,
+ 0600, "ttyv%r", vc);
+ if (scp == sc_console) {
+#ifndef SC_NO_SYSMOUSE
+ sc_mouse_devfs_token = devfs_add_devswf(&sc_cdevsw, SC_MOUSE,
+ DV_CHR, UID_ROOT, GID_WHEEL,
+ 0600, "sysmouse");
+#endif /* SC_NO_SYSMOUSE */
+ sc_console_devfs_token = devfs_add_devswf(&sc_cdevsw, SC_CONSOLECTL,
+ DV_CHR, UID_ROOT, GID_WHEEL,
+ 0600, "consolectl");
+ }
+#endif /* DEVFS */
+
+ return 0;
+}
+
+static void
+scmeminit(void *arg)
+{
+ if (sc_malloc)
+ return;
+ sc_malloc = TRUE;
+
+ /*
+ * As soon as malloc() becomes functional, we had better allocate
+ * various buffers for the kernel console.
+ */
+
+ if (sc_console_unit < 0)
+ return;
+
+ /* copy the temporary buffer to the final buffer */
+ sc_alloc_scr_buffer(sc_console, FALSE, FALSE);
+
+#ifndef SC_NO_CUTPASTE
+ /* cut buffer is available only when the mouse pointer is used */
+ if (ISMOUSEAVAIL(sc_console->sc->adp->va_flags))
+ sc_alloc_cut_buffer(sc_console, FALSE);
#endif
+
+#ifndef SC_NO_HISTORY
+ /* initialize history buffer & pointers */
+ sc_alloc_history_buffer(sc_console, 0, FALSE);
+#endif
+}
+
+/* XXX */
+SYSINIT(sc_mem, SI_SUB_KMEM, SI_ORDER_ANY, scmeminit, NULL);
+
+int
+sc_resume_unit(int unit)
+{
+ /* XXX should be moved to the keyboard driver? */
+ sc_softc_t *sc;
+
+ sc = sc_get_softc(unit, (sc_console_unit == unit) ? SC_KERNEL_CONSOLE : 0);
+ if (sc->kbd != NULL)
+ kbd_clear_state(sc->kbd);
return 0;
}
struct tty
*scdevtotty(dev_t dev)
{
- int unit = minor(dev);
+ sc_softc_t *sc;
+ int vty = SC_VTY(dev);
+ int unit;
if (init_done == COLD)
- return(NULL);
- if (unit == SC_CONSOLE)
+ return NULL;
+
+ if (vty == SC_CONSOLECTL)
return CONSOLE_TTY;
- if (unit == SC_MOUSE)
+#ifndef SC_NO_SYSMOUSE
+ if (vty == SC_MOUSE)
return MOUSE_TTY;
- if (unit >= MAXCONS || unit < 0)
- return(NULL);
- return VIRTUAL_TTY(unit);
+#endif
+
+ unit = scdevtounit(dev);
+ sc = sc_get_softc(unit, (sc_console_unit == unit) ? SC_KERNEL_CONSOLE : 0);
+ if (sc == NULL)
+ return NULL;
+ return VIRTUAL_TTY(sc, vty);
+}
+
+static int
+scdevtounit(dev_t dev)
+{
+ int vty = SC_VTY(dev);
+
+ if (vty == SC_CONSOLECTL)
+ return ((sc_console != NULL) ? sc_console->sc->unit : -1);
+ else if (vty == SC_MOUSE)
+ return -1;
+ else if ((vty < 0) || (vty >= MAXCONS*sc_max_unit()))
+ return -1;
+ else
+ return vty/MAXCONS;
}
int
scopen(dev_t dev, int flag, int mode, struct proc *p)
{
struct tty *tp = scdevtotty(dev);
+ int unit = scdevtounit(dev);
+ sc_softc_t *sc;
keyarg_t key;
if (!tp)
return(ENXIO);
- tp->t_oproc = (minor(dev) == SC_MOUSE) ? scmousestart : scstart;
+ DPRINTF(5, ("scopen: dev:%d, unit:%d, vty:%d\n",
+ dev, unit, SC_VTY(dev)));
+
+ /* sc == NULL, if SC_VTY(dev) == SC_MOUSE */
+ sc = sc_get_softc(unit, (sc_console_unit == unit) ? SC_KERNEL_CONSOLE : 0);
+
+ tp->t_oproc = (SC_VTY(dev) == SC_MOUSE) ? scmousestart : scstart;
tp->t_param = scparam;
tp->t_dev = dev;
if (!(tp->t_state & TS_ISOPEN)) {
ttychars(tp);
/* Use the current setting of the <-- key as default VERASE. */
/* If the Delete key is preferable, an stty is necessary */
- key.keynum = 0x0e; /* how do we know this magic number... XXX */
- kbd_ioctl(kbd, GIO_KEYMAPENT, (caddr_t)&key);
- tp->t_cc[VERASE] = key.key.map[0];
+ if (sc != NULL) {
+ key.keynum = KEYCODE_BS;
+ kbd_ioctl(sc->kbd, GIO_KEYMAPENT, (caddr_t)&key);
+ tp->t_cc[VERASE] = key.key.map[0];
+ }
tp->t_iflag = TTYDEF_IFLAG;
tp->t_oflag = TTYDEF_OFLAG;
tp->t_cflag = TTYDEF_CFLAG;
@@ -715,20 +510,29 @@ scopen(dev_t dev, int flag, int mode, struct proc *p)
tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
scparam(tp, &tp->t_termios);
(*linesw[tp->t_line].l_modem)(tp, 1);
- if (minor(dev) == SC_MOUSE)
- mouse_level = 0; /* XXX */
+#ifndef SC_NO_SYSMOUSE
+ if (SC_VTY(dev) == SC_MOUSE)
+ sc_mouse_set_level(0); /* XXX */
+#endif
}
else
if (tp->t_state & TS_XCLUDE && suser(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;
- tp->t_winsize.ws_row = console[minor(dev)]->ysize;
+ if ((SC_VTY(dev) != SC_CONSOLECTL) && (SC_VTY(dev) != SC_MOUSE)) {
+ /* assert(sc != NULL) */
+ if (sc->console[SC_VTY(dev) - sc->first_vty] == NULL) {
+ sc->console[SC_VTY(dev) - sc->first_vty]
+ = alloc_scp(sc, SC_VTY(dev));
+ if (ISGRAPHSC(sc->console[SC_VTY(dev) - sc->first_vty]))
+ sc_set_pixel_mode(sc->console[SC_VTY(dev) - sc->first_vty],
+ NULL, COL, ROW, 16);
+ }
+ if (!tp->t_winsize.ws_col && !tp->t_winsize.ws_row) {
+ tp->t_winsize.ws_col
+ = sc->console[SC_VTY(dev) - sc->first_vty]->xsize;
+ tp->t_winsize.ws_row
+ = sc->console[SC_VTY(dev) - sc->first_vty]->ysize;
+ }
}
return ((*linesw[tp->t_line].l_open)(dev, tp));
}
@@ -738,13 +542,29 @@ scclose(dev_t dev, int flag, int mode, struct proc *p)
{
struct tty *tp = scdevtotty(dev);
struct scr_stat *scp;
+ int s;
if (!tp)
return(ENXIO);
- if (minor(dev) < MAXCONS) {
+ if ((SC_VTY(dev) != SC_CONSOLECTL) && (SC_VTY(dev) != SC_MOUSE)) {
scp = sc_get_scr_stat(tp->t_dev);
- if (scp->status & SWITCH_WAIT_ACQ)
- wakeup((caddr_t)&scp->smode);
+ /* were we in the middle of the VT switching process? */
+ DPRINTF(5, ("sc%d: scclose(), ", scp->sc->unit));
+ s = spltty();
+ if ((scp == scp->sc->cur_scp) && (scp->sc->unit == sc_console_unit))
+ cons_unavail = FALSE;
+ if (scp->status & SWITCH_WAIT_REL) {
+ /* assert(scp == scp->sc->cur_scp) */
+ DPRINTF(5, ("reset WAIT_REL, "));
+ scp->status &= ~SWITCH_WAIT_REL;
+ do_switch_scr(scp->sc, s);
+ }
+ if (scp->status & SWITCH_WAIT_ACQ) {
+ /* assert(scp == scp->sc->cur_scp) */
+ DPRINTF(5, ("reset WAIT_ACQ, "));
+ scp->status &= ~SWITCH_WAIT_ACQ;
+ scp->sc->switch_in_progress = 0;
+ }
#if not_yet_done
if (scp == &main_console) {
scp->pid = 0;
@@ -752,22 +572,25 @@ scclose(dev_t dev, int flag, int mode, struct proc *p)
scp->smode.mode = VT_AUTO;
}
else {
- free(scp->scr_buf, M_DEVBUF);
+ sc_vtb_destroy(&scp->vtb);
+ sc_vtb_destroy(&scp->scr);
if (scp->history != NULL) {
+ /* XXX not quite correct */
+ sc_vtb_destroy(scp->history);
free(scp->history, M_DEVBUF);
- if (scp->history_size / scp->xsize
- > imax(sc_history_size, scp->ysize))
- extra_history_size += scp->history_size / scp->xsize
- - imax(sc_history_size, scp->ysize);
}
free(scp, M_DEVBUF);
- console[minor(dev)] = NULL;
+ sc->console[SC_VTY(dev) - sc->first_vty] = NULL;
}
#else
scp->pid = 0;
scp->proc = NULL;
scp->smode.mode = VT_AUTO;
#endif
+ scp->kbd_mode = K_XLATE;
+ if (scp == scp->sc->cur_scp)
+ kbd_ioctl(scp->sc->kbd, KDSKBMODE, (caddr_t)&scp->kbd_mode);
+ DPRINTF(5, ("done.\n"));
}
spltty();
(*linesw[tp->t_line].l_close)(tp, flag);
@@ -800,19 +623,21 @@ scwrite(dev_t dev, struct uio *uio, int flag)
static int
sckbdevent(keyboard_t *thiskbd, int event, void *arg)
{
- static struct tty *cur_tty;
+ sc_softc_t *sc;
+ struct tty *cur_tty;
int c;
size_t len;
u_char *cp;
- /* assert(thiskbd == kbd) */
+ sc = (sc_softc_t *)arg;
+ /* assert(thiskbd == sc->kbd) */
switch (event) {
case KBDIO_KEYINPUT:
break;
case KBDIO_UNLOADING:
- kbd = NULL;
- kbd_release(thiskbd, (void *)&keyboard);
+ sc->kbd = NULL;
+ kbd_release(thiskbd, (void *)&sc->keyboard);
return 0;
default:
return EINVAL;
@@ -823,9 +648,10 @@ sckbdevent(keyboard_t *thiskbd, int event, void *arg)
* I don't think this is nessesary, and it doesn't fix
* the Xaccel-2.1 keyboard hang, but it can't hurt. XXX
*/
- while ((c = scgetc(thiskbd, SCGETC_NONBLOCK)) != NOKEY) {
+ while ((c = scgetc(sc, SCGETC_NONBLOCK)) != NOKEY) {
- cur_tty = VIRTUAL_TTY(get_scr_num());
+ cur_tty = VIRTUAL_TTY(sc, sc->cur_scp->index);
+ /* XXX */
if (!(cur_tty->t_state & TS_ISOPEN))
if (!((cur_tty = CONSOLE_TTY)->t_state & TS_ISOPEN))
continue;
@@ -853,10 +679,12 @@ sckbdevent(keyboard_t *thiskbd, int event, void *arg)
}
}
- if (cur_console->status & MOUSE_VISIBLE) {
- remove_mouse_image(cur_console);
- cur_console->status &= ~MOUSE_VISIBLE;
+#ifndef SC_NO_CUTPASTE
+ if (sc->cur_scp->status & MOUSE_VISIBLE) {
+ sc_remove_mouse_image(sc->cur_scp);
+ sc->cur_scp->status &= ~MOUSE_VISIBLE;
}
+#endif /* SC_NO_CUTPASTE */
return 0;
}
@@ -873,17 +701,16 @@ scparam(struct tty *tp, struct termios *t)
int
scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
{
- u_int delta_ehs;
int error;
int i;
struct tty *tp;
+ sc_softc_t *sc;
scr_stat *scp;
int s;
tp = scdevtotty(dev);
if (!tp)
return ENXIO;
- scp = sc_get_scr_stat(tp->t_dev);
/* If there is a user_ioctl function call that first */
if (sc_user_ioctl) {
@@ -896,6 +723,32 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
if (error != ENOIOCTL)
return error;
+#ifndef SC_NO_HISTORY
+ error = sc_hist_ioctl(tp, cmd, data, flag, p);
+ if (error != ENOIOCTL)
+ return error;
+#endif
+
+#ifndef SC_NO_SYSMOUSE
+ error = sc_mouse_ioctl(tp, cmd, data, flag, p);
+ if (error != ENOIOCTL)
+ return error;
+ if (SC_VTY(dev) == SC_MOUSE) {
+ error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
+ if (error != ENOIOCTL)
+ return error;
+ error = ttioctl(tp, cmd, data, flag);
+ if (error != ENOIOCTL)
+ return error;
+ return ENOTTY;
+ }
+#endif
+
+ scp = sc_get_scr_stat(tp->t_dev);
+ /* assert(scp != NULL) */
+ /* scp is sc_console, if SC_VTY(dev) == SC_CONSOLECTL. */
+ sc = scp->sc;
+
switch (cmd) { /* process console hardware related ioctl's */
case GIO_ATTR: /* get current attributes */
@@ -903,7 +756,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 ? */
- *(int *)data = (scp->adp->va_flags & V_ADP_COLOR) ? 1 : 0;
+ *(int *)data = (sc->adp->va_flags & V_ADP_COLOR) ? 1 : 0;
return 0;
case CONS_BLANKTIME: /* set screen saver timeout (0 = no saver) */
@@ -916,461 +769,44 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return 0;
case CONS_CURSORTYPE: /* set cursor type blink/noblink */
+ if (!ISGRAPHSC(sc->cur_scp))
+ remove_cursor_image(sc->cur_scp);
if ((*(int*)data) & 0x01)
- sc_flags |= BLINK_CURSOR;
+ sc->flags |= SC_BLINK_CURSOR;
else
- sc_flags &= ~BLINK_CURSOR;
+ sc->flags &= ~SC_BLINK_CURSOR;
if ((*(int*)data) & 0x02) {
- if (!ISFONTAVAIL(scp->adp->va_flags))
- return ENXIO;
- sc_flags |= CHAR_CURSOR;
+ sc->flags |= SC_CHAR_CURSOR;
} else
- sc_flags &= ~CHAR_CURSOR;
+ sc->flags &= ~SC_CHAR_CURSOR;
/*
* The cursor shape is global property; all virtual consoles
* are affected. Update the cursor in the current console...
*/
- if (!ISGRAPHSC(cur_console)) {
+ if (!ISGRAPHSC(sc->cur_scp)) {
s = spltty();
- remove_cursor_image(cur_console);
- if (sc_flags & CHAR_CURSOR)
- set_destructive_cursor(cur_console);
- draw_cursor_image(cur_console);
+ sc_set_cursor_image(sc->cur_scp);
+ draw_cursor_image(sc->cur_scp);
splx(s);
}
return 0;
case CONS_BELLTYPE: /* set bell type sound/visual */
if ((*(int *)data) & 0x01)
- sc_flags |= VISUAL_BELL;
+ sc->flags |= SC_VISUAL_BELL;
else
- sc_flags &= ~VISUAL_BELL;
+ sc->flags &= ~SC_VISUAL_BELL;
if ((*(int *)data) & 0x02)
- sc_flags |= QUIET_BELL;
- else
- sc_flags &= ~QUIET_BELL;
- return 0;
-
- case CONS_HISTORY: /* set history size */
- if (*(int *)data > 0) {
- int lines; /* buffer size to allocate */
- int lines0; /* current buffer size */
-
- 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))
- delta_ehs = lines0 - imax(sc_history_size, scp->ysize);
- else
- delta_ehs = 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(sc_history_size, scp->ysize))
- if (lines - imax(sc_history_size, scp->ysize) >
- extra_history_size + delta_ehs)
- return EINVAL;
- if (cur_console->status & BUFFER_SAVED)
- return EBUSY;
- sc_alloc_history_buffer(scp, lines, delta_ehs, TRUE);
- return 0;
- }
+ sc->flags |= SC_QUIET_BELL;
else
- return EINVAL;
-
- case CONS_MOUSECTL: /* control mouse arrow */
- case OLD_CONS_MOUSECTL:
- {
- /* MOUSE_BUTTON?DOWN -> MOUSE_MSC_BUTTON?UP */
- static int butmap[8] = {
- MOUSE_MSC_BUTTON1UP | MOUSE_MSC_BUTTON2UP | MOUSE_MSC_BUTTON3UP,
- MOUSE_MSC_BUTTON2UP | MOUSE_MSC_BUTTON3UP,
- MOUSE_MSC_BUTTON1UP | MOUSE_MSC_BUTTON3UP,
- MOUSE_MSC_BUTTON3UP,
- MOUSE_MSC_BUTTON1UP | MOUSE_MSC_BUTTON2UP,
- MOUSE_MSC_BUTTON2UP,
- MOUSE_MSC_BUTTON1UP,
- 0,
- };
- mouse_info_t *mouse = (mouse_info_t*)data;
- mouse_info_t buf;
-
- /* FIXME: */
- if (!ISMOUSEAVAIL(scp->adp->va_flags))
- return ENODEV;
-
- if (cmd == OLD_CONS_MOUSECTL) {
- static u_char swapb[] = { 0, 4, 2, 6, 1, 5, 3, 7 };
- old_mouse_info_t *old_mouse = (old_mouse_info_t *)data;
-
- mouse = &buf;
- mouse->operation = old_mouse->operation;
- switch (mouse->operation) {
- case MOUSE_MODE:
- mouse->u.mode = old_mouse->u.mode;
- break;
- case MOUSE_SHOW:
- case MOUSE_HIDE:
- break;
- case MOUSE_MOVEABS:
- case MOUSE_MOVEREL:
- case MOUSE_ACTION:
- mouse->u.data.x = old_mouse->u.data.x;
- mouse->u.data.y = old_mouse->u.data.y;
- mouse->u.data.z = 0;
- mouse->u.data.buttons = swapb[old_mouse->u.data.buttons & 0x7];
- break;
- case MOUSE_GETINFO:
- old_mouse->u.data.x = scp->mouse_xpos;
- old_mouse->u.data.y = scp->mouse_ypos;
- old_mouse->u.data.buttons = swapb[scp->mouse_buttons & 0x7];
- break;
- default:
- return EINVAL;
- }
- }
-
- switch (mouse->operation) {
- case MOUSE_MODE:
- if (ISSIGVALID(mouse->u.mode.signal)) {
- scp->mouse_signal = mouse->u.mode.signal;
- scp->mouse_proc = p;
- scp->mouse_pid = p->p_pid;
- }
- else {
- scp->mouse_signal = 0;
- scp->mouse_proc = NULL;
- scp->mouse_pid = 0;
- }
- return 0;
-
- case MOUSE_SHOW:
- if (ISTEXTSC(scp) && !(scp->status & MOUSE_ENABLED)) {
- scp->status |= (MOUSE_ENABLED | MOUSE_VISIBLE);
- scp->mouse_oldpos = scp->mouse_pos;
- mark_all(scp);
- return 0;
- }
- else
- return EINVAL;
- break;
-
- case MOUSE_HIDE:
- if (ISTEXTSC(scp) && (scp->status & MOUSE_ENABLED)) {
- scp->status &= ~(MOUSE_ENABLED | MOUSE_VISIBLE);
- mark_all(scp);
- return 0;
- }
- else
- return EINVAL;
- break;
-
- case MOUSE_MOVEABS:
- scp->mouse_xpos = mouse->u.data.x;
- scp->mouse_ypos = mouse->u.data.y;
- set_mouse_pos(scp);
- break;
-
- case MOUSE_MOVEREL:
- scp->mouse_xpos += mouse->u.data.x;
- scp->mouse_ypos += mouse->u.data.y;
- set_mouse_pos(scp);
- break;
-
- case MOUSE_GETINFO:
- mouse->u.data.x = scp->mouse_xpos;
- mouse->u.data.y = scp->mouse_ypos;
- mouse->u.data.z = 0;
- mouse->u.data.buttons = scp->mouse_buttons;
- return 0;
-
- case MOUSE_ACTION:
- case MOUSE_MOTION_EVENT:
- /* this should maybe only be settable from /dev/consolectl SOS */
- /* send out mouse event on /dev/sysmouse */
-
- mouse_status.dx += mouse->u.data.x;
- mouse_status.dy += mouse->u.data.y;
- mouse_status.dz += mouse->u.data.z;
- if (mouse->operation == MOUSE_ACTION)
- mouse_status.button = mouse->u.data.buttons;
- mouse_status.flags |=
- ((mouse->u.data.x || mouse->u.data.y || mouse->u.data.z) ?
- MOUSE_POSCHANGED : 0)
- | (mouse_status.obutton ^ mouse_status.button);
- if (mouse_status.flags == 0)
- return 0;
-
- if (ISTEXTSC(cur_console) && (cur_console->status & MOUSE_ENABLED))
- cur_console->status |= MOUSE_VISIBLE;
-
- if ((MOUSE_TTY)->t_state & TS_ISOPEN) {
- u_char buf[MOUSE_SYS_PACKETSIZE];
- int j;
-
- /* the first five bytes are compatible with MouseSystems' */
- buf[0] = MOUSE_MSC_SYNC
- | butmap[mouse_status.button & MOUSE_STDBUTTONS];
- j = imax(imin(mouse->u.data.x, 255), -256);
- buf[1] = j >> 1;
- buf[3] = j - buf[1];
- j = -imax(imin(mouse->u.data.y, 255), -256);
- buf[2] = j >> 1;
- buf[4] = j - buf[2];
- for (j = 0; j < MOUSE_MSC_PACKETSIZE; j++)
- (*linesw[(MOUSE_TTY)->t_line].l_rint)(buf[j],MOUSE_TTY);
- if (mouse_level >= 1) { /* extended part */
- j = imax(imin(mouse->u.data.z, 127), -128);
- buf[5] = (j >> 1) & 0x7f;
- buf[6] = (j - (j >> 1)) & 0x7f;
- /* buttons 4-10 */
- buf[7] = (~mouse_status.button >> 3) & 0x7f;
- for (j = MOUSE_MSC_PACKETSIZE;
- j < MOUSE_SYS_PACKETSIZE; j++)
- (*linesw[(MOUSE_TTY)->t_line].l_rint)(buf[j],MOUSE_TTY);
- }
- }
-
- if (cur_console->mouse_signal) {
- cur_console->mouse_buttons = mouse->u.data.buttons;
- /* has controlling process died? */
- if (cur_console->mouse_proc &&
- (cur_console->mouse_proc != pfind(cur_console->mouse_pid))){
- cur_console->mouse_signal = 0;
- cur_console->mouse_proc = NULL;
- cur_console->mouse_pid = 0;
- }
- else
- psignal(cur_console->mouse_proc, cur_console->mouse_signal);
- }
- else if (mouse->operation == MOUSE_ACTION && cut_buffer != NULL) {
- /* process button presses */
- if ((cur_console->mouse_buttons ^ mouse->u.data.buttons) &&
- ISTEXTSC(cur_console)) {
- cur_console->mouse_buttons = mouse->u.data.buttons;
- if (cur_console->mouse_buttons & MOUSE_BUTTON1DOWN)
- mouse_cut_start(cur_console);
- else
- mouse_cut_end(cur_console);
- if (cur_console->mouse_buttons & MOUSE_BUTTON2DOWN ||
- cur_console->mouse_buttons & MOUSE_BUTTON3DOWN)
- mouse_paste(cur_console);
- }
- }
-
- if (mouse->u.data.x != 0 || mouse->u.data.y != 0) {
- cur_console->mouse_xpos += mouse->u.data.x;
- cur_console->mouse_ypos += mouse->u.data.y;
- set_mouse_pos(cur_console);
- }
-
- break;
-
- case MOUSE_BUTTON_EVENT:
- if ((mouse->u.event.id & MOUSE_BUTTONS) == 0)
- return EINVAL;
- if (mouse->u.event.value < 0)
- return EINVAL;
-
- if (mouse->u.event.value > 0) {
- cur_console->mouse_buttons |= mouse->u.event.id;
- mouse_status.button |= mouse->u.event.id;
- } else {
- cur_console->mouse_buttons &= ~mouse->u.event.id;
- mouse_status.button &= ~mouse->u.event.id;
- }
- mouse_status.flags |= mouse_status.obutton ^ mouse_status.button;
- if (mouse_status.flags == 0)
- return 0;
-
- if (ISTEXTSC(cur_console) && (cur_console->status & MOUSE_ENABLED))
- cur_console->status |= MOUSE_VISIBLE;
-
- if ((MOUSE_TTY)->t_state & TS_ISOPEN) {
- u_char buf[8];
- int i;
-
- buf[0] = MOUSE_MSC_SYNC
- | butmap[mouse_status.button & MOUSE_STDBUTTONS];
- buf[7] = (~mouse_status.button >> 3) & 0x7f;
- buf[1] = buf[2] = buf[3] = buf[4] = buf[5] = buf[6] = 0;
- for (i = 0;
- i < ((mouse_level >= 1) ? MOUSE_SYS_PACKETSIZE
- : MOUSE_MSC_PACKETSIZE); i++)
- (*linesw[(MOUSE_TTY)->t_line].l_rint)(buf[i],MOUSE_TTY);
- }
-
- if (cur_console->mouse_signal) {
- if (cur_console->mouse_proc &&
- (cur_console->mouse_proc != pfind(cur_console->mouse_pid))){
- cur_console->mouse_signal = 0;
- cur_console->mouse_proc = NULL;
- cur_console->mouse_pid = 0;
- }
- else
- psignal(cur_console->mouse_proc, cur_console->mouse_signal);
- break;
- }
-
- if (!ISTEXTSC(cur_console) || (cut_buffer == NULL))
- break;
-
- switch (mouse->u.event.id) {
- case MOUSE_BUTTON1DOWN:
- switch (mouse->u.event.value % 4) {
- case 0: /* up */
- mouse_cut_end(cur_console);
- break;
- case 1:
- mouse_cut_start(cur_console);
- break;
- case 2:
- mouse_cut_word(cur_console);
- break;
- case 3:
- mouse_cut_line(cur_console);
- break;
- }
- break;
- case MOUSE_BUTTON2DOWN:
- switch (mouse->u.event.value) {
- case 0: /* up */
- break;
- default:
- mouse_paste(cur_console);
- break;
- }
- break;
- case MOUSE_BUTTON3DOWN:
- switch (mouse->u.event.value) {
- case 0: /* up */
- if (!(cur_console->mouse_buttons & MOUSE_BUTTON1DOWN))
- mouse_cut_end(cur_console);
- break;
- default:
- mouse_cut_extend(cur_console);
- break;
- }
- break;
- }
- break;
-
- default:
- return EINVAL;
- }
- /* make screensaver happy */
- sc_touch_scrn_saver();
- return 0;
- }
-
- /* MOUSE_XXX: /dev/sysmouse ioctls */
- case MOUSE_GETHWINFO: /* get device information */
- {
- mousehw_t *hw = (mousehw_t *)data;
-
- if (tp != MOUSE_TTY)
- return ENOTTY;
- hw->buttons = 10; /* XXX unknown */
- hw->iftype = MOUSE_IF_SYSMOUSE;
- hw->type = MOUSE_MOUSE;
- hw->model = MOUSE_MODEL_GENERIC;
- hw->hwid = 0;
+ sc->flags &= ~SC_QUIET_BELL;
return 0;
- }
-
- case MOUSE_GETMODE: /* get protocol/mode */
- {
- mousemode_t *mode = (mousemode_t *)data;
-
- if (tp != MOUSE_TTY)
- return ENOTTY;
- mode->level = mouse_level;
- switch (mode->level) {
- case 0:
- /* at this level, sysmouse emulates MouseSystems protocol */
- mode->protocol = MOUSE_PROTO_MSC;
- mode->rate = -1; /* unknown */
- mode->resolution = -1; /* unknown */
- mode->accelfactor = 0; /* disabled */
- mode->packetsize = MOUSE_MSC_PACKETSIZE;
- mode->syncmask[0] = MOUSE_MSC_SYNCMASK;
- mode->syncmask[1] = MOUSE_MSC_SYNC;
- break;
-
- case 1:
- /* at this level, sysmouse uses its own protocol */
- mode->protocol = MOUSE_PROTO_SYSMOUSE;
- mode->rate = -1;
- mode->resolution = -1;
- mode->accelfactor = 0;
- mode->packetsize = MOUSE_SYS_PACKETSIZE;
- mode->syncmask[0] = MOUSE_SYS_SYNCMASK;
- mode->syncmask[1] = MOUSE_SYS_SYNC;
- break;
- }
- return 0;
- }
-
- case MOUSE_SETMODE: /* set protocol/mode */
- {
- mousemode_t *mode = (mousemode_t *)data;
-
- if (tp != MOUSE_TTY)
- return ENOTTY;
- if ((mode->level < 0) || (mode->level > 1))
- return EINVAL;
- mouse_level = mode->level;
- return 0;
- }
-
- case MOUSE_GETLEVEL: /* get operation level */
- if (tp != MOUSE_TTY)
- return ENOTTY;
- *(int *)data = mouse_level;
- return 0;
-
- case MOUSE_SETLEVEL: /* set operation level */
- if (tp != MOUSE_TTY)
- return ENOTTY;
- if ((*(int *)data < 0) || (*(int *)data > 1))
- return EINVAL;
- mouse_level = *(int *)data;
- return 0;
-
- case MOUSE_GETSTATUS: /* get accumulated mouse events */
- if (tp != MOUSE_TTY)
- return ENOTTY;
- s = spltty();
- *(mousestatus_t *)data = mouse_status;
- mouse_status.flags = 0;
- mouse_status.obutton = mouse_status.button;
- mouse_status.dx = 0;
- mouse_status.dy = 0;
- mouse_status.dz = 0;
- splx(s);
- return 0;
-
-#if notyet
- case MOUSE_GETVARS: /* get internal mouse variables */
- case MOUSE_SETVARS: /* set internal mouse variables */
- if (tp != MOUSE_TTY)
- return ENOTTY;
- return ENODEV;
-#endif
-
- case MOUSE_READSTATE: /* read status from the device */
- case MOUSE_READDATA: /* read data from the device */
- if (tp != MOUSE_TTY)
- return ENOTTY;
- return ENODEV;
case CONS_GETINFO: /* get current (virtual) console info */
{
vid_info_t *ptr = (vid_info_t*)data;
if (ptr->size == sizeof(struct vid_info)) {
- ptr->m_num = get_scr_num();
+ ptr->m_num = sc->cur_scp->index;
ptr->mv_col = scp->xpos;
ptr->mv_row = scp->ypos;
ptr->mv_csz = scp->xsize;
@@ -1382,7 +818,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
ptr->mv_grfc.fore = 0; /* not supported */
ptr->mv_grfc.back = 0; /* not supported */
ptr->mv_ovscan = scp->border;
- if (scp == cur_console)
+ if (scp == sc->cur_scp)
save_kbd_state(scp);
ptr->mk_keylock = scp->status & LOCK_MASK;
return 0;
@@ -1404,9 +840,9 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
* 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));
+ *(int *)data = (sc->flags & SC_SCRN_IDLE)
+ && (!ISGRAPHSC(sc->cur_scp)
+ || (sc->cur_scp->status & SAVER_RUNNING));
return 0;
case CONS_SAVERMODE: /* set saver mode */
@@ -1416,10 +852,13 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
scsplash_stick(FALSE);
saver_mode = *(int *)data;
s = spltty();
- if ((error = wait_scrn_saver_stop())) {
+#if NSPLASH > 0
+ if ((error = wait_scrn_saver_stop(NULL))) {
splx(s);
return error;
}
+#endif /* NSPLASH */
+ run_scrn_saver = TRUE;
scp->status |= SAVER_RUNNING;
scsplash_stick(TRUE);
splx(s);
@@ -1444,7 +883,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
s = spltty();
run_scrn_saver = (*(int *)data != 0);
if (run_scrn_saver)
- scrn_time_stamp -= scrn_blank_time;
+ sc->scrn_time_stamp -= scrn_blank_time;
splx(s);
return 0;
@@ -1453,16 +892,51 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
struct vt_mode *mode;
mode = (struct vt_mode *)data;
- if (ISSIGVALID(mode->relsig) && ISSIGVALID(mode->acqsig) &&
- ISSIGVALID(mode->frsig)) {
- bcopy(data, &scp->smode, sizeof(struct vt_mode));
- if (scp->smode.mode == VT_PROCESS) {
- scp->proc = p;
- scp->pid = scp->proc->p_pid;
+ DPRINTF(5, ("sc%d: VT_SETMODE ", sc->unit));
+ if (scp->smode.mode == VT_PROCESS) {
+ if (scp->proc == pfind(scp->pid) && scp->proc != p) {
+ DPRINTF(5, ("error EPERM\n"));
+ return EPERM;
}
- return 0;
- } else
- return EINVAL;
+ }
+ s = spltty();
+ if (mode->mode == VT_AUTO) {
+ scp->smode.mode = VT_AUTO;
+ scp->proc = NULL;
+ scp->pid = 0;
+ DPRINTF(5, ("VT_AUTO, "));
+ if ((scp == sc->cur_scp) && (sc->unit == sc_console_unit))
+ cons_unavail = FALSE;
+ /* were we in the middle of the vty switching process? */
+ if (scp->status & SWITCH_WAIT_REL) {
+ /* assert(scp == scp->sc->cur_scp) */
+ DPRINTF(5, ("reset WAIT_REL, "));
+ scp->status &= ~SWITCH_WAIT_REL;
+ s = do_switch_scr(sc, s);
+ }
+ if (scp->status & SWITCH_WAIT_ACQ) {
+ /* assert(scp == scp->sc->cur_scp) */
+ DPRINTF(5, ("reset WAIT_ACQ, "));
+ scp->status &= ~SWITCH_WAIT_ACQ;
+ sc->switch_in_progress = 0;
+ }
+ } else {
+ if (!ISSIGVALID(mode->relsig) || !ISSIGVALID(mode->acqsig)
+ || !ISSIGVALID(mode->frsig)) {
+ splx(s);
+ DPRINTF(5, ("error EINVAL\n"));
+ return EINVAL;
+ }
+ DPRINTF(5, ("VT_PROCESS %d, ", p->p_pid));
+ bcopy(data, &scp->smode, sizeof(struct vt_mode));
+ scp->proc = p;
+ scp->pid = scp->proc->p_pid;
+ if ((scp == sc->cur_scp) && (sc->unit == sc_console_unit))
+ cons_unavail = TRUE;
+ }
+ splx(s);
+ DPRINTF(5, ("\n"));
+ return 0;
}
case VT_GETMODE: /* get screen switcher mode */
@@ -1470,45 +944,58 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return 0;
case VT_RELDISP: /* screen switcher ioctl */
+ s = spltty();
+ /*
+ * This must be the current vty which is in the VT_PROCESS
+ * switching mode...
+ */
+ if ((scp != sc->cur_scp) || (scp->smode.mode != VT_PROCESS)) {
+ splx(s);
+ return EINVAL;
+ }
+ /* ...and this process is controlling it. */
+ if (scp->proc != p) {
+ splx(s);
+ return EPERM;
+ }
+ error = EINVAL;
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;
- switch_in_progress = FALSE;
- return 0;
+ if ((scp == sc->old_scp) && (scp->status & SWITCH_WAIT_REL)) {
+ sc->old_scp->status &= ~SWITCH_WAIT_REL;
+ sc->switch_in_progress = 0;
+ DPRINTF(5, ("sc%d: VT_FALSE\n", sc->unit));
+ error = 0;
}
- return EINVAL;
+ break;
case VT_TRUE: /* user has released screen, go on */
- if (scp == old_scp && (scp->status & SWITCH_WAIT_REL)) {
+ if ((scp == sc->old_scp) && (scp->status & SWITCH_WAIT_REL)) {
scp->status &= ~SWITCH_WAIT_REL;
- exchange_scr();
- if (new_scp->smode.mode == VT_PROCESS) {
- new_scp->status |= SWITCH_WAIT_ACQ;
- psignal(new_scp->proc, new_scp->smode.acqsig);
- }
- else
- switch_in_progress = FALSE;
- return 0;
+ s = do_switch_scr(sc, s);
+ DPRINTF(5, ("sc%d: VT_TRUE\n", sc->unit));
+ error = 0;
}
- return EINVAL;
+ break;
case VT_ACKACQ: /* acquire acknowledged, switch completed */
- if (scp == new_scp && (scp->status & SWITCH_WAIT_ACQ)) {
+ if ((scp == sc->new_scp) && (scp->status & SWITCH_WAIT_ACQ)) {
scp->status &= ~SWITCH_WAIT_ACQ;
- switch_in_progress = FALSE;
- return 0;
+ sc->switch_in_progress = 0;
+ DPRINTF(5, ("sc%d: VT_ACKACQ\n", sc->unit));
+ error = 0;
}
- return EINVAL;
+ break;
default:
- return EINVAL;
+ break;
}
- /* NOT REACHED */
+ splx(s);
+ return error;
case VT_OPENQRY: /* return free virtual console */
- for (i = 0; i < MAXCONS; i++) {
- tp = VIRTUAL_TTY(i);
+ for (i = sc->first_vty; i < sc->first_vty + sc->vtys; i++) {
+ tp = VIRTUAL_TTY(sc, i);
if (!(tp->t_state & TS_ISOPEN)) {
*(int *)data = i + 1;
return 0;
@@ -1518,32 +1005,33 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
case VT_ACTIVATE: /* switch to screen *data */
s = spltty();
- sc_clean_up(cur_console);
+ sc_clean_up(sc->cur_scp);
splx(s);
- return switch_scr(scp, *(int *)data - 1);
+ return switch_scr(sc, *(int *)data - 1);
case VT_WAITACTIVE: /* wait for switch to occur */
- if (*(int *)data > MAXCONS || *(int *)data < 0)
+ if ((*(int *)data >= sc->first_vty + sc->vtys)
+ || (*(int *)data < sc->first_vty))
return EINVAL;
s = spltty();
- error = sc_clean_up(cur_console);
+ error = sc_clean_up(sc->cur_scp);
splx(s);
if (error)
return error;
- if (minor(dev) == *(int *)data - 1)
+ if (*(int *)data != 0)
+ scp = sc->console[*(int *)data - 1 - sc->first_vty];
+ if (scp == scp->sc->cur_scp)
return 0;
- if (*(int *)data == 0) {
- if (scp == cur_console)
- return 0;
- }
- else
- scp = console[*(int *)data - 1];
while ((error=tsleep((caddr_t)&scp->smode, PZERO|PCATCH,
"waitvt", 0)) == ERESTART) ;
return error;
- case VT_GETACTIVE:
- *(int *)data = get_scr_num()+1;
+ case VT_GETACTIVE: /* get active vty # */
+ *(int *)data = sc->cur_scp->index + 1;
+ return 0;
+
+ case VT_GETINDEX: /* get this vty # */
+ *(int *)data = scp->index + 1;
return 0;
case KDENABIO: /* allow io operations */
@@ -1568,18 +1056,18 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return EINVAL;
scp->status &= ~LOCK_MASK;
scp->status |= *(int *)data;
- if (scp == cur_console)
- update_kbd_state(scp->status, LOCK_MASK);
+ if (scp == sc->cur_scp)
+ update_kbd_state(scp, scp->status, LOCK_MASK);
return 0;
case KDGKBSTATE: /* get keyboard state (locks) */
- if (scp == cur_console)
+ if (scp == sc->cur_scp)
save_kbd_state(scp);
*(int *)data = scp->status & LOCK_MASK;
return 0;
case KDSETREPEAT: /* set keyboard repeat & delay rates (new) */
- error = kbd_ioctl(kbd, cmd, data);
+ error = kbd_ioctl(sc->kbd, cmd, data);
if (error == ENOIOCTL)
error = ENODEV;
return error;
@@ -1587,7 +1075,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
case KDSETRAD: /* set keyboard repeat & delay rates (old) */
if (*(int *)data & ~0x7f)
return EINVAL;
- error = kbd_ioctl(kbd, cmd, data);
+ error = kbd_ioctl(sc->kbd, cmd, data);
if (error == ENOIOCTL)
error = ENODEV;
return error;
@@ -1598,8 +1086,8 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
case K_RAW: /* switch to RAW scancode mode */
case K_CODE: /* switch to CODE mode */
scp->kbd_mode = *(int *)data;
- if (scp == cur_console)
- kbd_ioctl(kbd, cmd, data);
+ if (scp == sc->cur_scp)
+ kbd_ioctl(sc->kbd, cmd, data);
return 0;
default:
return EINVAL;
@@ -1611,7 +1099,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return 0;
case KDGKBINFO:
- error = kbd_ioctl(kbd, cmd, data);
+ error = kbd_ioctl(sc->kbd, cmd, data);
if (error == ENOIOCTL)
error = ENODEV;
return error;
@@ -1625,33 +1113,16 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return 0;
case KIOCSOUND: /* make tone (*data) hz */
-#ifdef __i386__
- if (scp == cur_console) {
- if (*(int*)data) {
- int pitch = timer_freq / *(int*)data;
-
- /* set command for counter 2, 2 byte write */
- if (acquire_timer2(TIMER_16BIT|TIMER_SQWAVE))
- return EBUSY;
-
- /* set pitch */
- outb(TIMER_CNTR2, pitch);
- outb(TIMER_CNTR2, (pitch>>8));
-
- /* enable counter 2 output to speaker */
- outb(IO_PPI, inb(IO_PPI) | 3);
- }
- else {
- /* disable counter 2 output to speaker */
- outb(IO_PPI, inb(IO_PPI) & 0xFC);
- release_timer2();
- }
+ if (scp == sc->cur_scp) {
+ if (*(int *)data)
+ return sc_tone(*(int *)data);
+ else
+ return sc_tone(0);
}
-#endif /* __i386__ */
return 0;
case KDGKBTYPE: /* get keyboard type */
- error = kbd_ioctl(kbd, cmd, data);
+ error = kbd_ioctl(sc->kbd, cmd, data);
if (error == ENOIOCTL) {
/* always return something? XXX */
*(int *)data = 0;
@@ -1663,12 +1134,12 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return EINVAL;
scp->status &= ~LED_MASK;
scp->status |= *(int *)data;
- if (scp == cur_console)
- update_kbd_leds(scp->status);
+ if (scp == sc->cur_scp)
+ update_kbd_leds(scp, scp->status);
return 0;
case KDGETLED: /* get keyboard LED status */
- if (scp == cur_console)
+ if (scp == sc->cur_scp)
save_kbd_state(scp);
*(int *)data = scp->status & LED_MASK;
return 0;
@@ -1684,19 +1155,21 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return EINVAL;
}
error = 0;
- if (kbd != newkbd) {
+ if (sc->kbd != newkbd) {
i = kbd_allocate(newkbd->kb_name, newkbd->kb_unit,
- (void *)&keyboard, sckbdevent, NULL);
+ (void *)&sc->keyboard, sckbdevent, sc);
/* i == newkbd->kb_index */
if (i >= 0) {
- if (kbd != NULL) {
- save_kbd_state(cur_console);
- kbd_release(kbd, (void *)&keyboard);
+ if (sc->kbd != NULL) {
+ save_kbd_state(sc->cur_scp);
+ kbd_release(sc->kbd, (void *)&sc->keyboard);
}
- kbd = kbd_get_keyboard(i); /* kbd == newkbd */
- keyboard = i;
- kbd_ioctl(kbd, KDSKBMODE, (caddr_t)&cur_console->kbd_mode);
- update_kbd_state(cur_console->status, LOCK_MASK);
+ sc->kbd = kbd_get_keyboard(i); /* sc->kbd == newkbd */
+ sc->keyboard = i;
+ kbd_ioctl(sc->kbd, KDSKBMODE,
+ (caddr_t)&sc->cur_scp->kbd_mode);
+ update_kbd_state(sc->cur_scp, sc->cur_scp->status,
+ LOCK_MASK);
} else {
error = EPERM; /* XXX */
}
@@ -1708,25 +1181,26 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
case CONS_RELKBD: /* release the current keyboard */
s = spltty();
error = 0;
- if (kbd != NULL) {
- save_kbd_state(cur_console);
- error = kbd_release(kbd, (void *)&keyboard);
+ if (sc->kbd != NULL) {
+ save_kbd_state(sc->cur_scp);
+ error = kbd_release(sc->kbd, (void *)&sc->keyboard);
if (error == 0) {
- kbd = NULL;
- keyboard = -1;
+ sc->kbd = NULL;
+ sc->keyboard = -1;
}
}
splx(s);
return error;
case GIO_SCRNMAP: /* get output translation table */
- bcopy(&scr_map, data, sizeof(scr_map));
+ bcopy(&sc->scr_map, data, sizeof(sc->scr_map));
return 0;
case PIO_SCRNMAP: /* set output translation table */
- bcopy(data, &scr_map, sizeof(scr_map));
- for (i=0; i<sizeof(scr_map); i++)
- scr_rmap[scr_map[i]] = i;
+ bcopy(data, &sc->scr_map, sizeof(sc->scr_map));
+ for (i=0; i<sizeof(sc->scr_map); i++) {
+ sc->scr_rmap[sc->scr_map[i]] = i;
+ }
return 0;
case GIO_KEYMAP: /* get keyboard translation table */
@@ -1735,83 +1209,89 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
case PIO_DEADKEYMAP: /* set accent key translation table */
case GETFKEY: /* get function key string */
case SETFKEY: /* set function key string */
- error = kbd_ioctl(kbd, cmd, data);
+ error = kbd_ioctl(sc->kbd, cmd, data);
if (error == ENOIOCTL)
error = ENODEV;
return error;
+#ifndef SC_NO_FONT_LOADING
+
case PIO_FONT8x8: /* set 8x8 dot font */
- if (!ISFONTAVAIL(scp->adp->va_flags))
+ if (!ISFONTAVAIL(sc->adp->va_flags))
return ENXIO;
- bcopy(data, font_8, 8*256);
- fonts_loaded |= FONT_8;
+ bcopy(data, sc->font_8, 8*256);
+ sc->fonts_loaded |= FONT_8;
/*
* FONT KLUDGE
* Always use the font page #0. XXX
* Don't load if the current font size is not 8x8.
*/
- if (ISTEXTSC(cur_console) && (cur_console->font_size < 14))
- copy_font(cur_console, LOAD, 8, font_8);
+ if (ISTEXTSC(sc->cur_scp) && (sc->cur_scp->font_size < 14))
+ copy_font(sc->cur_scp, LOAD, 8, sc->font_8);
return 0;
case GIO_FONT8x8: /* get 8x8 dot font */
- if (!ISFONTAVAIL(scp->adp->va_flags))
+ if (!ISFONTAVAIL(sc->adp->va_flags))
return ENXIO;
- if (fonts_loaded & FONT_8) {
- bcopy(font_8, data, 8*256);
+ if (sc->fonts_loaded & FONT_8) {
+ bcopy(sc->font_8, data, 8*256);
return 0;
}
else
return ENXIO;
case PIO_FONT8x14: /* set 8x14 dot font */
- if (!ISFONTAVAIL(scp->adp->va_flags))
+ if (!ISFONTAVAIL(sc->adp->va_flags))
return ENXIO;
- bcopy(data, font_14, 14*256);
- fonts_loaded |= FONT_14;
+ bcopy(data, sc->font_14, 14*256);
+ sc->fonts_loaded |= FONT_14;
/*
* FONT KLUDGE
* Always use the font page #0. XXX
* Don't load if the current font size is not 8x14.
*/
- if (ISTEXTSC(cur_console)
- && (cur_console->font_size >= 14) && (cur_console->font_size < 16))
- copy_font(cur_console, LOAD, 14, font_14);
+ if (ISTEXTSC(sc->cur_scp)
+ && (sc->cur_scp->font_size >= 14)
+ && (sc->cur_scp->font_size < 16))
+ copy_font(sc->cur_scp, LOAD, 14, sc->font_14);
return 0;
case GIO_FONT8x14: /* get 8x14 dot font */
- if (!ISFONTAVAIL(scp->adp->va_flags))
+ if (!ISFONTAVAIL(sc->adp->va_flags))
return ENXIO;
- if (fonts_loaded & FONT_14) {
- bcopy(font_14, data, 14*256);
+ if (sc->fonts_loaded & FONT_14) {
+ bcopy(sc->font_14, data, 14*256);
return 0;
}
else
return ENXIO;
case PIO_FONT8x16: /* set 8x16 dot font */
- if (!ISFONTAVAIL(scp->adp->va_flags))
+ if (!ISFONTAVAIL(sc->adp->va_flags))
return ENXIO;
- bcopy(data, font_16, 16*256);
- fonts_loaded |= FONT_16;
+ bcopy(data, sc->font_16, 16*256);
+ sc->fonts_loaded |= FONT_16;
/*
* FONT KLUDGE
* Always use the font page #0. XXX
* Don't load if the current font size is not 8x16.
*/
- if (ISTEXTSC(cur_console) && (cur_console->font_size >= 16))
- copy_font(cur_console, LOAD, 16, font_16);
+ if (ISTEXTSC(sc->cur_scp) && (sc->cur_scp->font_size >= 16))
+ copy_font(sc->cur_scp, LOAD, 16, sc->font_16);
return 0;
case GIO_FONT8x16: /* get 8x16 dot font */
- if (!ISFONTAVAIL(scp->adp->va_flags))
+ if (!ISFONTAVAIL(sc->adp->va_flags))
return ENXIO;
- if (fonts_loaded & FONT_16) {
- bcopy(font_16, data, 16*256);
+ if (sc->fonts_loaded & FONT_16) {
+ bcopy(sc->font_16, data, 16*256);
return 0;
}
else
return ENXIO;
+
+#endif /* SC_NO_FONT_LOADING */
+
default:
break;
}
@@ -1833,8 +1313,8 @@ scstart(struct tty *tp)
u_char buf[PCBURST];
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? */
+ if (scp->status & SLKED || scp->sc->blink_in_progress)
+ return;
s = spltty();
if (!(tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP))) {
tp->t_state |= TS_BUSY;
@@ -1871,105 +1351,141 @@ scmousestart(struct tty *tp)
splx(s);
}
-#if __i386__
-
-/* XXX kludge! */
-extern struct isa_driver scdriver;
-
static void
sccnprobe(struct consdev *cp)
{
-#if 0
- struct isa_device *dvp;
+#if __i386__
+ int unit;
+ int flags;
- /*
- * Take control if we are the highest priority enabled display device.
- */
- dvp = find_display();
- if (dvp == NULL || dvp->id_driver != &scdriver) {
- cp->cn_pri = CN_DEAD;
- return;
- }
+ cp->cn_pri = sc_get_cons_priority(&unit, &flags);
- if (!scvidprobe(dvp->id_unit, dvp->id_flags, TRUE)) {
- cp->cn_pri = CN_DEAD;
- return;
- }
- sckbdprobe(dvp->id_unit, dvp->id_flags, TRUE);
-#else
- if (!scvidprobe(0, 0, TRUE)) {
+ /* a video card is always required */
+ if (!scvidprobe(unit, flags, TRUE))
cp->cn_pri = CN_DEAD;
+
+ /* syscons will become console even when there is no keyboard */
+ sckbdprobe(unit, flags, TRUE);
+
+ if (cp->cn_pri == CN_DEAD)
return;
- }
- sckbdprobe(0, 0, TRUE);
-#endif
/* initialize required fields */
- cp->cn_dev = makedev(CDEV_MAJOR, SC_CONSOLE);
- cp->cn_pri = CN_INTERNAL;
+ cp->cn_dev = makedev(CDEV_MAJOR, SC_CONSOLECTL);
+#endif /* __i386__ */
+
+#if __alpha__
+ /*
+ * alpha use sccnattach() rather than cnprobe()/cninit()/cnterm()
+ * interface to install the console. Always return CN_DEAD from
+ * here.
+ */
+ cp->cn_pri = CN_DEAD;
+#endif /* __alpha__ */
}
static void
sccninit(struct consdev *cp)
{
- scinit();
+#if __i386__
+ int unit;
+ int flags;
+
+ sc_get_cons_priority(&unit, &flags);
+ scinit(unit, flags | SC_KERNEL_CONSOLE);
+ sc_console_unit = unit;
+ sc_console = sc_get_softc(unit, SC_KERNEL_CONSOLE)->console[0];
+#endif /* __i386__ */
+
+#if __alpha__
+ /* SHOULDN'T REACH HERE */
+#endif /* __alpha__ */
+}
+
+static void
+sccnterm(struct consdev *cp)
+{
+ /* we are not the kernel console any more, release everything */
+
+ if (sc_console_unit < 0)
+ return; /* shouldn't happen */
+
+#if __i386__
+#if 0 /* XXX */
+ sc_clear_screen(sc_console);
+ sccnupdate(sc_console);
+#endif
+ scterm(sc_console_unit, SC_KERNEL_CONSOLE);
+ sc_console_unit = -1;
+ sc_console = NULL;
+#endif /* __i386__ */
+
+#if __alpha__
+ /* do nothing XXX */
+#endif /* __alpha__ */
}
-#else /* !__i386__ */
+#ifdef __alpha__
extern struct consdev *cn_tab;
void
sccnattach(void)
{
- if (!scvidprobe(0, 0, TRUE) || !sckbdprobe(0, 0, TRUE)) {
+ static struct consdev consdev;
+ int unit;
+ int flags;
+
+ bcopy(&sc_consdev, &consdev, sizeof(sc_consdev));
+ consdev.cn_pri = sc_get_cons_priority(&unit, &flags);
+
+ /* a video card is always required */
+ if (!scvidprobe(unit, flags, TRUE))
+ consdev.cn_pri = CN_DEAD;
+
+ /* alpha doesn't allow the console being without a keyboard... Why? */
+ if (!sckbdprobe(unit, flags, TRUE))
+ consdev.cn_pri = CN_DEAD;
+
+ if (consdev.cn_pri == CN_DEAD)
return;
- }
- scinit();
- sc_cons.cn_dev = makedev(CDEV_MAJOR, 0);
- cn_tab = &sc_cons;
+ scinit(unit, flags | SC_KERNEL_CONSOLE);
+ sc_console_unit = unit;
+ sc_console = sc_get_softc(unit, SC_KERNEL_CONSOLE)->console[0];
+ consdev.cn_dev = makedev(CDEV_MAJOR, 0);
+ cn_tab = &consdev;
}
-#endif /* __i386__ */
+#endif /* __alpha__ */
static void
sccnputc(dev_t dev, int c)
{
u_char buf[1];
- scr_stat *scp = console[0];
+ scr_stat *scp = sc_console;
term_stat save = scp->term;
- u_short *p;
int s;
- int i;
- if (scp == cur_console && scp->status & SLKED) {
+ /* assert(sc_console != NULL) */
+
+#ifndef SC_NO_HISTORY
+ if (scp == scp->sc->cur_scp && scp->status & SLKED) {
scp->status &= ~SLKED;
- update_kbd_state(scp->status, SLKED);
- if (cur_console->status & BUFFER_SAVED) {
- p = cur_console->history_save;
- for (i = 0; i < cur_console->ysize; ++i) {
- bcopy(p, cur_console->scr_buf + (cur_console->xsize*i),
- cur_console->xsize*sizeof(u_short));
- p += cur_console->xsize;
- if (p + cur_console->xsize
- > cur_console->history + cur_console->history_size)
- p = cur_console->history;
- }
- cur_console->status &= ~BUFFER_SAVED;
- cur_console->history_head = cur_console->history_save;
- cur_console->status |= CURSOR_ENABLED;
- mark_all(cur_console);
+ update_kbd_state(scp, scp->status, SLKED);
+ if (scp->status & BUFFER_SAVED) {
+ if (!sc_hist_restore(scp))
+ sc_remove_cutmarking(scp);
+ scp->status &= ~BUFFER_SAVED;
+ scp->status |= CURSOR_ENABLED;
+ draw_cursor_image(scp);
}
-#if 1 /* XXX */
- scstart(VIRTUAL_TTY(get_scr_num()));
-#endif
+ scstart(VIRTUAL_TTY(scp->sc, scp->index));
}
+#endif /* !SC_NO_HISTORY */
scp->term = kernel_console;
current_default = &kernel_default;
- if (scp == cur_console && !ISGRAPHSC(scp))
- remove_cursor_image(scp);
buf[0] = c;
ansi_put(scp, buf, 1);
kernel_console = scp->term;
@@ -1996,18 +1512,30 @@ sccncheckc(dev_t dev)
static int
sccngetch(int flags)
{
+ static struct fkeytab fkey;
+ static int fkeycp;
+ scr_stat *scp;
+ u_char *p;
int cur_mode;
int s = spltty(); /* block sckbdevent and scrn_timer while we poll */
int c;
+ /* assert(sc_console != NULL) */
+
/*
* Stop the screen saver and update the screen if necessary.
* What if we have been running in the screen saver code... XXX
*/
sc_touch_scrn_saver();
- sccnupdate(cur_console);
+ scp = sc_console->sc->cur_scp; /* XXX */
+ sccnupdate(scp);
+
+ if (fkeycp < fkey.len) {
+ splx(s);
+ return fkey.str[fkeycp++];
+ }
- if (kbd == NULL) {
+ if (scp->sc->kbd == NULL) {
splx(s);
return -1;
}
@@ -2016,26 +1544,33 @@ sccngetch(int flags)
* Make sure the keyboard is accessible even when the kbd device
* driver is disabled.
*/
- kbd_enable(kbd);
+ kbd_enable(scp->sc->kbd);
/* we shall always use the keyboard in the XLATE mode here */
- cur_mode = cur_console->kbd_mode;
- cur_console->kbd_mode = K_XLATE;
- kbd_ioctl(kbd, KDSKBMODE, (caddr_t)&cur_console->kbd_mode);
+ cur_mode = scp->kbd_mode;
+ scp->kbd_mode = K_XLATE;
+ kbd_ioctl(scp->sc->kbd, KDSKBMODE, (caddr_t)&scp->kbd_mode);
- kbd_poll(kbd, TRUE);
- c = scgetc(kbd, SCGETC_CN | flags);
- kbd_poll(kbd, FALSE);
+ kbd_poll(scp->sc->kbd, TRUE);
+ c = scgetc(scp->sc, SCGETC_CN | flags);
+ kbd_poll(scp->sc->kbd, FALSE);
- cur_console->kbd_mode = cur_mode;
- kbd_ioctl(kbd, KDSKBMODE, (caddr_t)&cur_console->kbd_mode);
- kbd_disable(kbd);
+ scp->kbd_mode = cur_mode;
+ kbd_ioctl(scp->sc->kbd, KDSKBMODE, (caddr_t)&scp->kbd_mode);
+ kbd_disable(scp->sc->kbd);
splx(s);
switch (KEYFLAGS(c)) {
case 0: /* normal char */
return KEYCHAR(c);
case FKEY: /* function key */
+ p = kbd_get_fkeystr(scp->sc->kbd, KEYCHAR(c), (size_t *)&fkeycp);
+ fkey.len = fkeycp;
+ if ((p != NULL) && (fkey.len > 0)) {
+ bcopy(p, fkey.str, fkey.len);
+ fkeycp = 1;
+ return fkey.str[0];
+ }
return c; /* XXX */
case NOKEY:
case ERRKEY:
@@ -2050,23 +1585,30 @@ sccnupdate(scr_stat *scp)
{
/* this is a cut-down version of scrn_timer()... */
- if (font_loading_in_progress)
+ if (scp->sc->font_loading_in_progress || scp->sc->videoio_in_progress)
return;
- if (panicstr || shutdown_in_progress) {
+ if (debugger || panicstr || shutdown_in_progress) {
sc_touch_scrn_saver();
- } else if (scp != cur_console) {
+ } else if (scp != scp->sc->cur_scp) {
return;
}
if (!run_scrn_saver)
- scrn_idle = FALSE;
- if ((saver_mode != CONS_LKM_SAVER) || !scrn_idle)
- if (scrn_blanked)
- stop_scrn_saver(current_saver);
+ scp->sc->flags &= ~SC_SCRN_IDLE;
+#if NSPLASH > 0
+ if ((saver_mode != CONS_LKM_SAVER) || !(scp->sc->flags & SC_SCRN_IDLE))
+ if (scp->sc->flags & SC_SCRN_BLANKED)
+ stop_scrn_saver(scp->sc, current_saver);
+#endif /* NSPLASH */
- if (scp != cur_console || blink_in_progress || switch_in_progress)
+ if (scp != scp->sc->cur_scp || scp->sc->blink_in_progress
+ || scp->sc->switch_in_progress)
return;
+ /*
+ * FIXME: unlike scrn_timer(), we call scrn_update() from here even
+ * when write_in_progress is non-zero. XXX
+ */
if (!ISGRAPHSC(scp) && !(scp->status & SAVER_RUNNING))
scrn_update(scp, TRUE);
@@ -2075,23 +1617,22 @@ sccnupdate(scr_stat *scp)
scr_stat
*sc_get_scr_stat(dev_t dev)
{
- int unit = minor(dev);
+ sc_softc_t *sc;
+ int vty = SC_VTY(dev);
+ int unit;
- if (unit == SC_CONSOLE)
- return console[0];
- if (unit >= MAXCONS || unit < 0)
- return(NULL);
- return console[unit];
-}
-
-static int
-get_scr_num()
-{
- int i = 0;
+ if (vty < 0)
+ return NULL;
+ if (vty == SC_CONSOLECTL)
+ return sc_console;
- while ((i < MAXCONS) && (cur_console != console[i]))
- i++;
- return i < MAXCONS ? i : 0;
+ unit = scdevtounit(dev);
+ sc = sc_get_softc(unit, (sc_console_unit == unit) ? SC_KERNEL_CONSOLE : 0);
+ if (sc == NULL)
+ return NULL;
+ if ((sc->first_vty <= vty) && (vty < sc->first_vty + sc->vtys))
+ return sc->console[vty - sc->first_vty];
+ return NULL;
}
static void
@@ -2099,113 +1640,187 @@ scrn_timer(void *arg)
{
static int kbd_interval = 0;
struct timeval tv;
+ sc_softc_t *sc;
scr_stat *scp;
+ int again;
int s;
- /* don't do anything when we are touching font */
- if (font_loading_in_progress) {
- if (arg)
- timeout(scrn_timer, (void *)TRUE, hz / 10);
+ again = (arg != NULL);
+ if (arg != NULL)
+ sc = (sc_softc_t *)arg;
+ else if (sc_console != NULL)
+ sc = sc_console->sc;
+ else
+ return;
+
+ /* don't do anything when we are performing some I/O operations */
+ if (sc->font_loading_in_progress || sc->videoio_in_progress) {
+ if (again)
+ timeout(scrn_timer, sc, hz / 10);
return;
}
s = spltty();
- if ((kbd == NULL) && (sc_flags & AUTODETECT_KBD)) {
+ if ((sc->kbd == NULL) && (sc->config & SC_AUTODETECT_KBD)) {
/* try to allocate a keyboard automatically */
if (++kbd_interval >= 25) {
- keyboard = kbd_allocate("*", -1, (void *)&keyboard,
- sckbdevent, NULL);
- if (keyboard >= 0) {
- kbd = kbd_get_keyboard(keyboard);
- kbd_ioctl(kbd, KDSKBMODE, (caddr_t)&cur_console->kbd_mode);
- update_kbd_state(cur_console->status, LOCK_MASK);
+ sc->keyboard = kbd_allocate("*", -1, (void *)&sc->keyboard,
+ sckbdevent, sc);
+ if (sc->keyboard >= 0) {
+ sc->kbd = kbd_get_keyboard(sc->keyboard);
+ kbd_ioctl(sc->kbd, KDSKBMODE,
+ (caddr_t)&sc->cur_scp->kbd_mode);
+ update_kbd_state(sc->cur_scp, sc->cur_scp->status,
+ LOCK_MASK);
}
kbd_interval = 0;
}
}
+ /* find the vty to update */
+ scp = sc->cur_scp;
+
/* should we stop the screen saver? */
getmicrouptime(&tv);
- if (panicstr || shutdown_in_progress)
+ if (debugger || panicstr || shutdown_in_progress)
sc_touch_scrn_saver();
if (run_scrn_saver) {
- scrn_idle = (tv.tv_sec > scrn_time_stamp + scrn_blank_time);
+ if (tv.tv_sec > sc->scrn_time_stamp + scrn_blank_time)
+ sc->flags |= SC_SCRN_IDLE;
+ else
+ sc->flags &= ~SC_SCRN_IDLE;
} else {
- scrn_time_stamp = tv.tv_sec;
- scrn_idle = FALSE;
+ sc->scrn_time_stamp = tv.tv_sec;
+ sc->flags &= ~SC_SCRN_IDLE;
if (scrn_blank_time > 0)
run_scrn_saver = TRUE;
}
- if ((saver_mode != CONS_LKM_SAVER) || !scrn_idle)
- if (scrn_blanked)
- stop_scrn_saver(current_saver);
+#if NSPLASH > 0
+ if ((saver_mode != CONS_LKM_SAVER) || !(sc->flags & SC_SCRN_IDLE))
+ if (sc->flags & SC_SCRN_BLANKED)
+ stop_scrn_saver(sc, current_saver);
+#endif /* NSPLASH */
/* should we just return ? */
- if (blink_in_progress || switch_in_progress) {
- if (arg)
- timeout(scrn_timer, (void *)TRUE, hz / 10);
+ if (sc->blink_in_progress || sc->switch_in_progress
+ || sc->write_in_progress) {
+ if (again)
+ timeout(scrn_timer, sc, hz / 10);
splx(s);
return;
}
/* Update the screen */
- scp = cur_console;
+ scp = sc->cur_scp; /* cur_scp may have changed... */
if (!ISGRAPHSC(scp) && !(scp->status & SAVER_RUNNING))
scrn_update(scp, TRUE);
+#if NSPLASH > 0
/* should we activate the screen saver? */
- if ((saver_mode == CONS_LKM_SAVER) && scrn_idle)
- if (!ISGRAPHSC(scp) || scrn_blanked)
- (*current_saver)(TRUE);
+ if ((saver_mode == CONS_LKM_SAVER) && (sc->flags & SC_SCRN_IDLE))
+ if (!ISGRAPHSC(scp) || (sc->flags & SC_SCRN_BLANKED))
+ (*current_saver)(sc, TRUE);
+#endif /* NSPLASH */
- if (arg)
- timeout(scrn_timer, (void *)TRUE, hz / 25);
+ if (again)
+ timeout(scrn_timer, sc, hz / 25);
splx(s);
}
+static int
+and_region(int *s1, int *e1, int s2, int e2)
+{
+ if (*e1 < s2 || e2 < *s1)
+ return FALSE;
+ *s1 = imax(*s1, s2);
+ *e1 = imin(*e1, e2);
+ return TRUE;
+}
+
static void
scrn_update(scr_stat *scp, int show_cursor)
{
+ int start;
+ int end;
+ int s;
+ int e;
+
+ /* assert(scp == scp->sc->cur_scp) */
+
+ ++scp->sc->videoio_in_progress;
+
+#ifndef SC_NO_CUTPASTE
+ /* remove the previous mouse pointer image if necessary */
+ if ((scp->status & (MOUSE_VISIBLE | MOUSE_MOVED))
+ == (MOUSE_VISIBLE | MOUSE_MOVED)) {
+ /* FIXME: I don't like this... XXX */
+ sc_remove_mouse_image(scp);
+ if (scp->end >= scp->xsize*scp->ysize)
+ scp->end = scp->xsize*scp->ysize - 1;
+ }
+#endif /* !SC_NO_CUTPASTE */
+
+#if 1
+ /* debug: XXX */
+ if (scp->end >= scp->xsize*scp->ysize) {
+ printf("scrn_update(): scp->end %d > size_of_screen!!\n", scp->end);
+ scp->end = scp->xsize*scp->ysize - 1;
+ }
+ if (scp->start < 0) {
+ printf("scrn_update(): scp->start %d < 0\n", scp->start);
+ scp->start = 0;
+ }
+#endif
+
/* update screen image */
- if (scp->start <= scp->end)
- sc_bcopy(scp, scp->scr_buf, scp->start, scp->end, 0);
+ if (scp->start <= scp->end) {
+ if (scp->mouse_cut_end >= 0) {
+ /* there is a marked region for cut & paste */
+ if (scp->mouse_cut_start <= scp->mouse_cut_end) {
+ start = scp->mouse_cut_start;
+ end = scp->mouse_cut_end;
+ } else {
+ start = scp->mouse_cut_end;
+ end = scp->mouse_cut_start - 1;
+ }
+ s = start;
+ e = end;
+ /* does the cut-mark region overlap with the update region? */
+ if (and_region(&s, &e, scp->start, scp->end)) {
+ (*scp->rndr->draw)(scp, s, e - s + 1, TRUE);
+ s = 0;
+ e = start - 1;
+ if (and_region(&s, &e, scp->start, scp->end))
+ (*scp->rndr->draw)(scp, s, e - s + 1, FALSE);
+ s = end + 1;
+ e = scp->xsize*scp->ysize - 1;
+ if (and_region(&s, &e, scp->start, scp->end))
+ (*scp->rndr->draw)(scp, s, e - s + 1, FALSE);
+ } else {
+ (*scp->rndr->draw)(scp, scp->start,
+ scp->end - scp->start + 1, FALSE);
+ }
+ } else {
+ (*scp->rndr->draw)(scp, scp->start,
+ scp->end - scp->start + 1, FALSE);
+ }
+ }
/* we are not to show the cursor and the mouse pointer... */
if (!show_cursor) {
scp->end = 0;
scp->start = scp->xsize*scp->ysize - 1;
+ --scp->sc->videoio_in_progress;
return;
}
- /* update "pseudo" mouse pointer image */
- if (scp->status & MOUSE_VISIBLE) {
- /* did mouse move since last time ? */
- if (scp->status & MOUSE_MOVED) {
- /* do we need to remove old mouse pointer image ? */
- if (scp->mouse_cut_start != NULL ||
- (scp->mouse_pos-scp->scr_buf) <= scp->start ||
- (scp->mouse_pos+scp->xsize + 1 - scp->scr_buf) >= scp->end) {
- remove_mouse_image(scp);
- }
- scp->status &= ~MOUSE_MOVED;
- draw_mouse_image(scp);
- }
- else {
- /* mouse didn't move, has it been overwritten ? */
- if ((scp->mouse_pos+scp->xsize + 1 - scp->scr_buf) >= scp->start &&
- (scp->mouse_pos - scp->scr_buf) <= scp->end) {
- draw_mouse_image(scp);
- }
- }
- }
-
/* update cursor image */
if (scp->status & CURSOR_ENABLED) {
/* did cursor move since last time ? */
if (scp->cursor_pos != scp->cursor_oldpos) {
/* do we need to remove old cursor image ? */
- if ((scp->cursor_oldpos - scp->scr_buf) < scp->start ||
- ((scp->cursor_oldpos - scp->scr_buf) > scp->end)) {
+ if (scp->cursor_oldpos < scp->start ||
+ scp->cursor_oldpos > scp->end) {
remove_cursor_image(scp);
}
scp->cursor_oldpos = scp->cursor_pos;
@@ -2213,40 +1828,64 @@ scrn_update(scr_stat *scp, int show_cursor)
}
else {
/* cursor didn't move, has it been overwritten ? */
- if (scp->cursor_pos - scp->scr_buf >= scp->start &&
- scp->cursor_pos - scp->scr_buf <= scp->end) {
+ if (scp->cursor_pos >= scp->start && scp->cursor_pos <= scp->end) {
draw_cursor_image(scp);
} else {
/* if its a blinking cursor, we may have to update it */
- if (sc_flags & BLINK_CURSOR)
- draw_cursor_image(scp);
+ if (scp->sc->flags & SC_BLINK_CURSOR)
+ (*scp->rndr->blink_cursor)(scp, scp->cursor_pos,
+ sc_inside_cutmark(scp,
+ scp->cursor_pos));
}
}
- blinkrate++;
}
- if (scp->mouse_cut_start != NULL)
- draw_cutmarking(scp);
+#ifndef SC_NO_CUTPASTE
+ /* update "pseudo" mouse pointer image */
+ if (scp->status & MOUSE_VISIBLE) {
+ /* did mouse move since last time ? */
+ if (scp->status & MOUSE_MOVED) {
+ /* the previous pointer image has been removed, see above */
+ scp->status &= ~MOUSE_MOVED;
+ sc_draw_mouse_image(scp);
+ } else {
+ /* mouse didn't move, has it been overwritten ? */
+ if (scp->mouse_pos + scp->xsize + 1 >= scp->start &&
+ scp->mouse_pos <= scp->end) {
+ sc_draw_mouse_image(scp);
+ } else if (scp->cursor_pos == scp->mouse_pos ||
+ scp->cursor_pos == scp->mouse_pos + 1 ||
+ scp->cursor_pos == scp->mouse_pos + scp->xsize ||
+ scp->cursor_pos == scp->mouse_pos + scp->xsize + 1) {
+ sc_draw_mouse_image(scp);
+ }
+ }
+ }
+#endif /* SC_NO_CUTPASTE */
scp->end = 0;
scp->start = scp->xsize*scp->ysize - 1;
+
+ --scp->sc->videoio_in_progress;
}
#if NSPLASH > 0
-
static int
-scsplash_callback(int event)
+scsplash_callback(int event, void *arg)
{
+ sc_softc_t *sc;
int error;
+ sc = (sc_softc_t *)arg;
+
switch (event) {
case SPLASH_INIT:
- scrn_saver_failed = FALSE;
if (add_scrn_saver(scsplash_saver) == 0) {
+ sc->flags &= ~SC_SAVER_FAILED;
run_scrn_saver = TRUE;
if (cold && !(boothowto & (RB_VERBOSE | RB_CONFIG))) {
scsplash_stick(TRUE);
- (*current_saver)(TRUE);
+ (*current_saver)(sc, TRUE);
}
}
return 0;
@@ -2266,7 +1905,7 @@ scsplash_callback(int event)
}
static void
-scsplash_saver(int show)
+scsplash_saver(sc_softc_t *sc, int show)
{
static int busy = FALSE;
scr_stat *scp;
@@ -2275,38 +1914,37 @@ scsplash_saver(int show)
return;
busy = TRUE;
- scp = cur_console;
+ scp = sc->cur_scp;
if (show) {
- if (!scrn_saver_failed) {
- if (!scrn_blanked)
+ if (!(sc->flags & SC_SAVER_FAILED)) {
+ if (!(sc->flags & SC_SCRN_BLANKED))
set_scrn_saver_mode(scp, -1, NULL, 0);
- switch (splash(scp->adp, TRUE)) {
+ switch (splash(sc->adp, TRUE)) {
case 0: /* succeeded */
- scrn_blanked = TRUE;
break;
case EAGAIN: /* try later */
restore_scrn_saver_mode(scp, FALSE);
+ sc_touch_scrn_saver(); /* XXX */
break;
default:
- scrn_saver_failed = TRUE;
+ sc->flags |= SC_SAVER_FAILED;
scsplash_stick(FALSE);
- printf("scsplash_saver(): failed to put up the image\n");
restore_scrn_saver_mode(scp, TRUE);
+ printf("scsplash_saver(): failed to put up the image\n");
break;
}
}
} else if (!sticky_splash) {
- if (scrn_blanked && (splash(scp->adp, FALSE) == 0)) {
+ if ((sc->flags & SC_SCRN_BLANKED) && (splash(sc->adp, FALSE) == 0))
restore_scrn_saver_mode(scp, TRUE);
- scrn_blanked = FALSE;
- }
}
busy = FALSE;
}
static int
-add_scrn_saver(void (*this_saver)(int))
+add_scrn_saver(void (*this_saver)(sc_softc_t *, int))
{
+#if 0
int error;
if (current_saver != none_saver) {
@@ -2314,6 +1952,9 @@ add_scrn_saver(void (*this_saver)(int))
if (error)
return error;
}
+#endif
+ if (current_saver != none_saver)
+ return EBUSY;
run_scrn_saver = FALSE;
saver_mode = CONS_LKM_SAVER;
@@ -2322,11 +1963,12 @@ add_scrn_saver(void (*this_saver)(int))
}
static int
-remove_scrn_saver(void (*this_saver)(int))
+remove_scrn_saver(void (*this_saver)(sc_softc_t *, int))
{
if (current_saver != this_saver)
return EINVAL;
+#if 0
/*
* In order to prevent `current_saver' from being called by
* the timeout routine `scrn_timer()' while we manipulate
@@ -2336,8 +1978,15 @@ remove_scrn_saver(void (*this_saver)(int))
current_saver = none_saver;
if (scrn_blanked)
stop_scrn_saver(this_saver);
+#endif
+
+ /* unblank all blanked screens */
+ wait_scrn_saver_stop(NULL);
+ if (scrn_blanked)
+ return EBUSY;
- return (scrn_blanked ? EBUSY : 0);
+ current_saver = none_saver;
+ return 0;
}
static int
@@ -2345,21 +1994,27 @@ set_scrn_saver_mode(scr_stat *scp, int mode, u_char *pal, int border)
{
int s;
- /* assert(scp == cur_console) */
+ /* assert(scp == scp->sc->cur_scp) */
s = spltty();
+ if (!ISGRAPHSC(scp))
+ remove_cursor_image(scp);
scp->splash_save_mode = scp->mode;
scp->splash_save_status = scp->status & (GRAPHICS_MODE | PIXEL_MODE);
scp->status &= ~(GRAPHICS_MODE | PIXEL_MODE);
scp->status |= (UNKNOWN_MODE | SAVER_RUNNING);
+ scp->sc->flags |= SC_SCRN_BLANKED;
+ ++scrn_blanked;
splx(s);
if (mode < 0)
return 0;
scp->mode = mode;
if (set_mode(scp) == 0) {
- if (scp->adp->va_info.vi_flags & V_INFO_GRAPHICS)
+ if (scp->sc->adp->va_info.vi_flags & V_INFO_GRAPHICS)
scp->status |= GRAPHICS_MODE;
+#ifndef SC_NO_PALETTE_LOADING
if (pal != NULL)
- load_palette(scp->adp, pal);
+ load_palette(scp->sc->adp, pal);
+#endif
set_border(scp, border);
return 0;
} else {
@@ -2379,19 +2034,26 @@ restore_scrn_saver_mode(scr_stat *scp, int changemode)
int status;
int s;
- /* assert(scp == cur_console) */
+ /* assert(scp == scp->sc->cur_scp) */
s = spltty();
mode = scp->mode;
status = scp->status;
scp->mode = scp->splash_save_mode;
scp->status &= ~(UNKNOWN_MODE | SAVER_RUNNING);
scp->status |= scp->splash_save_status;
+ scp->sc->flags &= ~SC_SCRN_BLANKED;
if (!changemode) {
+ if (!ISGRAPHSC(scp))
+ draw_cursor_image(scp);
+ --scrn_blanked;
splx(s);
return 0;
}
if (set_mode(scp) == 0) {
- load_palette(scp->adp, palette);
+#ifndef SC_NO_PALETTE_LOADING
+ load_palette(scp->sc->adp, scp->sc->palette);
+#endif
+ --scrn_blanked;
splx(s);
return 0;
} else {
@@ -2403,35 +2065,38 @@ restore_scrn_saver_mode(scr_stat *scp, int changemode)
}
static void
-stop_scrn_saver(void (*saver)(int))
+stop_scrn_saver(sc_softc_t *sc, void (*saver)(sc_softc_t *, int))
{
- (*saver)(FALSE);
+ (*saver)(sc, FALSE);
run_scrn_saver = FALSE;
/* the screen saver may have chosen not to stop after all... */
- if (scrn_blanked)
+ if (sc->flags & SC_SCRN_BLANKED)
return;
- mark_all(cur_console);
- if (delayed_next_scr)
- switch_scr(cur_console, delayed_next_scr - 1);
+ mark_all(sc->cur_scp);
+ if (sc->delayed_next_scr)
+ switch_scr(sc, sc->delayed_next_scr - 1);
wakeup((caddr_t)&scrn_blanked);
}
static int
-wait_scrn_saver_stop(void)
+wait_scrn_saver_stop(sc_softc_t *sc)
{
int error = 0;
- while (scrn_blanked) {
+ while (scrn_blanked > 0) {
run_scrn_saver = FALSE;
+ if (sc && !(sc->flags & SC_SCRN_BLANKED)) {
+ error = 0;
+ break;
+ }
error = tsleep((caddr_t)&scrn_blanked, PZERO | PCATCH, "scrsav", 0);
- run_scrn_saver = FALSE;
- if (error != ERESTART)
+ if ((error != 0) && (error != ERESTART))
break;
}
+ run_scrn_saver = FALSE;
return error;
}
-
#endif /* NSPLASH */
void
@@ -2446,99 +2111,297 @@ sc_clear_screen(scr_stat *scp)
{
move_crsr(scp, 0, 0);
scp->cursor_oldpos = scp->cursor_pos;
- fillw(scp->term.cur_color | scr_map[0x20], scp->scr_buf,
- scp->xsize * scp->ysize);
+ sc_vtb_clear(&scp->vtb, scp->sc->scr_map[0x20], scp->term.cur_color);
mark_all(scp);
- remove_cutmarking(scp);
+ sc_remove_cutmarking(scp);
}
static int
-switch_scr(scr_stat *scp, u_int next_scr)
+switch_scr(sc_softc_t *sc, u_int next_scr)
{
- /* delay switch if actively updating screen */
- if (scrn_blanked || write_in_progress || blink_in_progress) {
- delayed_next_scr = next_scr+1;
+ struct tty *tp;
+ int s;
+
+ DPRINTF(5, ("sc0: switch_scr() %d ", next_scr + 1));
+
+ /* delay switch if the screen is blanked or being updated */
+ if ((sc->flags & SC_SCRN_BLANKED) || sc->write_in_progress
+ || sc->blink_in_progress || sc->videoio_in_progress) {
+ sc->delayed_next_scr = next_scr + 1;
sc_touch_scrn_saver();
+ DPRINTF(5, ("switch delayed\n"));
return 0;
}
- if (switch_in_progress && (cur_console->proc != pfind(cur_console->pid)))
- switch_in_progress = FALSE;
+ s = spltty();
- if (next_scr >= MAXCONS || switch_in_progress ||
- (cur_console->smode.mode == VT_AUTO && ISGRAPHSC(cur_console))) {
- do_bell(scp, BELL_PITCH, BELL_DURATION);
+ /* we are in the middle of the vty switching process... */
+ if (sc->switch_in_progress
+ && (sc->cur_scp->smode.mode == VT_PROCESS)
+ && sc->cur_scp->proc) {
+ if (sc->cur_scp->proc != pfind(sc->cur_scp->pid)) {
+ /*
+ * The controlling process has died!!. Do some clean up.
+ * NOTE:`cur_scp->proc' and `cur_scp->smode.mode'
+ * are not reset here yet; they will be cleared later.
+ */
+ DPRINTF(5, ("cur_scp controlling process %d died, ",
+ sc->cur_scp->pid));
+ if (sc->cur_scp->status & SWITCH_WAIT_REL) {
+ /*
+ * Force the previous switch to finish, but return now
+ * with error.
+ */
+ DPRINTF(5, ("reset WAIT_REL, "));
+ sc->cur_scp->status &= ~SWITCH_WAIT_REL;
+ s = do_switch_scr(sc, s);
+ splx(s);
+ DPRINTF(5, ("finishing previous switch\n"));
+ return EINVAL;
+ } else if (sc->cur_scp->status & SWITCH_WAIT_ACQ) {
+ /* let's assume screen switch has been completed. */
+ DPRINTF(5, ("reset WAIT_ACQ, "));
+ sc->cur_scp->status &= ~SWITCH_WAIT_ACQ;
+ sc->switch_in_progress = 0;
+ } else {
+ /*
+ * We are in between screen release and acquisition, and
+ * reached here via scgetc() or scrn_timer() which has
+ * interrupted exchange_scr(). Don't do anything stupid.
+ */
+ DPRINTF(5, ("waiting nothing, "));
+ }
+ } else {
+ /*
+ * The controlling process is alive, but not responding...
+ * It is either buggy or it may be just taking time.
+ * The following code is a gross kludge to cope with this
+ * problem for which there is no clean solution. XXX
+ */
+ if (sc->cur_scp->status & SWITCH_WAIT_REL) {
+ switch (sc->switch_in_progress++) {
+ case 1:
+ break;
+ case 2:
+ DPRINTF(5, ("sending relsig again, "));
+ signal_vt_rel(sc->cur_scp);
+ break;
+ case 3:
+ break;
+ case 4:
+ default:
+ /*
+ * Clear the flag and force the previous switch to finish,
+ * but return now with error.
+ */
+ DPRINTF(5, ("force reset WAIT_REL, "));
+ sc->cur_scp->status &= ~SWITCH_WAIT_REL;
+ s = do_switch_scr(sc, s);
+ splx(s);
+ DPRINTF(5, ("force finishing previous switch\n"));
+ return EINVAL;
+ }
+ } else if (sc->cur_scp->status & SWITCH_WAIT_ACQ) {
+ switch (sc->switch_in_progress++) {
+ case 1:
+ break;
+ case 2:
+ DPRINTF(5, ("sending acqsig again, "));
+ signal_vt_acq(sc->cur_scp);
+ break;
+ case 3:
+ break;
+ case 4:
+ default:
+ /* clear the flag and finish the previous switch */
+ DPRINTF(5, ("force reset WAIT_ACQ, "));
+ sc->cur_scp->status &= ~SWITCH_WAIT_ACQ;
+ sc->switch_in_progress = 0;
+ break;
+ }
+ }
+ }
+ }
+
+ /*
+ * Return error if an invalid argument is given, or vty switch
+ * is still in progress.
+ */
+ if ((next_scr < sc->first_vty) || (next_scr >= sc->first_vty + sc->vtys)
+ || sc->switch_in_progress) {
+ splx(s);
+ do_bell(sc->cur_scp, bios_value.bell_pitch, BELL_DURATION);
+ DPRINTF(5, ("error 1\n"));
+ return EINVAL;
+ }
+
+ /*
+ * Don't allow switching away from the graphics mode vty
+ * if the switch mode is VT_AUTO, unless the next vty is the same
+ * as the current or the current vty has been closed (but showing).
+ */
+ tp = VIRTUAL_TTY(sc, sc->cur_scp->index);
+ if ((sc->cur_scp->index != next_scr)
+ && (tp->t_state & TS_ISOPEN)
+ && (sc->cur_scp->smode.mode == VT_AUTO)
+ && ISGRAPHSC(sc->cur_scp)) {
+ splx(s);
+ do_bell(sc->cur_scp, bios_value.bell_pitch, BELL_DURATION);
+ DPRINTF(5, ("error, graphics mode\n"));
return EINVAL;
}
- /* is the wanted virtual console open ? */
- if (next_scr) {
- struct tty *tp = VIRTUAL_TTY(next_scr);
+ /*
+ * Is the wanted vty open? Don't allow switching to a closed vty.
+ * Note that we always allow the user to switch to the kernel
+ * console even if it is closed.
+ */
+ if ((sc_console == NULL) || (next_scr != sc_console->index)) {
+ tp = VIRTUAL_TTY(sc, next_scr);
if (!(tp->t_state & TS_ISOPEN)) {
- do_bell(scp, BELL_PITCH, BELL_DURATION);
+ splx(s);
+ do_bell(sc->cur_scp, bios_value.bell_pitch, BELL_DURATION);
+ DPRINTF(5, ("error 2, requested vty isn't open!\n"));
return EINVAL;
}
}
- switch_in_progress = TRUE;
- old_scp = cur_console;
- new_scp = console[next_scr];
- wakeup((caddr_t)&new_scp->smode);
- if (new_scp == old_scp) {
- switch_in_progress = FALSE;
- delayed_next_scr = FALSE;
+ /* this is the start of vty switching process... */
+ ++sc->switch_in_progress;
+ sc->delayed_next_scr = 0;
+ sc->old_scp = sc->cur_scp;
+ sc->new_scp = sc->console[next_scr - sc->first_vty];
+ if (sc->new_scp == sc->old_scp) {
+ sc->switch_in_progress = 0;
+ wakeup((caddr_t)&sc->new_scp->smode);
+ splx(s);
+ DPRINTF(5, ("switch done (new == old)\n"));
return 0;
}
/* has controlling process died? */
- if (old_scp->proc && (old_scp->proc != pfind(old_scp->pid)))
- old_scp->smode.mode = VT_AUTO;
- if (new_scp->proc && (new_scp->proc != pfind(new_scp->pid)))
- new_scp->smode.mode = VT_AUTO;
-
- /* check the modes and switch appropriately */
- if (old_scp->smode.mode == VT_PROCESS) {
- old_scp->status |= SWITCH_WAIT_REL;
- psignal(old_scp->proc, old_scp->smode.relsig);
+ vt_proc_alive(sc->old_scp);
+ vt_proc_alive(sc->new_scp);
+
+ /* wait for the controlling process to release the screen, if necessary */
+ if (signal_vt_rel(sc->old_scp)) {
+ splx(s);
+ return 0;
}
- else {
- exchange_scr();
- if (new_scp->smode.mode == VT_PROCESS) {
- new_scp->status |= SWITCH_WAIT_ACQ;
- psignal(new_scp->proc, new_scp->smode.acqsig);
- }
- else
- switch_in_progress = FALSE;
+
+ /* go set up the new vty screen */
+ splx(s);
+ exchange_scr(sc);
+ s = spltty();
+
+ /* wake up processes waiting for this vty */
+ wakeup((caddr_t)&sc->cur_scp->smode);
+
+ /* wait for the controlling process to acknowledge, if necessary */
+ if (signal_vt_acq(sc->cur_scp)) {
+ splx(s);
+ return 0;
}
+
+ sc->switch_in_progress = 0;
+ if (sc->unit == sc_console_unit)
+ cons_unavail = FALSE;
+ splx(s);
+ DPRINTF(5, ("switch done\n"));
+
return 0;
}
+static int
+do_switch_scr(sc_softc_t *sc, int s)
+{
+ vt_proc_alive(sc->new_scp);
+
+ splx(s);
+ exchange_scr(sc);
+ s = spltty();
+ /* sc->cur_scp == sc->new_scp */
+ wakeup((caddr_t)&sc->cur_scp->smode);
+
+ /* wait for the controlling process to acknowledge, if necessary */
+ if (!signal_vt_acq(sc->cur_scp)) {
+ sc->switch_in_progress = 0;
+ if (sc->unit == sc_console_unit)
+ cons_unavail = FALSE;
+ }
+
+ return s;
+}
+
+static int
+vt_proc_alive(scr_stat *scp)
+{
+ if (scp->proc) {
+ if (scp->proc == pfind(scp->pid))
+ return TRUE;
+ scp->proc = NULL;
+ scp->smode.mode = VT_AUTO;
+ DPRINTF(5, ("vt controlling process %d died\n", scp->pid));
+ }
+ return FALSE;
+}
+
+static int
+signal_vt_rel(scr_stat *scp)
+{
+ if (scp->smode.mode != VT_PROCESS)
+ return FALSE;
+ scp->status |= SWITCH_WAIT_REL;
+ psignal(scp->proc, scp->smode.relsig);
+ DPRINTF(5, ("sending relsig to %d\n", scp->pid));
+ return TRUE;
+}
+
+static int
+signal_vt_acq(scr_stat *scp)
+{
+ if (scp->smode.mode != VT_PROCESS)
+ return FALSE;
+ if (scp->sc->unit == sc_console_unit)
+ cons_unavail = TRUE;
+ scp->status |= SWITCH_WAIT_ACQ;
+ psignal(scp->proc, scp->smode.acqsig);
+ DPRINTF(5, ("sending acqsig to %d\n", scp->pid));
+ return TRUE;
+}
+
static void
-exchange_scr(void)
+exchange_scr(sc_softc_t *sc)
{
+ scr_stat *scp;
+
/* save the current state of video and keyboard */
- move_crsr(old_scp, old_scp->xpos, old_scp->ypos);
- if (old_scp->kbd_mode == K_XLATE)
- save_kbd_state(old_scp);
+ move_crsr(sc->old_scp, sc->old_scp->xpos, sc->old_scp->ypos);
+ if (sc->old_scp->kbd_mode == K_XLATE)
+ save_kbd_state(sc->old_scp);
/* set up the video for the new screen */
- cur_console = new_scp;
- if (old_scp->mode != new_scp->mode || ISUNKNOWNSC(old_scp))
- set_mode(new_scp);
- move_crsr(new_scp, new_scp->xpos, new_scp->ypos);
- if (ISTEXTSC(new_scp) && (sc_flags & CHAR_CURSOR))
- set_destructive_cursor(new_scp);
- if (ISGRAPHSC(old_scp))
- load_palette(new_scp->adp, palette);
- set_border(new_scp, new_scp->border);
+ scp = sc->cur_scp = sc->new_scp;
+ if (sc->old_scp->mode != scp->mode || ISUNKNOWNSC(sc->old_scp))
+ set_mode(scp);
+ else
+ sc_vtb_init(&scp->scr, VTB_FRAMEBUFFER, scp->xsize, scp->ysize,
+ (void *)sc->adp->va_window, FALSE);
+ move_crsr(scp, scp->xpos, scp->ypos);
+ if (!ISGRAPHSC(scp))
+ sc_set_cursor_image(scp);
+#ifndef SC_NO_PALETTE_LOADING
+ if (ISGRAPHSC(sc->old_scp))
+ load_palette(sc->adp, sc->palette);
+#endif
+ set_border(scp, scp->border);
/* set up the keyboard for the new screen */
- if (old_scp->kbd_mode != new_scp->kbd_mode)
- kbd_ioctl(kbd, KDSKBMODE, (caddr_t)&new_scp->kbd_mode);
- update_kbd_state(new_scp->status, LOCK_MASK);
+ if (sc->old_scp->kbd_mode != scp->kbd_mode)
+ kbd_ioctl(sc->kbd, KDSKBMODE, (caddr_t)&scp->kbd_mode);
+ update_kbd_state(scp, scp->status, LOCK_MASK);
- delayed_next_scr = FALSE;
- mark_all(new_scp);
+ mark_all(scp);
}
static void
@@ -2546,9 +2409,11 @@ scan_esc(scr_stat *scp, u_char c)
{
static u_char ansi_col[16] =
{0, 4, 2, 6, 1, 5, 3, 7, 8, 12, 10, 14, 9, 13, 11, 15};
+ sc_softc_t *sc;
int i, n;
- u_short *src, *dst, count;
+ int count;
+ sc = scp->sc;
if (scp->term.esc == 1) { /* seen ESC */
switch (c) {
@@ -2574,10 +2439,8 @@ scan_esc(scr_stat *scp, u_char c)
if (scp->ypos > 0)
move_crsr(scp, scp->xpos, scp->ypos - 1);
else {
- bcopy(scp->scr_buf, scp->scr_buf + scp->xsize,
- (scp->ysize - 1) * scp->xsize * sizeof(u_short));
- fillw(scp->term.cur_color | scr_map[0x20],
- scp->scr_buf, scp->xsize);
+ sc_vtb_ins(&scp->vtb, 0, scp->xsize,
+ sc->scr_map[0x20], scp->term.cur_color);
mark_all(scp);
}
break;
@@ -2669,26 +2532,24 @@ scan_esc(scr_stat *scp, u_char c)
n = scp->term.param[0];
switch (n) {
case 0: /* clear form cursor to end of display */
- fillw(scp->term.cur_color | scr_map[0x20],
- scp->cursor_pos,
- scp->scr_buf + scp->xsize * scp->ysize - scp->cursor_pos);
- mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
+ sc_vtb_erase(&scp->vtb, scp->cursor_pos,
+ scp->xsize * scp->ysize - scp->cursor_pos,
+ sc->scr_map[0x20], scp->term.cur_color);
+ mark_for_update(scp, scp->cursor_pos);
mark_for_update(scp, scp->xsize * scp->ysize - 1);
- remove_cutmarking(scp);
+ sc_remove_cutmarking(scp);
break;
case 1: /* clear from beginning of display to cursor */
- fillw(scp->term.cur_color | scr_map[0x20],
- scp->scr_buf,
- scp->cursor_pos - scp->scr_buf);
- mark_for_update(scp, 0);
- mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
- remove_cutmarking(scp);
+ sc_vtb_erase(&scp->vtb, 0, scp->cursor_pos,
+ sc->scr_map[0x20], scp->term.cur_color);
+ mark_for_update(scp, 0);
+ mark_for_update(scp, scp->cursor_pos);
+ sc_remove_cutmarking(scp);
break;
case 2: /* clear entire display */
- fillw(scp->term.cur_color | scr_map[0x20], scp->scr_buf,
- scp->xsize * scp->ysize);
+ sc_vtb_clear(&scp->vtb, sc->scr_map[0x20], scp->term.cur_color);
mark_all(scp);
- remove_cutmarking(scp);
+ sc_remove_cutmarking(scp);
break;
}
break;
@@ -2700,24 +2561,24 @@ scan_esc(scr_stat *scp, u_char c)
n = scp->term.param[0];
switch (n) {
case 0: /* clear form cursor to end of line */
- fillw(scp->term.cur_color | scr_map[0x20],
- scp->cursor_pos,
- scp->xsize - scp->xpos);
- mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
- mark_for_update(scp, scp->cursor_pos - scp->scr_buf +
+ sc_vtb_erase(&scp->vtb, scp->cursor_pos,
+ scp->xsize - scp->xpos,
+ sc->scr_map[0x20], scp->term.cur_color);
+ mark_for_update(scp, scp->cursor_pos);
+ mark_for_update(scp, scp->cursor_pos +
scp->xsize - 1 - scp->xpos);
break;
case 1: /* clear from beginning of line to cursor */
- fillw(scp->term.cur_color | scr_map[0x20],
- scp->cursor_pos - scp->xpos,
- scp->xpos + 1);
+ sc_vtb_erase(&scp->vtb, scp->cursor_pos - scp->xpos,
+ scp->xpos + 1,
+ sc->scr_map[0x20], scp->term.cur_color);
mark_for_update(scp, scp->ypos * scp->xsize);
- mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
+ mark_for_update(scp, scp->cursor_pos);
break;
case 2: /* clear entire line */
- fillw(scp->term.cur_color | scr_map[0x20],
- scp->cursor_pos - scp->xpos,
- scp->xsize);
+ sc_vtb_erase(&scp->vtb, scp->cursor_pos - scp->xpos,
+ scp->xsize,
+ sc->scr_map[0x20], scp->term.cur_color);
mark_for_update(scp, scp->ypos * scp->xsize);
mark_for_update(scp, (scp->ypos + 1) * scp->xsize - 1);
break;
@@ -2728,12 +2589,8 @@ scan_esc(scr_stat *scp, u_char c)
n = scp->term.param[0]; if (n < 1) n = 1;
if (n > scp->ysize - scp->ypos)
n = scp->ysize - scp->ypos;
- src = scp->scr_buf + scp->ypos * scp->xsize;
- dst = src + n * scp->xsize;
- count = scp->ysize - (scp->ypos + n);
- bcopy(src, dst, count * scp->xsize * sizeof(u_short));
- fillw(scp->term.cur_color | scr_map[0x20], src,
- n * scp->xsize);
+ sc_vtb_ins(&scp->vtb, scp->ypos * scp->xsize, n * scp->xsize,
+ sc->scr_map[0x20], scp->term.cur_color);
mark_for_update(scp, scp->ypos * scp->xsize);
mark_for_update(scp, scp->xsize * scp->ysize - 1);
break;
@@ -2742,13 +2599,8 @@ scan_esc(scr_stat *scp, u_char c)
n = scp->term.param[0]; if (n < 1) n = 1;
if (n > scp->ysize - scp->ypos)
n = scp->ysize - scp->ypos;
- dst = scp->scr_buf + scp->ypos * scp->xsize;
- src = dst + n * scp->xsize;
- count = scp->ysize - (scp->ypos + n);
- bcopy(src, dst, count * scp->xsize * sizeof(u_short));
- src = dst + count * scp->xsize;
- fillw(scp->term.cur_color | scr_map[0x20], src,
- n * scp->xsize);
+ sc_vtb_delete(&scp->vtb, scp->ypos * scp->xsize, n * scp->xsize,
+ sc->scr_map[0x20], scp->term.cur_color);
mark_for_update(scp, scp->ypos * scp->xsize);
mark_for_update(scp, scp->xsize * scp->ysize - 1);
break;
@@ -2757,39 +2609,30 @@ scan_esc(scr_stat *scp, u_char c)
n = scp->term.param[0]; if (n < 1) n = 1;
if (n > scp->xsize - scp->xpos)
n = scp->xsize - scp->xpos;
- dst = scp->cursor_pos;
- src = dst + n;
count = scp->xsize - (scp->xpos + n);
- bcopy(src, dst, count * sizeof(u_short));
- src = dst + count;
- fillw(scp->term.cur_color | scr_map[0x20], src, n);
- mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
- mark_for_update(scp, scp->cursor_pos - scp->scr_buf + n + count - 1);
+ sc_vtb_delete(&scp->vtb, scp->cursor_pos, n,
+ sc->scr_map[0x20], scp->term.cur_color);
+ mark_for_update(scp, scp->cursor_pos);
+ mark_for_update(scp, scp->cursor_pos + n + count - 1);
break;
case '@': /* Insert n chars */
n = scp->term.param[0]; if (n < 1) n = 1;
if (n > scp->xsize - scp->xpos)
n = scp->xsize - scp->xpos;
- src = scp->cursor_pos;
- dst = src + n;
count = scp->xsize - (scp->xpos + n);
- bcopy(src, dst, count * sizeof(u_short));
- fillw(scp->term.cur_color | scr_map[0x20], src, n);
- mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
- mark_for_update(scp, scp->cursor_pos - scp->scr_buf + n + count - 1);
+ sc_vtb_ins(&scp->vtb, scp->cursor_pos, n,
+ sc->scr_map[0x20], scp->term.cur_color);
+ mark_for_update(scp, scp->cursor_pos);
+ mark_for_update(scp, scp->cursor_pos + n + count - 1);
break;
case 'S': /* scroll up n lines */
n = scp->term.param[0]; if (n < 1) n = 1;
if (n > scp->ysize)
n = scp->ysize;
- bcopy(scp->scr_buf + (scp->xsize * n),
- scp->scr_buf,
- scp->xsize * (scp->ysize - n) * sizeof(u_short));
- fillw(scp->term.cur_color | scr_map[0x20],
- scp->scr_buf + scp->xsize * (scp->ysize - n),
- scp->xsize * n);
+ sc_vtb_delete(&scp->vtb, 0, n * scp->xsize,
+ sc->scr_map[0x20], scp->term.cur_color);
mark_all(scp);
break;
@@ -2797,12 +2640,8 @@ scan_esc(scr_stat *scp, u_char c)
n = scp->term.param[0]; if (n < 1) n = 1;
if (n > scp->ysize)
n = scp->ysize;
- bcopy(scp->scr_buf,
- scp->scr_buf + (scp->xsize * n),
- scp->xsize * (scp->ysize - n) *
- sizeof(u_short));
- fillw(scp->term.cur_color | scr_map[0x20],
- scp->scr_buf, scp->xsize * n);
+ sc_vtb_ins(&scp->vtb, 0, n * scp->xsize,
+ sc->scr_map[0x20], scp->term.cur_color);
mark_all(scp);
break;
@@ -2810,10 +2649,10 @@ scan_esc(scr_stat *scp, u_char c)
n = scp->term.param[0]; if (n < 1) n = 1;
if (n > scp->xsize - scp->xpos)
n = scp->xsize - scp->xpos;
- fillw(scp->term.cur_color | scr_map[0x20],
- scp->cursor_pos, n);
- mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
- mark_for_update(scp, scp->cursor_pos - scp->scr_buf + n - 1);
+ sc_vtb_erase(&scp->vtb, scp->cursor_pos, n,
+ sc->scr_map[0x20], scp->term.cur_color);
+ mark_for_update(scp, scp->cursor_pos);
+ mark_for_update(scp, scp->cursor_pos + n - 1);
break;
case 'Z': /* move n tabs backwards */
@@ -2962,7 +2801,7 @@ scan_esc(scr_stat *scp, u_char c)
case 'z': /* switch to (virtual) console n */
if (scp->term.num_param == 1)
- switch_scr(scp, scp->term.param[0]);
+ switch_scr(sc, scp->term.param[0]);
break;
}
}
@@ -2990,8 +2829,8 @@ scan_esc(scr_stat *scp, u_char c)
case 'A': /* set display border color */
if (scp->term.num_param == 1) {
scp->border=scp->term.param[0] & 0xff;
- if (scp == cur_console)
- set_border(cur_console, scp->border);
+ if (scp == sc->cur_scp)
+ set_border(scp, scp->border);
}
break;
@@ -3003,31 +2842,32 @@ scan_esc(scr_stat *scp, u_char c)
break;
case 'C': /* set cursor type & shape */
+ if (!ISGRAPHSC(sc->cur_scp))
+ remove_cursor_image(sc->cur_scp);
if (scp->term.num_param == 1) {
if (scp->term.param[0] & 0x01)
- sc_flags |= BLINK_CURSOR;
+ sc->flags |= SC_BLINK_CURSOR;
else
- sc_flags &= ~BLINK_CURSOR;
- if ((scp->term.param[0] & 0x02)
- && ISFONTAVAIL(scp->adp->va_flags))
- sc_flags |= CHAR_CURSOR;
+ sc->flags &= ~SC_BLINK_CURSOR;
+ if (scp->term.param[0] & 0x02)
+ sc->flags |= SC_CHAR_CURSOR;
else
- sc_flags &= ~CHAR_CURSOR;
+ sc->flags &= ~SC_CHAR_CURSOR;
}
else if (scp->term.num_param == 2) {
- scp->cursor_start = scp->term.param[0] & 0x1F;
- scp->cursor_end = scp->term.param[1] & 0x1F;
+ sc->cursor_base = scp->font_size
+ - (scp->term.param[1] & 0x1F) - 1;
+ sc->cursor_height = (scp->term.param[1] & 0x1F)
+ - (scp->term.param[0] & 0x1F) + 1;
}
/*
* The cursor shape is global property; all virtual consoles
* are affected. Update the cursor in the current console...
*/
- if (!ISGRAPHSC(cur_console)) {
+ if (!ISGRAPHSC(sc->cur_scp)) {
i = spltty();
- remove_cursor_image(cur_console);
- if (sc_flags & CHAR_CURSOR)
- set_destructive_cursor(cur_console);
- draw_cursor_image(cur_console);
+ sc_set_cursor_image(sc->cur_scp);
+ draw_cursor_image(sc->cur_scp);
splx(i);
}
break;
@@ -3094,19 +2934,28 @@ ansi_put(scr_stat *scp, u_char *buf, int len)
u_char *ptr = buf;
/* make screensaver happy */
- if (!sticky_splash && scp == cur_console)
+ if (!sticky_splash && scp == scp->sc->cur_scp)
run_scrn_saver = FALSE;
- write_in_progress++;
outloop:
+ scp->sc->write_in_progress++;
if (scp->term.esc) {
scan_esc(scp, *ptr++);
len--;
}
else if (PRINTABLE(*ptr)) { /* Print only printables */
- int cnt = len <= (scp->xsize-scp->xpos) ? len : (scp->xsize-scp->xpos);
- u_short cur_attr = scp->term.cur_attr;
- u_short *cursor_pos = scp->cursor_pos;
+ vm_offset_t p;
+ u_char *map;
+ int cnt;
+ int attr;
+ int i;
+
+ p = sc_vtb_pointer(&scp->vtb, scp->cursor_pos);
+ map = scp->sc->scr_map;
+ attr = scp->term.cur_attr;
+
+ cnt = (len <= scp->xsize - scp->xpos) ? len : (scp->xsize - scp->xpos);
+ i = cnt;
do {
/*
* gcc-2.6.3 generates poor (un)sign extension code. Casting the
@@ -3115,15 +2964,17 @@ outloop:
* (+ cache misses) on i486's.
*/
#define UCVP(ucp) ((u_char volatile *)(ucp))
- *cursor_pos++ = UCVP(scr_map)[*UCVP(ptr)] | cur_attr;
- ptr++;
- cnt--;
- } while (cnt && PRINTABLE(*ptr));
- len -= (cursor_pos - scp->cursor_pos);
- scp->xpos += (cursor_pos - scp->cursor_pos);
- mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
- mark_for_update(scp, cursor_pos - scp->scr_buf);
- scp->cursor_pos = cursor_pos;
+ p = sc_vtb_putchar(&scp->vtb, p, UCVP(map)[*UCVP(ptr)], attr);
+ ++ptr;
+ --i;
+ } while (i > 0 && PRINTABLE(*ptr));
+
+ len -= cnt - i;
+ mark_for_update(scp, scp->cursor_pos);
+ scp->cursor_pos += cnt - i;
+ mark_for_update(scp, scp->cursor_pos - 1);
+ scp->xpos += cnt - i;
+
if (scp->xpos >= scp->xsize) {
scp->xpos = 0;
scp->ypos++;
@@ -3136,10 +2987,10 @@ outloop:
break;
case 0x08: /* non-destructive backspace */
- if (scp->cursor_pos > scp->scr_buf) {
- mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
+ if (scp->cursor_pos > 0) {
+ mark_for_update(scp, scp->cursor_pos);
scp->cursor_pos--;
- mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
+ mark_for_update(scp, scp->cursor_pos);
if (scp->xpos > 0)
scp->xpos--;
else {
@@ -3150,9 +3001,9 @@ outloop:
break;
case 0x09: /* non-destructive tab */
- mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
+ mark_for_update(scp, scp->cursor_pos);
scp->cursor_pos += (8 - scp->xpos % 8u);
- mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
+ mark_for_update(scp, scp->cursor_pos);
if ((scp->xpos += (8 - scp->xpos % 8u)) >= scp->xsize) {
scp->xpos = 0;
scp->ypos++;
@@ -3160,9 +3011,9 @@ outloop:
break;
case 0x0a: /* newline, same pos */
- mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
+ mark_for_update(scp, scp->cursor_pos);
scp->cursor_pos += scp->xsize;
- mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
+ mark_for_update(scp, scp->cursor_pos);
scp->ypos++;
break;
@@ -3171,9 +3022,9 @@ outloop:
break;
case 0x0d: /* return, return to pos 0 */
- mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
+ mark_for_update(scp, scp->cursor_pos);
scp->cursor_pos -= scp->xpos;
- mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
+ mark_for_update(scp, scp->cursor_pos);
scp->xpos = 0;
break;
@@ -3185,117 +3036,379 @@ outloop:
ptr++; len--;
}
/* do we have to scroll ?? */
- if (scp->cursor_pos >= scp->scr_buf + scp->ysize * scp->xsize) {
- remove_cutmarking(scp);
- if (scp->history != NULL) {
- bcopy(scp->scr_buf, scp->history_head,
- scp->xsize * sizeof(u_short));
- scp->history_head += scp->xsize;
- if (scp->history_head + scp->xsize >
- scp->history + scp->history_size)
- scp->history_head = scp->history;
- }
- bcopy(scp->scr_buf + scp->xsize, scp->scr_buf,
- scp->xsize * (scp->ysize - 1) * sizeof(u_short));
- fillw(scp->term.cur_color | scr_map[0x20],
- scp->scr_buf + scp->xsize * (scp->ysize - 1),
- scp->xsize);
+ if (scp->cursor_pos >= scp->ysize * scp->xsize) {
+ sc_remove_cutmarking(scp);
+#ifndef SC_NO_HISTORY
+ if (scp->history != NULL)
+ sc_hist_save_one_line(scp, 0);
+#endif
+ sc_vtb_delete(&scp->vtb, 0, scp->xsize,
+ scp->sc->scr_map[0x20], scp->term.cur_color);
scp->cursor_pos -= scp->xsize;
scp->ypos--;
mark_all(scp);
}
+ scp->sc->write_in_progress--;
if (len)
goto outloop;
- write_in_progress--;
- if (delayed_next_scr)
- switch_scr(scp, delayed_next_scr - 1);
+ if (scp->sc->delayed_next_scr)
+ switch_scr(scp->sc, scp->sc->delayed_next_scr - 1);
}
static void
-scinit(void)
+draw_cursor_image(scr_stat *scp)
+{
+ /* assert(scp == scp->sc->cur_scp); */
+ ++scp->sc->videoio_in_progress;
+ (*scp->rndr->draw_cursor)(scp, scp->cursor_pos,
+ scp->sc->flags & SC_BLINK_CURSOR, TRUE,
+ sc_inside_cutmark(scp, scp->cursor_pos));
+ --scp->sc->videoio_in_progress;
+}
+
+static void
+remove_cursor_image(scr_stat *scp)
+{
+ /* assert(scp == scp->sc->cur_scp); */
+ ++scp->sc->videoio_in_progress;
+ (*scp->rndr->draw_cursor)(scp, scp->cursor_oldpos,
+ scp->sc->flags & SC_BLINK_CURSOR, FALSE,
+ sc_inside_cutmark(scp, scp->cursor_oldpos));
+ --scp->sc->videoio_in_progress;
+}
+
+static void
+update_cursor_image(scr_stat *scp)
{
+ int blink;
+
+ if (scp->sc->flags & SC_CHAR_CURSOR) {
+ scp->cursor_base = scp->sc->cursor_base;
+ scp->cursor_height = imin(scp->sc->cursor_height, scp->font_size);
+ } else {
+ scp->cursor_base = 0;
+ scp->cursor_height = scp->font_size;
+ }
+ blink = scp->sc->flags & SC_BLINK_CURSOR;
+
+ /* assert(scp == scp->sc->cur_scp); */
+ ++scp->sc->videoio_in_progress;
+ (*scp->rndr->draw_cursor)(scp, scp->cursor_oldpos, blink, FALSE,
+ sc_inside_cutmark(scp, scp->cursor_pos));
+ (*scp->rndr->set_cursor)(scp, scp->cursor_base, scp->cursor_height, blink);
+ (*scp->rndr->draw_cursor)(scp, scp->cursor_pos, blink, TRUE,
+ sc_inside_cutmark(scp, scp->cursor_pos));
+ --scp->sc->videoio_in_progress;
+}
+
+void
+sc_set_cursor_image(scr_stat *scp)
+{
+ if (scp->sc->flags & SC_CHAR_CURSOR) {
+ scp->cursor_base = scp->sc->cursor_base;
+ scp->cursor_height = imin(scp->sc->cursor_height, scp->font_size);
+ } else {
+ scp->cursor_base = 0;
+ scp->cursor_height = scp->font_size;
+ }
+
+ /* assert(scp == scp->sc->cur_scp); */
+ ++scp->sc->videoio_in_progress;
+ (*scp->rndr->set_cursor)(scp, scp->cursor_base, scp->cursor_height,
+ scp->sc->flags & SC_BLINK_CURSOR);
+ --scp->sc->videoio_in_progress;
+}
+
+static void
+move_crsr(scr_stat *scp, int x, int y)
+{
+ if (x < 0)
+ x = 0;
+ if (y < 0)
+ y = 0;
+ if (x >= scp->xsize)
+ x = scp->xsize-1;
+ if (y >= scp->ysize)
+ y = scp->ysize-1;
+ scp->xpos = x;
+ scp->ypos = y;
+ scp->cursor_pos = scp->ypos * scp->xsize + scp->xpos;
+}
+
+static void
+scinit(int unit, int flags)
+{
+ /*
+ * When syscons is being initialized as the kernel console, malloc()
+ * is not yet functional, because various kernel structures has not been
+ * fully initialized yet. Therefore, we need to declare the following
+ * static buffers for the console. This is less than ideal,
+ * but is necessry evil for the time being. XXX
+ */
+ static scr_stat main_console;
+ static scr_stat *main_vtys[MAXCONS];
+ static struct tty main_tty[MAXCONS];
+ static u_short sc_buffer[ROW*COL]; /* XXX */
+#ifdef DEVFS
+ static void *main_devfs_token[MAXCONS];
+#endif
+#ifndef SC_NO_FONT_LOADING
+ static u_char font_8[256*8];
+ static u_char font_14[256*14];
+ static u_char font_16[256*16];
+#endif
+
+ sc_softc_t *sc;
+ scr_stat *scp;
video_adapter_t *adp;
int col;
int row;
- u_int i;
+ int i;
- if (init_done != COLD)
- return;
+ /* one time initialization */
+ if (init_done == COLD) {
+ sc_get_bios_values(&bios_value);
+ current_default = &user_default;
+ /* kernel console attributes */
+ kernel_console.esc = 0;
+ kernel_console.attr_mask = NORMAL_ATTR;
+ kernel_console.cur_attr =
+ kernel_console.cur_color = kernel_console.std_color =
+ kernel_default.std_color;
+ kernel_console.rev_color = kernel_default.rev_color;
+ }
init_done = WARM;
- get_bios_values();
+ /*
+ * Allocate resources. Even if we are being called for the second
+ * time, we must allocate them again, because they might have
+ * disappeared...
+ */
+ sc = sc_get_softc(unit, flags & SC_KERNEL_CONSOLE);
+ adp = NULL;
+ if (sc->adapter >= 0) {
+ vid_release(sc->adp, (void *)&sc->adapter);
+ adp = sc->adp;
+ sc->adp = NULL;
+ }
+ if (sc->keyboard >= 0) {
+ DPRINTF(5, ("sc%d: releasing kbd%d\n", unit, sc->keyboard));
+ i = kbd_release(sc->kbd, (void *)&sc->keyboard);
+ DPRINTF(5, ("sc%d: kbd_release returned %d\n", unit, i));
+ if (sc->kbd != NULL) {
+ DPRINTF(5, ("sc%d: kbd != NULL!, index:%d, minor:%d, flags:0x%x\n",
+ unit, sc->kbd->kb_index, sc->kbd->kb_minor, sc->kbd->kb_flags));
+ }
+ sc->kbd = NULL;
+ }
+ sc->adapter = vid_allocate("*", unit, (void *)&sc->adapter);
+ sc->adp = vid_get_adapter(sc->adapter);
+ /* assert((sc->adapter >= 0) && (sc->adp != NULL)) */
+ sc->keyboard = kbd_allocate("*", unit, (void *)&sc->keyboard,
+ sckbdevent, sc);
+ DPRINTF(1, ("sc%d: keyboard %d\n", unit, sc->keyboard));
+ sc->kbd = kbd_get_keyboard(sc->keyboard);
+ if (sc->kbd != NULL) {
+ DPRINTF(1, ("sc%d: kbd index:%d, minor:%d, flags:0x%x\n",
+ unit, sc->kbd->kb_index, sc->kbd->kb_minor, sc->kbd->kb_flags));
+ }
+
+ if (!(sc->flags & SC_INIT_DONE) || (adp != sc->adp)) {
+
+ sc->initial_mode = sc->adp->va_initial_mode;
+
+#ifndef SC_NO_FONT_LOADING
+ if (flags & SC_KERNEL_CONSOLE) {
+ sc->font_8 = font_8;
+ sc->font_14 = font_14;
+ sc->font_16 = font_16;
+ } else if (sc->font_8 == NULL) {
+ /* assert(sc_malloc) */
+ sc->font_8 = malloc(sizeof(font_8), M_DEVBUF, M_WAITOK);
+ sc->font_14 = malloc(sizeof(font_14), M_DEVBUF, M_WAITOK);
+ sc->font_16 = malloc(sizeof(font_16), M_DEVBUF, M_WAITOK);
+ }
+#endif
- /* extract the hardware cursor location and hide the cursor for now */
- adp = vid_get_adapter(adapter);
- (*vidsw[adapter]->read_hw_cursor)(adp, &col, &row);
- (*vidsw[adapter]->set_hw_cursor)(adp, -1, -1);
+ /* extract the hardware cursor location and hide the cursor for now */
+ (*vidsw[sc->adapter]->read_hw_cursor)(sc->adp, &col, &row);
+ (*vidsw[sc->adapter]->set_hw_cursor)(sc->adp, -1, -1);
- /* set up the first console */
- current_default = &user_default;
- console[0] = &main_console;
- init_scp(console[0]);
- cur_console = console[0];
-
- /* copy screen to temporary buffer */
- if (ISTEXTSC(console[0]))
- bcopy_fromio(console[0]->adp->va_window, sc_buffer,
- console[0]->xsize * console[0]->ysize * sizeof(u_short));
-
- console[0]->scr_buf = console[0]->mouse_pos = console[0]->mouse_oldpos
- = sc_buffer;
- 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;
- for (i=1; i<MAXCONS; i++)
- console[i] = NULL;
- kernel_console.esc = 0;
- kernel_console.attr_mask = NORMAL_ATTR;
- kernel_console.cur_attr =
- kernel_console.cur_color = kernel_console.std_color =
- kernel_default.std_color;
- kernel_console.rev_color = kernel_default.rev_color;
+ /* set up the first console */
+ sc->first_vty = unit*MAXCONS;
+ if (flags & SC_KERNEL_CONSOLE) {
+ sc->vtys = sizeof(main_vtys)/sizeof(main_vtys[0]);
+ sc->tty = main_tty;
+#ifdef DEVFS
+ sc->devfs_token = main_devfs_token;
+#endif
+ sc->console = main_vtys;
+ scp = main_vtys[0] = &main_console;
+ init_scp(sc, sc->first_vty, scp);
+ sc_vtb_init(&scp->vtb, VTB_MEMORY, scp->xsize, scp->ysize,
+ (void *)sc_buffer, FALSE);
+ } else {
+ /* assert(sc_malloc) */
+ sc->vtys = MAXCONS;
+ sc->tty = malloc(sizeof(struct tty)*MAXCONS, M_DEVBUF, M_WAITOK);
+ bzero(sc->tty, sizeof(struct tty)*MAXCONS);
+#ifdef DEVFS
+ sc->devfs_token = malloc(sizeof(void *)*MAXCONS,
+ M_DEVBUF, M_WAITOK);
+#endif
+ sc->console = malloc(sizeof(struct scr_stat *)*MAXCONS,
+ M_DEVBUF, M_WAITOK);
+ scp = sc->console[0] = alloc_scp(sc, sc->first_vty);
+ }
+ sc->cur_scp = scp;
+
+ /* copy screen to temporary buffer */
+ sc_vtb_init(&scp->scr, VTB_FRAMEBUFFER, scp->xsize, scp->ysize,
+ (void *)scp->sc->adp->va_window, FALSE);
+ if (ISTEXTSC(scp))
+ sc_vtb_copy(&scp->scr, 0, &scp->vtb, 0, scp->xsize*scp->ysize);
+
+ /* move cursors to the initial positions */
+ scp->mouse_pos = scp->mouse_oldpos = 0;
+ if (col >= scp->xsize)
+ col = 0;
+ if (row >= scp->ysize)
+ row = scp->ysize - 1;
+ scp->xpos = col;
+ scp->ypos = row;
+ scp->cursor_pos = scp->cursor_oldpos = row*scp->xsize + col;
+ if (bios_value.cursor_end < scp->font_size)
+ sc->cursor_base = scp->font_size - bios_value.cursor_end - 1;
+ else
+ sc->cursor_base = 0;
+ i = bios_value.cursor_end - bios_value.cursor_start + 1;
+ sc->cursor_height = imin(i, scp->font_size);
+ if (!ISGRAPHSC(scp)) {
+ sc_set_cursor_image(scp);
+ draw_cursor_image(scp);
+ }
- /* initialize mapscrn arrays to a one to one map */
- for (i=0; i<sizeof(scr_map); i++) {
- scr_map[i] = scr_rmap[i] = i;
- }
+ /* save font and palette */
+#ifndef SC_NO_FONT_LOADING
+ sc->fonts_loaded = 0;
+ if (ISFONTAVAIL(sc->adp->va_flags)) {
+#ifdef SC_DFLT_FONT
+ bcopy(dflt_font_8, sc->font_8, sizeof(dflt_font_8));
+ bcopy(dflt_font_14, sc->font_14, sizeof(dflt_font_14));
+ bcopy(dflt_font_16, sc->font_16, sizeof(dflt_font_16));
+ sc->fonts_loaded = FONT_16 | FONT_14 | FONT_8;
+ if (scp->font_size < 14) {
+ copy_font(scp, LOAD, 8, sc->font_8);
+ sc->fonts_loaded = FONT_8;
+ } else if (scp->font_size >= 16) {
+ copy_font(scp, LOAD, 16, sc->font_16);
+ sc->fonts_loaded = FONT_16;
+ } else {
+ copy_font(scp, LOAD, 14, sc->font_14);
+ sc->fonts_loaded = FONT_14;
+ }
+#else /* !SC_DFLT_FONT */
+ if (scp->font_size < 14) {
+ copy_font(scp, SAVE, 8, sc->font_8);
+ sc->fonts_loaded = FONT_8;
+ } else if (scp->font_size >= 16) {
+ copy_font(scp, SAVE, 16, sc->font_16);
+ sc->fonts_loaded = FONT_16;
+ } else {
+ copy_font(scp, SAVE, 14, sc->font_14);
+ sc->fonts_loaded = FONT_14;
+ }
+#endif /* SC_DFLT_FONT */
+ /* FONT KLUDGE: always use the font page #0. XXX */
+ (*vidsw[sc->adapter]->show_font)(sc->adp, 0);
+ }
+#endif /* !SC_NO_FONT_LOADING */
- /* Save font and palette */
- if (ISFONTAVAIL(cur_console->adp->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);
+#ifndef SC_NO_PALETTE_LOADING
+ save_palette(sc->adp, sc->palette);
+#endif
+
+#if NSPLASH > 0
+ if (!(sc->flags & SC_SPLASH_SCRN) && (flags & SC_KERNEL_CONSOLE)) {
+ /* we are ready to put up the splash image! */
+ splash_init(sc->adp, scsplash_callback, sc);
+ sc->flags |= SC_SPLASH_SCRN;
}
- /*
- * FONT KLUDGE
- * Always use the font page #0. XXX
- */
- (*vidsw[cur_console->ad]->show_font)(cur_console->adp, 0);
+#endif /* NSPLASH */
}
- save_palette(cur_console->adp, palette);
+
+ /* the rest is not necessary, if we have done it once */
+ if (sc->flags & SC_INIT_DONE)
+ return;
+
+ /* clear structures */
+ for (i = 1; i < sc->vtys; i++)
+ sc->console[i] = NULL;
+
+ /* initialize mapscrn arrays to a one to one map */
+ for (i = 0; i < sizeof(sc->scr_map); i++)
+ sc->scr_map[i] = sc->scr_rmap[i] = i;
+
+ sc->flags |= SC_INIT_DONE;
+}
+
+static void
+scterm(int unit, int flags)
+{
+ sc_softc_t *sc;
+
+ sc = sc_get_softc(unit, flags & SC_KERNEL_CONSOLE);
+ if (sc == NULL)
+ return; /* shouldn't happen */
#if NSPLASH > 0
- /* we are ready to put up the splash image! */
- splash_init(cur_console->adp, scsplash_callback);
+ /* this console is no longer available for the splash screen */
+ if (sc->flags & SC_SPLASH_SCRN) {
+ splash_term(sc->adp);
+ sc->flags &= ~SC_SPLASH_SCRN;
+ }
+#endif /* NSPLASH */
+
+#if 0 /* XXX */
+ /* move the hardware cursor to the upper-left corner */
+ (*vidsw[sc->adapter]->set_hw_cursor)(sc->adp, 0, 0);
+#endif
+
+ /* release the keyboard and the video card */
+ if (sc->keyboard >= 0)
+ kbd_release(sc->kbd, &sc->keyboard);
+ if (sc->adapter >= 0)
+ vid_release(sc->adp, &sc->adapter);
+
+ /* clear the structure */
+ if (!(flags & SC_KERNEL_CONSOLE)) {
+ free(sc->console, M_DEVBUF);
+ free(sc->tty, M_DEVBUF);
+#ifdef DEVFS
+ free(sc->devfs_token, M_DEVBUF);
#endif
+#ifndef SC_NO_FONT_LOADING
+ free(sc->font_8, M_DEVBUF);
+ free(sc->font_14, M_DEVBUF);
+ free(sc->font_16, M_DEVBUF);
+#endif
+ /* XXX vtb, history */
+ }
+ bzero(sc, sizeof(*sc));
+ sc->keyboard = -1;
+ sc->adapter = -1;
}
static void
scshutdown(int howto, void *arg)
{
+ /* assert(sc_console != NULL) */
+
sc_touch_scrn_saver();
- if (!cold && cur_console->smode.mode == VT_AUTO
- && console[0]->smode.mode == VT_AUTO)
- switch_scr(cur_console, 0);
+ if (!cold && sc_console
+ && sc_console->sc->cur_scp->smode.mode == VT_AUTO
+ && sc_console->smode.mode == VT_AUTO)
+ switch_scr(sc_console->sc, sc_console->index);
shutdown_in_progress = TRUE;
}
@@ -3305,108 +3418,83 @@ sc_clean_up(scr_stat *scp)
int error;
sc_touch_scrn_saver();
- if ((error = wait_scrn_saver_stop()))
+#if NSPLASH > 0
+ if ((error = wait_scrn_saver_stop(scp->sc)))
return error;
+#endif /* NSPLASH */
scp->status &= ~MOUSE_VISIBLE;
- remove_cutmarking(scp);
+ sc_remove_cutmarking(scp);
return 0;
}
void
-sc_alloc_scr_buffer(scr_stat *scp, int wait, int clear)
+sc_alloc_scr_buffer(scr_stat *scp, int wait, int discard)
{
- 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);
+ sc_vtb_t new;
+ sc_vtb_t old;
+ int s;
- if (clear) {
+ old = scp->vtb;
+ sc_vtb_init(&new, VTB_MEMORY, scp->xsize, scp->ysize, NULL, wait);
+ if (!discard && (old.vtb_flags & VTB_VALID)) {
+ /* retain the current cursor position and buffer contants */
+ scp->cursor_oldpos = scp->cursor_pos;
+ /*
+ * This works only if the old buffer has the same size as or larger
+ * than the new one. XXX
+ */
+ sc_vtb_copy(&old, 0, &new, 0, scp->xsize*scp->ysize);
+ scp->vtb = new;
+ } else {
/* clear the screen and move the text cursor to the top-left position */
+ s = splhigh();
+ scp->vtb = new;
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;
+ splx(s);
+ sc_vtb_destroy(&old);
}
+#ifndef SC_NO_SYSMOUSE
/* move the mouse cursor at the center of the screen */
- sc_move_mouse(scp, scp->xpixel / 2, scp->ypixel / 2);
-}
-
-void
-sc_alloc_cut_buffer(scr_stat *scp, int wait)
-{
- 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;
+ sc_mouse_move(scp, scp->xpixel / 2, scp->ypixel / 2);
+#endif
}
static scr_stat
-*alloc_scp()
+*alloc_scp(sc_softc_t *sc, int vty)
{
scr_stat *scp;
+ /* assert(sc_malloc) */
+
scp = (scr_stat *)malloc(sizeof(scr_stat), M_DEVBUF, M_WAITOK);
- init_scp(scp);
+ init_scp(sc, vty, scp);
+
sc_alloc_scr_buffer(scp, TRUE, TRUE);
- if (ISMOUSEAVAIL(scp->adp->va_flags))
+
+#ifndef SC_NO_SYSMOUSE
+ if (ISMOUSEAVAIL(sc->adp->va_flags))
sc_alloc_cut_buffer(scp, TRUE);
- sc_alloc_history_buffer(scp, sc_history_size, 0, TRUE);
-/* SOS
- if (scp->adp->va_flags & V_ADP_MODECHANGE)
- set_mode(scp);
-*/
+#endif
+
+#ifndef SC_NO_HISTORY
+ sc_alloc_history_buffer(scp, 0, TRUE);
+#endif
+
sc_clear_screen(scp);
- scp->cursor_saveunder = *scp->cursor_pos;
return scp;
}
static void
-init_scp(scr_stat *scp)
+init_scp(sc_softc_t *sc, int vty, scr_stat *scp)
{
video_info_t info;
- scp->ad = adapter;
- scp->adp = vid_get_adapter(scp->ad);
- (*vidsw[scp->ad]->get_info)(scp->adp, initial_video_mode, &info);
-
+ scp->index = vty;
+ scp->sc = sc;
scp->status = 0;
- scp->mode = initial_video_mode;
- scp->scr_buf = NULL;
+ scp->mode = sc->initial_mode;
+ (*vidsw[sc->adapter]->get_info)(sc->adp, scp->mode, &info);
if (info.vi_flags & V_INFO_GRAPHICS) {
scp->status |= GRAPHICS_MODE;
scp->xpixel = info.vi_width;
@@ -3414,17 +3502,41 @@ init_scp(scr_stat *scp)
scp->xsize = info.vi_width/8;
scp->ysize = info.vi_height/info.vi_cheight;
scp->font_size = FONT_NONE;
+ scp->font = NULL;
} 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;
+ if (info.vi_cheight < 14) {
+ scp->font_size = 8;
+#ifndef SC_NO_FONT_LOADING
+ scp->font = sc->font_8;
+#else
+ scp->font = NULL;
+#endif
+ } else if (info.vi_cheight >= 16) {
+ scp->font_size = 16;
+#ifndef SC_NO_FONT_LOADING
+ scp->font = sc->font_16;
+#else
+ scp->font = NULL;
+#endif
+ } else {
+ scp->font_size = 14;
+#ifndef SC_NO_FONT_LOADING
+ scp->font = sc->font_14;
+#else
+ scp->font = NULL;
+#endif
+ }
}
+ sc_vtb_init(&scp->vtb, VTB_MEMORY, 0, 0, NULL, FALSE);
+ sc_vtb_init(&scp->scr, VTB_FRAMEBUFFER, 0, 0, NULL, FALSE);
scp->xoff = scp->yoff = 0;
scp->xpos = scp->ypos = 0;
scp->saved_xpos = scp->saved_ypos = -1;
- scp->start = scp->xsize * scp->ysize;
+ scp->start = scp->xsize * scp->ysize - 1;
scp->end = 0;
scp->term.esc = 0;
scp->term.attr_mask = NORMAL_ATTR;
@@ -3433,70 +3545,30 @@ init_scp(scr_stat *scp)
current_default->std_color;
scp->term.rev_color = current_default->rev_color;
scp->border = BG_BLACK;
- scp->cursor_start = bios_value.cursor_start;
- scp->cursor_end = bios_value.cursor_end;
- scp->mouse_xpos = scp->xsize*8/2;
- scp->mouse_ypos = scp->ysize*scp->font_size/2;
- scp->mouse_cut_start = scp->mouse_cut_end = NULL;
+ scp->cursor_base = sc->cursor_base;
+ scp->cursor_height = imin(sc->cursor_height, scp->font_size);
+ scp->mouse_xpos = scp->xoff*8 + scp->xsize*8/2;
+ scp->mouse_ypos = (scp->ysize + scp->yoff)*scp->font_size/2;
+ scp->mouse_cut_start = scp->xsize*scp->ysize;
+ scp->mouse_cut_end = -1;
scp->mouse_signal = 0;
scp->mouse_pid = 0;
scp->mouse_proc = NULL;
scp->kbd_mode = K_XLATE;
- scp->bell_pitch = BELL_PITCH;
+ scp->bell_pitch = bios_value.bell_pitch;
scp->bell_duration = BELL_DURATION;
- scp->status |= (bios_value.shift_state & 0x20) ? NLKED : 0;
+ scp->status |= (bios_value.shift_state & NLKED);
scp->status |= CURSOR_ENABLED;
scp->pid = 0;
scp->proc = NULL;
scp->smode.mode = VT_AUTO;
- scp->history_head = scp->history_pos = scp->history = NULL;
- scp->history_size = imax(sc_history_size, scp->ysize) * scp->xsize;
-}
-
-static void
-get_bios_values(void)
-{
- bios_value.cursor_start = *(u_int8_t *)pa_to_va(0x461);
- bios_value.cursor_end = *(u_int8_t *)pa_to_va(0x460);
- bios_value.shift_state = *(u_int8_t *)pa_to_va(0x417);
-}
-
-static void
-history_to_screen(scr_stat *scp)
-{
- int i;
-
- for (i=0; i<scp->ysize; i++)
- bcopy(scp->history + (((scp->history_pos - scp->history) +
- scp->history_size-((i+1)*scp->xsize))%scp->history_size),
- scp->scr_buf + (scp->xsize * (scp->ysize-1 - i)),
- scp->xsize * sizeof(u_short));
- mark_all(scp);
-}
-
-static int
-history_up_line(scr_stat *scp)
-{
- if (WRAPHIST(scp, scp->history_pos, -(scp->xsize*scp->ysize)) !=
- scp->history_head) {
- scp->history_pos = WRAPHIST(scp, scp->history_pos, -scp->xsize);
- history_to_screen(scp);
- return 0;
- }
- else
- return -1;
-}
+ scp->history = NULL;
+ scp->history_pos = 0;
+ scp->history_size = 0;
-static int
-history_down_line(scr_stat *scp)
-{
- if (scp->history_pos != scp->history_head) {
- scp->history_pos = WRAPHIST(scp, scp->history_pos, scp->xsize);
- history_to_screen(scp);
- return 0;
- }
- else
- return -1;
+ /* what if the following call fails... XXX */
+ scp->rndr = sc_render_match(scp, scp->sc->adp,
+ scp->status & (GRAPHICS_MODE | PIXEL_MODE));
}
/*
@@ -3506,26 +3578,30 @@ history_down_line(scr_stat *scp)
* return NOKEY if there is nothing there.
*/
static u_int
-scgetc(keyboard_t *kbd, u_int flags)
+scgetc(sc_softc_t *sc, u_int flags)
{
+ scr_stat *scp;
u_int c;
int this_scr;
int f;
int i;
- if (kbd == NULL)
+ if (sc->kbd == NULL)
return NOKEY;
next_code:
+#if 1
/* I don't like this, but... XXX */
if (flags & SCGETC_CN)
- sccnupdate(cur_console);
+ sccnupdate(sc->cur_scp);
+#endif
+ scp = sc->cur_scp;
/* first see if there is something in the keyboard port */
for (;;) {
- c = kbd_read_char(kbd, !(flags & SCGETC_NONBLOCK));
+ c = kbd_read_char(sc->kbd, !(flags & SCGETC_NONBLOCK));
if (c == ERRKEY) {
if (!(flags & SCGETC_CN))
- do_bell(cur_console, BELL_PITCH, BELL_DURATION);
+ do_bell(scp, bios_value.bell_pitch, BELL_DURATION);
} else if (c == NOKEY)
return c;
else
@@ -3542,81 +3618,67 @@ next_code:
add_keyboard_randomness(c);
#endif
- if (cur_console->kbd_mode != K_XLATE)
+ if (scp->kbd_mode != K_XLATE)
return KEYCHAR(c);
/* if scroll-lock pressed allow history browsing */
- if (!ISGRAPHSC(cur_console) && cur_console->history
- && cur_console->status & SLKED) {
-
- cur_console->status &= ~CURSOR_ENABLED;
- if (!(cur_console->status & BUFFER_SAVED)) {
- cur_console->status |= BUFFER_SAVED;
- cur_console->history_save = cur_console->history_head;
-
- /* copy screen into top of history buffer */
- for (i=0; i<cur_console->ysize; i++) {
- bcopy(cur_console->scr_buf + (cur_console->xsize * i),
- cur_console->history_head,
- cur_console->xsize * sizeof(u_short));
- cur_console->history_head += cur_console->xsize;
- if (cur_console->history_head + cur_console->xsize >
- cur_console->history + cur_console->history_size)
- cur_console->history_head=cur_console->history;
- }
- cur_console->history_pos = cur_console->history_head;
- history_to_screen(cur_console);
+ if (!ISGRAPHSC(scp) && scp->history && scp->status & SLKED) {
+
+ scp->status &= ~CURSOR_ENABLED;
+ remove_cursor_image(scp);
+
+#ifndef SC_NO_HISTORY
+ if (!(scp->status & BUFFER_SAVED)) {
+ scp->status |= BUFFER_SAVED;
+ sc_hist_save(scp);
}
switch (c) {
/* FIXME: key codes */
case SPCLKEY | FKEY | F(49): /* home key */
- remove_cutmarking(cur_console);
- cur_console->history_pos = cur_console->history_head;
- history_to_screen(cur_console);
+ sc_remove_cutmarking(scp);
+ sc_hist_home(scp);
goto next_code;
case SPCLKEY | FKEY | F(57): /* end key */
- remove_cutmarking(cur_console);
- cur_console->history_pos =
- WRAPHIST(cur_console, cur_console->history_head,
- cur_console->xsize*cur_console->ysize);
- history_to_screen(cur_console);
+ sc_remove_cutmarking(scp);
+ sc_hist_end(scp);
goto next_code;
case SPCLKEY | FKEY | F(50): /* up arrow key */
- remove_cutmarking(cur_console);
- if (history_up_line(cur_console))
+ sc_remove_cutmarking(scp);
+ if (sc_hist_up_line(scp))
if (!(flags & SCGETC_CN))
- do_bell(cur_console, BELL_PITCH, BELL_DURATION);
+ do_bell(scp, bios_value.bell_pitch, BELL_DURATION);
goto next_code;
case SPCLKEY | FKEY | F(58): /* down arrow key */
- remove_cutmarking(cur_console);
- if (history_down_line(cur_console))
+ sc_remove_cutmarking(scp);
+ if (sc_hist_down_line(scp))
if (!(flags & SCGETC_CN))
- do_bell(cur_console, BELL_PITCH, BELL_DURATION);
+ do_bell(scp, bios_value.bell_pitch, BELL_DURATION);
goto next_code;
case SPCLKEY | FKEY | F(51): /* page up key */
- remove_cutmarking(cur_console);
- for (i=0; i<cur_console->ysize; i++)
- if (history_up_line(cur_console)) {
+ sc_remove_cutmarking(scp);
+ for (i=0; i<scp->ysize; i++)
+ if (sc_hist_up_line(scp)) {
if (!(flags & SCGETC_CN))
- do_bell(cur_console, BELL_PITCH, BELL_DURATION);
+ do_bell(scp, bios_value.bell_pitch, BELL_DURATION);
break;
}
goto next_code;
case SPCLKEY | FKEY | F(59): /* page down key */
- remove_cutmarking(cur_console);
- for (i=0; i<cur_console->ysize; i++)
- if (history_down_line(cur_console)) {
+ sc_remove_cutmarking(scp);
+ for (i=0; i<scp->ysize; i++)
+ if (sc_hist_down_line(scp)) {
if (!(flags & SCGETC_CN))
- do_bell(cur_console, BELL_PITCH, BELL_DURATION);
+ do_bell(scp, bios_value.bell_pitch, BELL_DURATION);
break;
}
goto next_code;
}
+#endif /* SC_NO_HISTORY */
}
/*
@@ -3635,33 +3697,22 @@ next_code:
case NLK: case CLK: case ALK:
break;
case SLK:
- kbd_ioctl(kbd, KDGKBSTATE, (caddr_t)&f);
+ kbd_ioctl(sc->kbd, KDGKBSTATE, (caddr_t)&f);
if (f & SLKED) {
- cur_console->status |= SLKED;
+ scp->status |= SLKED;
} else {
- if (cur_console->status & SLKED) {
- cur_console->status &= ~SLKED;
- if (cur_console->status & BUFFER_SAVED) {
- int i;
- u_short *ptr = cur_console->history_save;
-
- for (i=0; i<cur_console->ysize; i++) {
- bcopy(ptr,
- cur_console->scr_buf +
- (cur_console->xsize*i),
- cur_console->xsize * sizeof(u_short));
- ptr += cur_console->xsize;
- if (ptr + cur_console->xsize >
- cur_console->history +
- cur_console->history_size)
- ptr = cur_console->history;
- }
- cur_console->status &= ~BUFFER_SAVED;
- cur_console->history_head=cur_console->history_save;
- cur_console->status |= CURSOR_ENABLED;
- mark_all(cur_console);
+ if (scp->status & SLKED) {
+ scp->status &= ~SLKED;
+#ifndef SC_NO_HISTORY
+ if (scp->status & BUFFER_SAVED) {
+ if (!sc_hist_restore(scp))
+ sc_remove_cutmarking(scp);
+ scp->status &= ~BUFFER_SAVED;
+ scp->status |= CURSOR_ENABLED;
+ draw_cursor_image(scp);
}
- scstart(VIRTUAL_TTY(get_scr_num()));
+#endif
+ scstart(VIRTUAL_TTY(sc, scp->index));
}
}
break;
@@ -3673,27 +3724,29 @@ next_code:
break;
case BTAB:
- return c;
+ if (!(sc->flags & SC_SCRN_BLANKED))
+ return c;
+ break;
case SPSC:
+#if NSPLASH > 0
/* force activatation/deactivation of the screen saver */
- if (!scrn_blanked) {
+ if (!(sc->flags & SC_SCRN_BLANKED)) {
run_scrn_saver = TRUE;
- scrn_time_stamp -= scrn_blank_time;
+ sc->scrn_time_stamp -= scrn_blank_time;
}
-#if NSPLASH > 0
if (cold) {
/*
* While devices are being probed, the screen saver need
* to be invoked explictly. XXX
*/
- if (scrn_blanked) {
+ if (sc->flags & SC_SCRN_BLANKED) {
scsplash_stick(FALSE);
- stop_scrn_saver(current_saver);
+ stop_scrn_saver(sc, current_saver);
} else {
- if (!ISGRAPHSC(cur_console)) {
+ if (!ISGRAPHSC(scp)) {
scsplash_stick(TRUE);
- (*current_saver)(TRUE);
+ (*current_saver)(sc, TRUE);
}
}
}
@@ -3720,28 +3773,53 @@ next_code:
#endif
case DBG:
-#ifdef DDB /* try to switch to console 0 */
- /*
- * TRY to make sure the screen saver is stopped,
- * and the screen is updated before switching to
- * the vty0.
- */
- scrn_timer((void *)FALSE);
- if (cur_console->smode.mode == VT_AUTO &&
- console[0]->smode.mode == VT_AUTO)
- switch_scr(cur_console, 0);
+#ifndef SC_DISABLE_DDBKEY
+#ifdef DDB
+ if (debugger)
+ break;
+ /* try to switch to the kernel console screen */
+ if (sc_console) {
+ /*
+ * TRY to make sure the screen saver is stopped,
+ * and the screen is updated before switching to
+ * the vty0.
+ */
+ scrn_timer(NULL);
+ if (!cold
+ && sc_console->sc->cur_scp->smode.mode == VT_AUTO
+ && sc_console->smode.mode == VT_AUTO)
+ switch_scr(sc_console->sc, sc_console->index);
+ }
Debugger("manual escape to debugger");
#else
printf("No debugger in kernel\n");
#endif
+#else /* SC_DISABLE_DDBKEY */
+ /* do nothing */
+#endif /* SC_DISABLE_DDBKEY */
break;
case NEXT:
- this_scr = get_scr_num();
- for (i = this_scr + 1; i != this_scr; i = (i + 1)%MAXCONS) {
- struct tty *tp = VIRTUAL_TTY(i);
+ this_scr = scp->index;
+ for (i = (this_scr - sc->first_vty + 1)%sc->vtys;
+ sc->first_vty + i != this_scr;
+ i = (i + 1)%sc->vtys) {
+ struct tty *tp = VIRTUAL_TTY(sc, sc->first_vty + i);
+ if (tp->t_state & TS_ISOPEN) {
+ switch_scr(scp->sc, sc->first_vty + i);
+ break;
+ }
+ }
+ break;
+
+ case PREV:
+ this_scr = scp->index;
+ for (i = (this_scr - sc->first_vty + sc->vtys - 1)%sc->vtys;
+ sc->first_vty + i != this_scr;
+ i = (i + sc->vtys - 1)%sc->vtys) {
+ struct tty *tp = VIRTUAL_TTY(sc, sc->first_vty + i);
if (tp->t_state & TS_ISOPEN) {
- switch_scr(cur_console, i);
+ switch_scr(scp->sc, sc->first_vty + i);
break;
}
}
@@ -3749,16 +3827,19 @@ next_code:
default:
if (KEYCHAR(c) >= F_SCR && KEYCHAR(c) <= L_SCR) {
- switch_scr(cur_console, KEYCHAR(c) - F_SCR);
+ switch_scr(scp->sc, sc->first_vty + KEYCHAR(c) - F_SCR);
break;
}
/* assert(c & FKEY) */
- return c;
+ if (!(sc->flags & SC_SCRN_BLANKED))
+ return c;
+ break;
}
/* goto next_code */
} else {
/* regular keys (maybe MKEY is set) */
- return c;
+ if (!(sc->flags & SC_SCRN_BLANKED))
+ return c;
}
}
@@ -3775,7 +3856,7 @@ scmmap(dev_t dev, vm_offset_t offset, int nprot)
if (!tp)
return ENXIO;
scp = sc_get_scr_stat(tp->t_dev);
- return (*vidsw[scp->ad]->mmap)(scp->adp, offset);
+ return (*vidsw[scp->sc->adapter]->mmap)(scp->sc->adp, offset, nprot);
}
/*
@@ -3813,7 +3894,7 @@ save_kbd_state(scr_stat *scp)
int state;
int error;
- error = kbd_ioctl(kbd, KDGKBSTATE, (caddr_t)&state);
+ error = kbd_ioctl(scp->sc->kbd, KDGKBSTATE, (caddr_t)&state);
if (error == ENOIOCTL)
error = ENODEV;
if (error == 0) {
@@ -3824,13 +3905,13 @@ save_kbd_state(scr_stat *scp)
}
static int
-update_kbd_state(int new_bits, int mask)
+update_kbd_state(scr_stat *scp, int new_bits, int mask)
{
int state;
int error;
if (mask != LOCK_MASK) {
- error = kbd_ioctl(kbd, KDGKBSTATE, (caddr_t)&state);
+ error = kbd_ioctl(scp->sc->kbd, KDGKBSTATE, (caddr_t)&state);
if (error == ENOIOCTL)
error = ENODEV;
if (error)
@@ -3840,19 +3921,19 @@ update_kbd_state(int new_bits, int mask)
} else {
state = new_bits & LOCK_MASK;
}
- error = kbd_ioctl(kbd, KDSKBSTATE, (caddr_t)&state);
+ error = kbd_ioctl(scp->sc->kbd, KDSKBSTATE, (caddr_t)&state);
if (error == ENOIOCTL)
error = ENODEV;
return error;
}
static int
-update_kbd_leds(int which)
+update_kbd_leds(scr_stat *scp, int which)
{
int error;
which &= LOCK_MASK;
- error = kbd_ioctl(kbd, KDSETLED, (caddr_t)&which);
+ error = kbd_ioctl(scp->sc->kbd, KDSETLED, (caddr_t)&which);
if (error == ENOIOCTL)
error = ENODEV;
return error;
@@ -3864,28 +3945,31 @@ set_mode(scr_stat *scp)
video_info_t info;
/* reject unsupported mode */
- if ((*vidsw[scp->ad]->get_info)(scp->adp, scp->mode, &info))
+ if ((*vidsw[scp->sc->adapter]->get_info)(scp->sc->adp, scp->mode, &info))
return 1;
/* if this vty is not currently showing, do nothing */
- if (scp != cur_console)
+ if (scp != scp->sc->cur_scp)
return 0;
/* setup video hardware for the given mode */
- (*vidsw[scp->ad]->set_mode)(scp->adp, scp->mode);
+ (*vidsw[scp->sc->adapter]->set_mode)(scp->sc->adp, scp->mode);
+ sc_vtb_init(&scp->scr, VTB_FRAMEBUFFER, scp->xsize, scp->ysize,
+ (void *)scp->sc->adp->va_window, FALSE);
+#ifndef SC_NO_FONT_LOADING
+ /* load appropriate font */
if (!(scp->status & GRAPHICS_MODE)) {
- /* load appropriate font */
- if (!(scp->status & PIXEL_MODE) && ISFONTAVAIL(scp->adp->va_flags)) {
+ if (!(scp->status & PIXEL_MODE) && ISFONTAVAIL(scp->sc->adp->va_flags)) {
if (scp->font_size < 14) {
- if (fonts_loaded & FONT_8)
- copy_font(scp, LOAD, 8, font_8);
+ if (scp->sc->fonts_loaded & FONT_8)
+ copy_font(scp, LOAD, 8, scp->sc->font_8);
} else if (scp->font_size >= 16) {
- if (fonts_loaded & FONT_16)
- copy_font(scp, LOAD, 16, font_16);
+ if (scp->sc->fonts_loaded & FONT_16)
+ copy_font(scp, LOAD, 16, scp->sc->font_16);
} else {
- if (fonts_loaded & FONT_14)
- copy_font(scp, LOAD, 14, font_14);
+ if (scp->sc->fonts_loaded & FONT_14)
+ copy_font(scp, LOAD, 14, scp->sc->font_14);
}
/*
* FONT KLUDGE:
@@ -3894,18 +3978,14 @@ set_mode(scr_stat *scp)
* Somehow we cannot show the font in other font pages on
* some video cards... XXX
*/
- (*vidsw[scp->ad]->show_font)(scp->adp, 0);
+ (*vidsw[scp->sc->adapter]->show_font)(scp->sc->adp, 0);
}
mark_all(scp);
}
-
- if (scp->status & PIXEL_MODE)
- bzero_io(scp->adp->va_window, scp->xpixel*scp->ypixel/8);
+#endif /* !SC_NO_FONT_LOADING */
set_border(scp, scp->border);
-
- /* move hardware cursor out of the way */
- (*vidsw[scp->ad]->set_hw_cursor)(scp->adp, -1, -1);
+ sc_set_cursor_image(scp);
return 0;
}
@@ -3913,43 +3993,12 @@ set_mode(scr_stat *scp)
void
set_border(scr_stat *scp, int color)
{
- vm_offset_t p;
- int xoff;
- int yoff;
- int xlen;
- int ylen;
- int i;
-
- (*vidsw[scp->ad]->set_border)(scp->adp, color);
-
- if (scp->status & PIXEL_MODE) {
- outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */
- outw(GDCIDX, 0x0003); /* data rotate/function select */
- outw(GDCIDX, 0x0f01); /* set/reset enable */
- outw(GDCIDX, 0xff08); /* bit mask */
- outw(GDCIDX, (color << 8) | 0x00); /* set/reset */
- p = scp->adp->va_window;
- xoff = scp->xoff;
- yoff = scp->yoff*scp->font_size;
- xlen = scp->xpixel/8;
- ylen = scp->ysize*scp->font_size;
- if (yoff > 0) {
- bzero_io(p, xlen*yoff);
- bzero_io(p + xlen*(yoff + ylen),
- xlen*scp->ypixel - xlen*(yoff + ylen));
- }
- if (xoff > 0) {
- for (i = 0; i < ylen; ++i) {
- bzero_io(p + xlen*(yoff + i), xoff);
- bzero_io(p + xlen*(yoff + i) + xoff + scp->xsize,
- xlen - xoff - scp->xsize);
- }
- }
- outw(GDCIDX, 0x0000); /* set/reset */
- outw(GDCIDX, 0x0001); /* set/reset enable */
- }
+ ++scp->sc->videoio_in_progress;
+ (*scp->rndr->draw_border)(scp, color);
+ --scp->sc->videoio_in_progress;
}
+#ifndef SC_NO_FONT_LOADING
void
copy_font(scr_stat *scp, int operation, int font_size, u_char *buf)
{
@@ -3960,450 +4009,41 @@ copy_font(scr_stat *scp, int operation, int font_size, u_char *buf)
* Somehow we cannot show the font in other font pages on
* some video cards... XXX
*/
- font_loading_in_progress = TRUE;
+ scp->sc->font_loading_in_progress = TRUE;
if (operation == LOAD) {
- (*vidsw[scp->ad]->load_font)(scp->adp, 0, font_size, buf, 0, 256);
- if (sc_flags & CHAR_CURSOR)
- set_destructive_cursor(scp);
+ (*vidsw[scp->sc->adapter]->load_font)(scp->sc->adp, 0, font_size,
+ buf, 0, 256);
} else if (operation == SAVE) {
- (*vidsw[scp->ad]->save_font)(scp->adp, 0, font_size, buf, 0, 256);
+ (*vidsw[scp->sc->adapter]->save_font)(scp->sc->adp, 0, font_size,
+ buf, 0, 256);
}
- font_loading_in_progress = FALSE;
+ scp->sc->font_loading_in_progress = FALSE;
}
+#endif /* !SC_NO_FONT_LOADING */
-static void
-set_destructive_cursor(scr_stat *scp)
+#ifndef SC_NO_SYSMOUSE
+struct tty
+*sc_get_mouse_tty(void)
{
- u_char cursor[32];
- u_char *font_buffer;
- int font_size;
- int crtc_addr;
- int i;
-
- if (!ISFONTAVAIL(scp->adp->va_flags)
- || (scp->status & (GRAPHICS_MODE | PIXEL_MODE)))
- return;
-
- if (scp->font_size < 14) {
- font_buffer = font_8;
- font_size = 8;
- } else if (scp->font_size >= 16) {
- font_buffer = font_16;
- font_size = 16;
- } else {
- font_buffer = font_14;
- font_size = 14;
- }
-
- if (scp->status & MOUSE_VISIBLE) {
- if ((scp->cursor_saveunder & 0xff) == SC_MOUSE_CHAR)
- bcopy(&scp->mouse_cursor[0], cursor, scp->font_size);
- else if ((scp->cursor_saveunder & 0xff) == SC_MOUSE_CHAR + 1)
- bcopy(&scp->mouse_cursor[32], cursor, scp->font_size);
- else if ((scp->cursor_saveunder & 0xff) == SC_MOUSE_CHAR + 2)
- bcopy(&scp->mouse_cursor[64], cursor, scp->font_size);
- else if ((scp->cursor_saveunder & 0xff) == SC_MOUSE_CHAR + 3)
- bcopy(&scp->mouse_cursor[96], cursor, scp->font_size);
- else
- bcopy(font_buffer+((scp->cursor_saveunder & 0xff)*scp->font_size),
- cursor, scp->font_size);
- }
- else
- bcopy(font_buffer + ((scp->cursor_saveunder & 0xff) * scp->font_size),
- cursor, scp->font_size);
- for (i=0; i<32; i++)
- if ((i >= scp->cursor_start && i <= scp->cursor_end) ||
- (scp->cursor_start >= scp->font_size && i == scp->font_size - 1))
- cursor[i] |= 0xff;
-#if 1
- crtc_addr = scp->adp->va_crtc_addr;
- while (!(inb(crtc_addr+6) & 0x08)) /* wait for vertical retrace */ ;
-#endif
- font_loading_in_progress = TRUE;
- (*vidsw[scp->ad]->load_font)(scp->adp, 0, font_size, cursor, DEAD_CHAR, 1);
- font_loading_in_progress = FALSE;
+ return MOUSE_TTY;
}
+#endif /* !SC_NO_SYSMOUSE */
+#ifndef SC_NO_CUTPASTE
void
-sc_move_mouse(scr_stat *scp, int x, int y)
+sc_paste(scr_stat *scp, u_char *p, int count)
{
- 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
-set_mouse_pos(scr_stat *scp)
-{
- static int last_xpos = -1, last_ypos = -1;
-
- if (scp->mouse_xpos < 0)
- scp->mouse_xpos = 0;
- if (scp->mouse_ypos < 0)
- scp->mouse_ypos = 0;
- if (!ISTEXTSC(scp)) {
- if (scp->mouse_xpos > scp->xpixel-1)
- scp->mouse_xpos = scp->xpixel-1;
- if (scp->mouse_ypos > scp->ypixel-1)
- scp->mouse_ypos = scp->ypixel-1;
- return;
- }
- if (scp->mouse_xpos > (scp->xsize*8)-1)
- scp->mouse_xpos = (scp->xsize*8)-1;
- if (scp->mouse_ypos > (scp->ysize*scp->font_size)-1)
- scp->mouse_ypos = (scp->ysize*scp->font_size)-1;
-
- if (scp->mouse_xpos != last_xpos || scp->mouse_ypos != last_ypos) {
- scp->status |= MOUSE_MOVED;
-
- scp->mouse_pos = scp->scr_buf +
- ((scp->mouse_ypos/scp->font_size)*scp->xsize + scp->mouse_xpos/8);
-
- if ((scp->status & MOUSE_VISIBLE) && (scp->status & MOUSE_CUTTING))
- mouse_cut(scp);
- }
-}
-
-#define isspace(c) (((c) & 0xff) == ' ')
-
-static int
-skip_spc_right(scr_stat *scp, u_short *p)
-{
- int i;
-
- for (i = (p - scp->scr_buf) % scp->xsize; i < scp->xsize; ++i) {
- if (!isspace(*p))
- break;
- ++p;
- }
- return i;
-}
-
-static int
-skip_spc_left(scr_stat *scp, u_short *p)
-{
- int i;
-
- for (i = (p-- - scp->scr_buf) % scp->xsize - 1; i >= 0; --i) {
- if (!isspace(*p))
- break;
- --p;
- }
- return i;
-}
-
-static void
-mouse_cut(scr_stat *scp)
-{
- u_short *end;
- u_short *p;
- int i = 0;
- int j = 0;
-
- scp->mouse_cut_end = (scp->mouse_pos >= scp->mouse_cut_start) ?
- scp->mouse_pos + 1 : scp->mouse_pos;
- end = (scp->mouse_cut_start > scp->mouse_cut_end) ?
- scp->mouse_cut_start : scp->mouse_cut_end;
- for (p = (scp->mouse_cut_start > scp->mouse_cut_end) ?
- scp->mouse_cut_end : scp->mouse_cut_start; p < end; ++p) {
- cut_buffer[i] = *p & 0xff;
- /* remember the position of the last non-space char */
- if (!isspace(cut_buffer[i++]))
- j = i;
- /* trim trailing blank when crossing lines */
- if (((p - scp->scr_buf) % scp->xsize) == (scp->xsize - 1)) {
- cut_buffer[j++] = '\r';
- i = j;
- }
- }
- cut_buffer[i] = '\0';
-
- /* scan towards the end of the last line */
- --p;
- for (i = (p - scp->scr_buf) % scp->xsize; i < scp->xsize; ++i) {
- if (!isspace(*p))
- break;
- ++p;
- }
- /* if there is nothing but blank chars, trim them, but mark towards eol */
- if (i >= scp->xsize) {
- if (scp->mouse_cut_start > scp->mouse_cut_end)
- scp->mouse_cut_start = p;
- else
- scp->mouse_cut_end = p;
- cut_buffer[j++] = '\r';
- cut_buffer[j] = '\0';
- }
-
- mark_for_update(scp, scp->mouse_cut_start - scp->scr_buf);
- mark_for_update(scp, scp->mouse_cut_end - scp->scr_buf);
-}
-
-static void
-mouse_cut_start(scr_stat *scp)
-{
- int i;
-
- if (scp->status & MOUSE_VISIBLE) {
- if (scp->mouse_pos == scp->mouse_cut_start &&
- scp->mouse_cut_start == scp->mouse_cut_end - 1) {
- cut_buffer[0] = '\0';
- remove_cutmarking(scp);
- } else if (skip_spc_right(scp, scp->mouse_pos) >= scp->xsize) {
- /* if the pointer is on trailing blank chars, mark towards eol */
- i = skip_spc_left(scp, scp->mouse_pos) + 1;
- scp->mouse_cut_start = scp->scr_buf +
- ((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] = '\r';
- cut_buffer[1] = '\0';
- scp->status |= MOUSE_CUTTING;
- } else {
- scp->mouse_cut_start = scp->mouse_pos;
- scp->mouse_cut_end = scp->mouse_cut_start + 1;
- cut_buffer[0] = *scp->mouse_cut_start & 0xff;
- cut_buffer[1] = '\0';
- scp->status |= MOUSE_CUTTING;
- }
- mark_all(scp);
- /* delete all other screens cut markings */
- for (i=0; i<MAXCONS; i++) {
- if (console[i] == NULL || console[i] == scp)
- continue;
- remove_cutmarking(console[i]);
- }
- }
-}
-
-static void
-mouse_cut_end(scr_stat *scp)
-{
- if (scp->status & MOUSE_VISIBLE) {
- scp->status &= ~MOUSE_CUTTING;
- }
-}
-
-static void
-mouse_cut_word(scr_stat *scp)
-{
- u_short *p;
- u_short *sol;
- u_short *eol;
- int i;
-
- /*
- * Because we don't have locale information in the kernel,
- * we only distinguish space char and non-space chars. Punctuation
- * chars, symbols and other regular chars are all treated alike.
- */
- if (scp->status & MOUSE_VISIBLE) {
- sol = scp->scr_buf
- + ((scp->mouse_pos - scp->scr_buf) / scp->xsize) * scp->xsize;
- eol = sol + scp->xsize;
- if (isspace(*scp->mouse_pos)) {
- for (p = scp->mouse_pos; p >= sol; --p)
- if (!isspace(*p))
- break;
- scp->mouse_cut_start = ++p;
- for (p = scp->mouse_pos; p < eol; ++p)
- if (!isspace(*p))
- break;
- scp->mouse_cut_end = p;
- } else {
- for (p = scp->mouse_pos; p >= sol; --p)
- if (isspace(*p))
- break;
- scp->mouse_cut_start = ++p;
- for (p = scp->mouse_pos; p < eol; ++p)
- if (isspace(*p))
- break;
- scp->mouse_cut_end = p;
- }
- for (i = 0, p = scp->mouse_cut_start; p < scp->mouse_cut_end; ++p)
- cut_buffer[i++] = *p & 0xff;
- cut_buffer[i] = '\0';
- scp->status |= MOUSE_CUTTING;
- }
-}
-
-static void
-mouse_cut_line(scr_stat *scp)
-{
- u_short *p;
- int i;
-
- if (scp->status & MOUSE_VISIBLE) {
- scp->mouse_cut_start = scp->scr_buf
- + ((scp->mouse_pos - scp->scr_buf) / scp->xsize) * scp->xsize;
- 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++] = '\r';
- cut_buffer[i] = '\0';
- scp->status |= MOUSE_CUTTING;
- }
-}
-
-static void
-mouse_cut_extend(scr_stat *scp)
-{
- if ((scp->status & MOUSE_VISIBLE) && !(scp->status & MOUSE_CUTTING)
- && (scp->mouse_cut_start != NULL)) {
- mouse_cut(scp);
- scp->status |= MOUSE_CUTTING;
- }
-}
+ struct tty *tp;
+ u_char *rmap;
-static void
-mouse_paste(scr_stat *scp)
-{
if (scp->status & MOUSE_VISIBLE) {
- struct tty *tp;
- u_char *ptr = cut_buffer;
-
- tp = VIRTUAL_TTY(get_scr_num());
- while (*ptr)
- (*linesw[tp->t_line].l_rint)(scr_rmap[*ptr++], tp);
- }
-}
-
-static void
-draw_mouse_image(scr_stat *scp)
-{
- u_short buffer[32];
- u_short xoffset, yoffset;
- vm_offset_t crt_pos = scp->adp->va_window + 2*(scp->mouse_pos - scp->scr_buf);
- u_char *font_buffer;
- int font_size;
- int crtc_addr;
- int i;
-
- if (scp->font_size < 14) {
- font_buffer = font_8;
- font_size = 8;
- } else if (scp->font_size >= 16) {
- font_buffer = font_16;
- font_size = 16;
- } else {
- font_buffer = font_14;
- font_size = 14;
- }
-
- xoffset = scp->mouse_xpos % 8;
- yoffset = scp->mouse_ypos % scp->font_size;
-
- /* prepare mousepointer char's bitmaps */
- bcopy(font_buffer + ((*(scp->mouse_pos) & 0xff) * font_size),
- &scp->mouse_cursor[0], font_size);
- bcopy(font_buffer + ((*(scp->mouse_pos+1) & 0xff) * font_size),
- &scp->mouse_cursor[32], font_size);
- bcopy(font_buffer + ((*(scp->mouse_pos+scp->xsize) & 0xff) * font_size),
- &scp->mouse_cursor[64], font_size);
- bcopy(font_buffer + ((*(scp->mouse_pos+scp->xsize+1) & 0xff) * font_size),
- &scp->mouse_cursor[96], font_size);
- for (i=0; i<font_size; i++) {
- buffer[i] = scp->mouse_cursor[i]<<8 | scp->mouse_cursor[i+32];
- buffer[i+font_size]=scp->mouse_cursor[i+64]<<8|scp->mouse_cursor[i+96];
- }
-
- /* now and-or in the mousepointer image */
- for (i=0; i<16; i++) {
- buffer[i+yoffset] =
- ( buffer[i+yoffset] & ~(mouse_and_mask[i] >> xoffset))
- | (mouse_or_mask[i] >> xoffset);
- }
- for (i=0; i<font_size; i++) {
- scp->mouse_cursor[i] = (buffer[i] & 0xff00) >> 8;
- scp->mouse_cursor[i+32] = buffer[i] & 0xff;
- scp->mouse_cursor[i+64] = (buffer[i+font_size] & 0xff00) >> 8;
- scp->mouse_cursor[i+96] = buffer[i+font_size] & 0xff;
- }
-
- scp->mouse_oldpos = scp->mouse_pos;
-
-#if 1
- /* wait for vertical retrace to avoid jitter on some videocards */
- crtc_addr = scp->adp->va_crtc_addr;
- while (!(inb(crtc_addr+6) & 0x08)) /* idle */ ;
-#endif
- font_loading_in_progress = TRUE;
- (*vidsw[scp->ad]->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));
- if (scp->mouse_xpos < (scp->xsize-1)*8) {
- writew(crt_pos + 2, (*(scp->mouse_pos + 1) & 0xff00) | (SC_MOUSE_CHAR + 1));
- writew(crt_pos+2*scp->xsize + 2,
- (*(scp->mouse_pos + scp->xsize + 1) & 0xff00) | (SC_MOUSE_CHAR + 3));
- }
- mark_for_update(scp, scp->mouse_pos - scp->scr_buf);
- mark_for_update(scp, scp->mouse_pos + scp->xsize + 1 - scp->scr_buf);
-}
-
-static void
-remove_mouse_image(scr_stat *scp)
-{
- vm_offset_t crt_pos;
-
- if (!ISTEXTSC(scp))
- return;
-
- crt_pos = scp->adp->va_window + 2*(scp->mouse_oldpos - scp->scr_buf);
- 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));
- writew(crt_pos+2*scp->xsize+2, *(scp->mouse_oldpos+scp->xsize+1));
- mark_for_update(scp, scp->mouse_oldpos - scp->scr_buf);
- mark_for_update(scp, scp->mouse_oldpos + scp->xsize + 1 - scp->scr_buf);
-}
-
-static void
-draw_cutmarking(scr_stat *scp)
-{
- vm_offset_t crt_pos;
- u_short *ptr;
- u_short och, nch;
-
- crt_pos = scp->adp->va_window;
- for (ptr=scp->scr_buf; ptr<=(scp->scr_buf+(scp->xsize*scp->ysize)); ptr++) {
- nch = och = readw(crt_pos + 2*(ptr - scp->scr_buf));
- /* are we outside the selected area ? */
- if ( ptr < (scp->mouse_cut_start > scp->mouse_cut_end ?
- scp->mouse_cut_end : scp->mouse_cut_start) ||
- ptr >= (scp->mouse_cut_start > scp->mouse_cut_end ?
- scp->mouse_cut_start : scp->mouse_cut_end)) {
- if (ptr != scp->cursor_pos)
- nch = (och & 0xff) | (*ptr & 0xff00);
- }
- else {
- /* are we clear of the cursor image ? */
- if (ptr != scp->cursor_pos)
- nch = (och & 0x88ff) | (*ptr & 0x7000)>>4 | (*ptr & 0x0700)<<4;
- else {
- if (sc_flags & CHAR_CURSOR)
- nch = (och & 0x88ff)|(*ptr & 0x7000)>>4|(*ptr & 0x0700)<<4;
- else
- if (!(sc_flags & BLINK_CURSOR))
- nch = (och & 0xff) | (*ptr & 0xff00);
- }
- }
- if (nch != och)
- writew(crt_pos + 2*(ptr - scp->scr_buf), nch);
+ tp = VIRTUAL_TTY(scp->sc, scp->sc->cur_scp->index);
+ rmap = scp->sc->scr_rmap;
+ for (; count > 0; --count)
+ (*linesw[tp->t_line].l_rint)(rmap[*p++], tp);
}
}
-
-static void
-remove_cutmarking(scr_stat *scp)
-{
- scp->mouse_cut_start = scp->mouse_cut_end = NULL;
- scp->status &= ~MOUSE_CUTTING;
- mark_all(scp);
-}
+#endif /* SC_NO_CUTPASTE */
static void
do_bell(scr_stat *scp, int pitch, int duration)
@@ -4411,18 +4051,18 @@ do_bell(scr_stat *scp, int pitch, int duration)
if (cold || shutdown_in_progress)
return;
- if (scp != cur_console && (sc_flags & QUIET_BELL))
+ if (scp != scp->sc->cur_scp && (scp->sc->flags & SC_QUIET_BELL))
return;
- if (sc_flags & VISUAL_BELL) {
- if (blink_in_progress)
+ if (scp->sc->flags & SC_VISUAL_BELL) {
+ if (scp->sc->blink_in_progress)
return;
- blink_in_progress = 4;
- if (scp != cur_console)
- blink_in_progress += 2;
- blink_screen(cur_console);
+ scp->sc->blink_in_progress = 3;
+ if (scp != scp->sc->cur_scp)
+ scp->sc->blink_in_progress += 2;
+ blink_screen(scp->sc->cur_scp);
} else {
- if (scp != cur_console)
+ if (scp != scp->sc->cur_scp)
pitch *= 2;
sysbeep(pitch, duration);
}
@@ -4433,122 +4073,19 @@ blink_screen(void *arg)
{
scr_stat *scp = arg;
- if (!ISTEXTSC(scp) || (blink_in_progress <= 1)) {
- blink_in_progress = FALSE;
+ if (ISGRAPHSC(scp) || (scp->sc->blink_in_progress <= 1)) {
+ scp->sc->blink_in_progress = 0;
mark_all(scp);
- if (delayed_next_scr)
- switch_scr(scp, delayed_next_scr - 1);
+ scstart(VIRTUAL_TTY(scp->sc, scp->index));
+ if (scp->sc->delayed_next_scr)
+ switch_scr(scp->sc, scp->sc->delayed_next_scr - 1);
}
else {
- if (blink_in_progress & 1)
- fillw_io(kernel_default.std_color | scr_map[0x20],
- scp->adp->va_window,
- scp->xsize * scp->ysize);
- else
- fillw_io(kernel_default.rev_color | scr_map[0x20],
- scp->adp->va_window,
- scp->xsize * scp->ysize);
- blink_in_progress--;
+ (*scp->rndr->draw)(scp, 0, scp->xsize*scp->ysize,
+ scp->sc->blink_in_progress & 1);
+ scp->sc->blink_in_progress--;
timeout(blink_screen, scp, hz / 10);
}
}
-void
-sc_bcopy(scr_stat *scp, u_short *p, int from, int to, int mark)
-{
- u_char *font;
- vm_offset_t d;
- vm_offset_t e;
- u_char *f;
- int font_size;
- int line_length;
- int xsize;
- u_short bg;
- int i, j;
- u_char c;
-
- if (ISTEXTSC(scp)) {
- bcopy_toio(p + from, scp->adp->va_window + 2*from,
- (to - from + 1)*sizeof(u_short));
- } else /* if ISPIXELSC(scp) */ {
- if (mark)
- 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 = scp->adp->va_window
- + scp->xoff + scp->yoff*font_size*line_length
- + (from%xsize) + font_size*line_length*(from/xsize);
-
- outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */
- outw(GDCIDX, 0x0003); /* data rotate/function select */
- outw(GDCIDX, 0x0f01); /* set/reset enable */
- bg = -1;
- for (i = from ; i <= to ; i++) {
- /* set background color in EGA/VGA latch */
- if (bg != (p[i] & 0xf000)) {
- bg = (p[i] & 0xf000);
- outw(GDCIDX, (bg >> 4) | 0x00); /* set/reset */
- outw(GDCIDX, 0xff08); /* bit mask */
- writeb(d, 0);
- c = readb(d); /* set the background color in the latch */
- }
- /* foreground color */
- outw(GDCIDX, (p[i] & 0x0f00) | 0x00); /* set/reset */
- e = d;
- f = &font[(p[i] & 0x00ff)*font_size];
- for (j = 0 ; j < font_size; j++, f++) {
- outw(GDCIDX, ((*f^mark) << 8) | 0x08); /* bit mask */
- writeb(e, 0);
- e += line_length;
- }
- d++;
- if ((i % xsize) == xsize - 1)
- d += scp->xoff*2 + (font_size - 1)*line_length;
- }
- outw(GDCIDX, 0x0000); /* set/reset */
- outw(GDCIDX, 0x0001); /* set/reset enable */
- outw(GDCIDX, 0xff08); /* bit mask */
-
-#if 0 /* VGA only */
- outw(GDCIDX, 0x0305); /* read mode 0, write mode 3 */
- outw(GDCIDX, 0x0003); /* data rotate/function select */
- outw(GDCIDX, 0x0f01); /* set/reset enable */
- outw(GDCIDX, 0xff08); /* bit mask */
- bg = -1;
- for (i = from ; i <= to ; i++) {
- /* set background color in EGA/VGA latch */
- if (bg != (p[i] & 0xf000)) {
- bg = (p[i] & 0xf000);
- outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */
- outw(GDCIDX, (bg >> 4) | 0x00); /* set/reset */
- *d = 0;
- c = *d; /* set the background color in the latch */
- outw(GDCIDX, 0x0305); /* read mode 0, write mode 3 */
- }
- /* foreground color */
- outw(GDCIDX, (p[i] & 0x0f00) | 0x00); /* set/reset */
- e = (u_char *)d;
- f = &font[(p[i] & 0x00ff)*font_size];
- for (j = 0 ; j < font_size; j++, f++) {
- *e = *f^mark;
- e += line_length;
- }
- d++;
- if ((i % xsize) == xsize - 1)
- d += scp->xoff*2 + (font_size - 1)*line_length;
- }
- outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */
- outw(GDCIDX, 0x0000); /* set/reset */
- outw(GDCIDX, 0x0001); /* set/reset enable */
-#endif /* 0 */
- }
-}
-
#endif /* NSC */
diff --git a/sys/dev/syscons/syscons.h b/sys/dev/syscons/syscons.h
index c8ba6cd..da48c7c 100644
--- a/sys/dev/syscons/syscons.h
+++ b/sys/dev/syscons/syscons.h
@@ -25,21 +25,51 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: syscons.h,v 1.46 1999/01/19 11:31:19 yokota Exp $
+ * $Id: syscons.h,v 1.47 1999/04/12 13:34:56 des Exp $
*/
#ifndef _DEV_SYSCONS_SYSCONS_H_
#define _DEV_SYSCONS_SYSCONS_H_
-/* vm things */
-#define ISMAPPED(pa, width) \
- (((pa) <= (u_long)0x1000 - (width)) \
- || ((pa) >= 0xa0000 && (pa) <= 0x100000 - (width)))
-#define pa_to_va(pa) (KERNBASE + (pa)) /* works if ISMAPPED(pa...) */
+/* machine-dependent part of the header */
+
+#ifdef PC98
+#include <pc98/pc98/sc_machdep.h>
+#elif defined(__i386__)
+/* nothing for the moment */
+#elif defined(__alpha__)
+/* nothing for the moment */
+#endif
+
+/* default values for configuration options */
+
+#ifndef MAXCONS
+#define MAXCONS 16
+#endif
+
+#ifdef SC_NO_SYSMOUSE
+#undef SC_NO_CUTPASTE
+#define SC_NO_CUTPASTE 1
+#endif
+
+#ifdef SC_NO_MODE_CHANGE
+#undef SC_PIXEL_MODE
+#endif
+
+#ifndef SC_DEBUG_LEVEL
+#define SC_DEBUG_LEVEL 0
+#endif
+
+#define DPRINTF(l, p) if (SC_DEBUG_LEVEL >= (l)) printf p
+
+#define SC_DRIVER_NAME "sc"
+#define SC_VTY(dev) minor(dev)
/* printable chars */
+#ifndef PRINTABLE
#define PRINTABLE(ch) ((ch) > 0x1b || ((ch) > 0x0d && (ch) < 0x1b) \
|| (ch) < 0x07)
+#endif
/* macros for "intelligent" screen update */
#define mark_for_update(scp, x) {\
@@ -51,33 +81,20 @@
scp->end = scp->xsize * scp->ysize - 1;\
}
-/* status flags */
+/* vty status flags (scp->status) */
#define UNKNOWN_MODE 0x00010
#define SWITCH_WAIT_REL 0x00080
#define SWITCH_WAIT_ACQ 0x00100
#define BUFFER_SAVED 0x00200
#define CURSOR_ENABLED 0x00400
-#define MOUSE_ENABLED 0x00800
#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
-#define BLINK_CURSOR 0x00002
-#define CHAR_CURSOR 0x00004
-/* these options are now obsolete; use corresponding options for kbd driver */
-#if 0
-#define DETECT_KBD 0x00008
-#define XT_KEYBD 0x00010
-#define KBD_NORESET 0x00020
-#endif
-#define QUIET_BELL 0x00040
-#define VESA800X600 0x00080
-#define AUTODETECT_KBD 0x00100
+#define VR_CURSOR_BLINK 0x40000
+#define VR_CURSOR_ON 0x80000
/* attribute flags */
#define NORMAL_ATTR 0x00
@@ -96,8 +113,6 @@
#define SAVE 0
#define COL 80
#define ROW 25
-#define BELL_DURATION 5
-#define BELL_PITCH 800
#define CONSOLE_BUFSIZE 1024
#define PCBURST 128
#define FONT_NONE 1
@@ -105,6 +120,11 @@
#define FONT_14 4
#define FONT_16 8
+#ifndef BELL_DURATION
+#define BELL_DURATION 5
+#define BELL_PITCH 800
+#endif
+
/* special characters */
#define cntlc 0x03
#define cntld 0x04
@@ -115,6 +135,23 @@
#define DEAD_CHAR 0x07 /* char used for cursor */
+/* virtual terminal buffer */
+typedef struct sc_vtb {
+ int vtb_flags;
+#define VTB_VALID (1 << 0)
+ int vtb_type;
+#define VTB_INVALID 0
+#define VTB_MEMORY 1
+#define VTB_FRAMEBUFFER 2
+#define VTB_RINGBUFFER 3
+ int vtb_cols;
+ int vtb_rows;
+ int vtb_size;
+ vm_offset_t vtb_buffer;
+ int vtb_tail; /* valid for VTB_RINGBUFFER only */
+} sc_vtb_t;
+
+/* terminal status */
typedef struct term_stat {
int esc; /* processing escape sequence */
int num_param; /* # of parameters to ESC */
@@ -127,10 +164,89 @@ typedef struct term_stat {
int rev_color; /* reverse hardware color */
} term_stat;
+/* softc */
+
+struct keyboard;
+struct video_adapter;
+struct scr_stat;
+struct tty;
+
+typedef struct sc_softc {
+ int unit; /* unit # */
+ int config; /* configuration flags */
+#define SC_VESA800X600 (1 << 7)
+#define SC_AUTODETECT_KBD (1 << 8)
+#define SC_KERNEL_CONSOLE (1 << 9)
+
+ int flags; /* status flags */
+#define SC_VISUAL_BELL (1 << 0)
+#define SC_QUIET_BELL (1 << 1)
+#define SC_BLINK_CURSOR (1 << 2)
+#define SC_CHAR_CURSOR (1 << 3)
+#define SC_MOUSE_ENABLED (1 << 4)
+#define SC_SCRN_IDLE (1 << 5)
+#define SC_SCRN_BLANKED (1 << 6)
+#define SC_SAVER_FAILED (1 << 7)
+
+#define SC_INIT_DONE (1 << 16)
+#define SC_SPLASH_SCRN (1 << 17)
+
+ int keyboard; /* -1 if unavailable */
+ struct keyboard *kbd;
+
+ int adapter;
+ struct video_adapter *adp;
+ int initial_mode; /* initial video mode */
+
+ int first_vty;
+ int vtys;
+ struct tty *tty;
+ struct scr_stat **console;
+ struct scr_stat *cur_scp;
+ struct scr_stat *new_scp;
+ struct scr_stat *old_scp;
+ int delayed_next_scr;
+
+ void **devfs_token;
+
+ char font_loading_in_progress;
+ char switch_in_progress;
+ char videoio_in_progress;
+ char write_in_progress;
+ char blink_in_progress;
+
+ long scrn_time_stamp;
+
+ char cursor_base;
+ char cursor_height;
+
+ u_char scr_map[256];
+ u_char scr_rmap[256];
+
+#ifdef _SC_MD_SOFTC_DECLARED_
+ sc_md_softc_t md; /* machine dependent vars */
+#endif
+
+#ifndef SC_NO_PALETTE_LOADING
+ u_char palette[256*3];
+#endif
+
+#ifndef SC_NO_FONT_LOADING
+ int fonts_loaded;
+ u_char *font_8;
+ u_char *font_14;
+ u_char *font_16;
+#endif
+
+} sc_softc_t;
+
+/* virtual screen */
typedef struct scr_stat {
- int ad; /* video adapter index */
- video_adapter_t *adp; /* video adapter structure */
- u_short *scr_buf; /* buffer when off screen */
+ int index; /* index of this vty */
+ struct sc_softc *sc; /* pointer to softc */
+ struct sc_rndr_sw *rndr; /* renderer */
+ sc_vtb_t scr;
+ sc_vtb_t vtb;
int xpos; /* current X position */
int ypos; /* current Y position */
int saved_xpos; /* saved X position */
@@ -141,25 +257,26 @@ typedef struct scr_stat {
int ypixel; /* Y graphics size */
int xoff; /* X offset in pixel mode */
int yoff; /* Y offset in pixel mode */
+ u_char *font; /* current font */
int font_size; /* fontsize in Y direction */
int start; /* modified area start */
int end; /* modified area end */
term_stat term; /* terminal emulation stuff */
int status; /* status (bitfield) */
int kbd_mode; /* keyboard I/O mode */
- u_short *cursor_pos; /* cursor buffer position */
- u_short *cursor_oldpos; /* cursor old buffer position */
- u_short cursor_saveunder; /* saved chars under cursor */
- char cursor_start; /* cursor start line # */
- char cursor_end; /* cursor end line # */
- u_short *mouse_pos; /* mouse buffer position */
- u_short *mouse_oldpos; /* mouse old buffer position */
+ int cursor_pos; /* cursor buffer position */
+ int cursor_oldpos; /* cursor old buffer position */
+ u_short cursor_saveunder_char; /* saved char under cursor */
+ u_short cursor_saveunder_attr; /* saved attr under cursor */
+ char cursor_base; /* cursor base line # */
+ char cursor_height; /* cursor height */
+ int mouse_pos; /* mouse buffer position */
+ int mouse_oldpos; /* mouse old buffer position */
short mouse_xpos; /* mouse x coordinate */
short mouse_ypos; /* mouse y coordinate */
short mouse_buttons; /* mouse buttons */
- u_char mouse_cursor[128]; /* mouse cursor bitmap store */
- u_short *mouse_cut_start; /* mouse cut start pos */
- u_short *mouse_cut_end; /* mouse cut end pos */
+ int mouse_cut_start; /* mouse cut start pos */
+ int mouse_cut_end; /* mouse cut end pos */
struct proc *mouse_proc; /* proc* of controlling proc */
pid_t mouse_pid; /* pid of controlling proc */
int mouse_signal; /* signal # to report with */
@@ -170,16 +287,14 @@ typedef struct scr_stat {
pid_t pid; /* pid of controlling proc */
struct proc *proc; /* proc* of controlling proc */
struct vt_mode smode; /* switch mode */
- u_short *history; /* circular history buffer */
- u_short *history_head; /* current head position */
- u_short *history_pos; /* position shown on screen */
- u_short *history_save; /* save area index */
+ sc_vtb_t *history; /* circular history buffer */
+ int history_pos; /* position shown on screen */
int history_size; /* size of history buffer */
-#ifdef __i386__
- struct apmhook r_hook; /* reconfiguration support */
-#endif
int splash_save_mode; /* saved mode for splash screen */
int splash_save_status; /* saved status for splash screen */
+#ifdef _SCR_MD_STAT_DECLARED_
+ scr_md_stat_t md; /* machine dependent vars */
+#endif
} scr_stat;
typedef struct default_attr {
@@ -187,7 +302,63 @@ typedef struct default_attr {
int rev_color; /* reverse hardware color */
} default_attr;
+#ifndef SC_NORM_ATTR
+#define SC_NORM_ATTR (FG_LIGHTGREY | BG_BLACK)
+#endif
+#ifndef SC_NORM_REV_ATTR
+#define SC_NORM_REV_ATTR (FG_BLACK | BG_LIGHTGREY)
+#endif
+#ifndef SC_KERNEL_CONS_ATTR
+#define SC_KERNEL_CONS_ATTR (FG_WHITE | BG_BLACK)
+#endif
+#ifndef SC_KERNEL_CONS_REV_ATTR
+#define SC_KERNEL_CONS_REV_ATTR (FG_BLACK | BG_LIGHTGREY)
+#endif
+
+/* renderer function table */
+typedef void vr_clear_t(scr_stat *scp, int c, int attr);
+typedef void vr_draw_border_t(scr_stat *scp, int color);
+typedef void vr_draw_t(scr_stat *scp, int from, int count, int flip);
+typedef void vr_set_cursor_t(scr_stat *scp, int base, int height, int blink);
+typedef void vr_draw_cursor_t(scr_stat *scp, int at, int blink,
+ int on, int flip);
+typedef void vr_blink_cursor_t(scr_stat *scp, int at, int flip);
+typedef void vr_set_mouse_t(scr_stat *scp);
+typedef void vr_draw_mouse_t(scr_stat *scp, int x, int y, int on);
+
+typedef struct sc_rndr_sw {
+ vr_clear_t *clear;
+ vr_draw_border_t *draw_border;
+ vr_draw_t *draw;
+ vr_set_cursor_t *set_cursor;
+ vr_draw_cursor_t *draw_cursor;
+ vr_blink_cursor_t *blink_cursor;
+ vr_set_mouse_t *set_mouse;
+ vr_draw_mouse_t *draw_mouse;
+} sc_rndr_sw_t;
+
+typedef struct sc_renderer {
+ char *name;
+ int mode;
+ sc_rndr_sw_t *rndrsw;
+} sc_renderer_t;
+
+#define RENDERER(name, mode, sw) \
+ static struct sc_renderer name##_##mode##_renderer = { \
+ #name, mode, &sw \
+ }; \
+ DATA_SET(scrndr_set, name##_##mode##_renderer)
+extern struct linker_set scrndr_set;
+
+typedef struct {
+ int cursor_start;
+ int cursor_end;
+ int shift_state;
+ int bell_pitch;
+} bios_values_t;
+
+/* other macros */
#define ISTEXTSC(scp) (!((scp)->status \
& (UNKNOWN_MODE | GRAPHICS_MODE | PIXEL_MODE)))
#define ISGRAPHSC(scp) (((scp)->status \
@@ -197,41 +368,143 @@ typedef struct default_attr {
== PIXEL_MODE)
#define ISUNKNOWNSC(scp) ((scp)->status & UNKNOWN_MODE)
-#define ISFONTAVAIL(af) ((af) & V_ADP_FONT)
+#ifndef ISMOUSEAVAIL
+#ifdef SC_ALT_MOUSE_IMAGE
+#define ISMOUSEAVAIL(af) (1)
+#else
#define ISMOUSEAVAIL(af) ((af) & V_ADP_FONT)
+#endif /* SC_ALT_MOUSE_IMAGE */
+#define ISFONTAVAIL(af) ((af) & V_ADP_FONT)
#define ISPALAVAIL(af) ((af) & V_ADP_PALETTE)
+#endif /* ISMOUSEAVAIL */
-/* misc prototypes used by different syscons related LKM's */
+#define ISSIGVALID(sig) ((sig) > 0 && (sig) < NSIG)
+
+#define kbd_read_char(kbd, wait) \
+ (*kbdsw[(kbd)->kb_index]->read_char)((kbd), (wait))
+#define kbd_check_char(kbd) \
+ (*kbdsw[(kbd)->kb_index]->check_char)((kbd))
+#define kbd_enable(kbd) \
+ (*kbdsw[(kbd)->kb_index]->enable)((kbd))
+#define kbd_disable(kbd) \
+ (*kbdsw[(kbd)->kb_index]->disable)((kbd))
+#define kbd_lock(kbd, lockf) \
+ (*kbdsw[(kbd)->kb_index]->lock)((kbd), (lockf))
+#define kbd_ioctl(kbd, cmd, arg) \
+ (((kbd) == NULL) ? \
+ ENODEV : (*kbdsw[(kbd)->kb_index]->ioctl)((kbd), (cmd), (arg)))
+#define kbd_clear_state(kbd) \
+ (*kbdsw[(kbd)->kb_index]->clear_state)((kbd))
+#define kbd_get_fkeystr(kbd, fkey, len) \
+ (*kbdsw[(kbd)->kb_index]->get_fkeystr)((kbd), (fkey), (len))
+#define kbd_poll(kbd, on) \
+ (*kbdsw[(kbd)->kb_index]->poll)((kbd), (on))
/* syscons.c */
-int sc_probe_unit(int unit, int flags);
-int sc_attach_unit(int unit, int flags);
+extern int (*sc_user_ioctl)(dev_t dev, u_long cmd, caddr_t data,
+ int flag, struct proc *p);
+
+int sc_probe_unit(int unit, int flags);
+int sc_attach_unit(int unit, int flags);
+int sc_resume_unit(int unit);
-extern int (*sc_user_ioctl)(dev_t dev, u_long cmd, caddr_t data, int flag,
- struct proc *p);
+int set_mode(scr_stat *scp);
+scr_stat *sc_get_scr_stat(dev_t dev);
-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);
+void set_border(scr_stat *scp, int color);
-void copy_font(scr_stat *scp, int operation, int font_size, u_char *font_image);
-void set_border(scr_stat *scp, int color);
+void sc_touch_scrn_saver(void);
+void sc_clear_screen(scr_stat *scp);
+void sc_set_cursor_image(scr_stat *scp);
+int sc_clean_up(scr_stat *scp);
+void sc_alloc_scr_buffer(scr_stat *scp, int wait, int discard);
+struct tty *scdevtotty(dev_t dev);
+#ifndef SC_NO_SYSMOUSE
+struct tty *sc_get_mouse_tty(void);
+#endif /* SC_NO_SYSMOUSE */
+#ifndef SC_NO_CUTPASTE
+void sc_paste(scr_stat *scp, u_char *p, int count);
+#endif /* SC_NO_CUTPASTE */
-void sc_touch_scrn_saver(void);
-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);
-struct tty *scdevtotty(dev_t dev);
+/* schistory.c */
+#ifndef SC_NO_HISTORY
+int sc_alloc_history_buffer(scr_stat *scp, int lines, int wait);
+void sc_hist_save(scr_stat *scp);
+#define sc_hist_save_one_line(scp, from) \
+ sc_vtb_append(&(scp)->vtb, (from), (scp)->history, (scp)->xsize)
+int sc_hist_restore(scr_stat *scp);
+void sc_hist_home(scr_stat *scp);
+void sc_hist_end(scr_stat *scp);
+int sc_hist_up_line(scr_stat *scp);
+int sc_hist_down_line(scr_stat *scp);
+int sc_hist_ioctl(struct tty *tp, u_long cmd, caddr_t data,
+ int flag, struct proc *p);
+#endif /* SC_NO_HISTORY */
+
+/* scmouse.c */
+#ifndef SC_NO_CUTPASTE
+void sc_alloc_cut_buffer(scr_stat *scp, int wait);
+void sc_draw_mouse_image(scr_stat *scp);
+void sc_remove_mouse_image(scr_stat *scp);
+int sc_inside_cutmark(scr_stat *scp, int pos);
+void sc_remove_cutmarking(scr_stat *scp);
+void sc_remove_all_cutmarkings(sc_softc_t *scp);
+void sc_remove_all_mouse(sc_softc_t *scp);
+#else
+#define sc_inside_cutmark(scp, pos) FALSE
+#define sc_remove_cutmarking(scp)
+#endif /* SC_NO_CUTPASTE */
+#ifndef SC_NO_SYSMOUSE
+void sc_mouse_set_level(int level);
+void sc_mouse_move(scr_stat *scp, int x, int y);
+int sc_mouse_ioctl(struct tty *tp, u_long cmd, caddr_t data,
+ int flag, struct proc *p);
+#endif /* SC_NO_SYSMOUSE */
/* 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);
+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);
+sc_rndr_sw_t *sc_render_match(scr_stat *scp, video_adapter_t *adp, int mode);
+int sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag,
+ struct proc *p);
+
+/* scvtb.c */
+void sc_vtb_init(sc_vtb_t *vtb, int type, int cols, int rows,
+ void *buffer, int wait);
+void sc_vtb_destroy(sc_vtb_t *vtb);
+size_t sc_vtb_size(int cols, int rows);
+void sc_vtb_clear(sc_vtb_t *vtb, int c, int attr);
+
+int sc_vtb_getc(sc_vtb_t *vtb, int at);
+int sc_vtb_geta(sc_vtb_t *vtb, int at);
+void sc_vtb_putc(sc_vtb_t *vtb, int at, int c, int a);
+vm_offset_t sc_vtb_putchar(sc_vtb_t *vtb, vm_offset_t p, int c, int a);
+vm_offset_t sc_vtb_pointer(sc_vtb_t *vtb, int at);
+int sc_vtb_pos(sc_vtb_t *vtb, int pos, int offset);
+
+#define sc_vtb_tail(vtb) ((vtb)->vtb_tail)
+#define sc_vtb_rows(vtb) ((vtb)->vtb_rows)
+
+void sc_vtb_copy(sc_vtb_t *vtb1, int from, sc_vtb_t *vtb2, int to,
+ int count);
+void sc_vtb_append(sc_vtb_t *vtb1, int from, sc_vtb_t *vtb2,
+ int count);
+void sc_vtb_seek(sc_vtb_t *vtb, int pos);
+void sc_vtb_erase(sc_vtb_t *vtb, int at, int count, int c, int attr);
+void sc_vtb_delete(sc_vtb_t *vtb, int at, int count, int c, int attr);
+void sc_vtb_ins(sc_vtb_t *vtb, int at, int count, int c, int attr);
+
+/* machine dependent functions */
+int sc_max_unit(void);
+sc_softc_t *sc_get_softc(int unit, int flags);
+sc_softc_t *sc_find_softc(struct video_adapter *adp, struct keyboard *kbd);
+int sc_get_cons_priority(int *unit, int *flags);
+void sc_get_bios_values(bios_values_t *values);
+int sc_tone(int herz);
#endif /* !_DEV_SYSCONS_SYSCONS_H_ */
diff --git a/sys/dev/syscons/warp/warp_saver.c b/sys/dev/syscons/warp/warp_saver.c
index 3476c36..cd6f42b 100644
--- a/sys/dev/syscons/warp/warp_saver.c
+++ b/sys/dev/syscons/warp/warp_saver.c
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: warp_saver.c,v 1.4 1999/01/11 03:18:55 yokota Exp $
+ * $Id: warp_saver.c,v 1.5 1999/04/12 13:34:58 des Exp $
*/
#include <sys/param.h>
@@ -33,11 +33,14 @@
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/syslog.h>
+#include <sys/consio.h>
+#include <sys/fbio.h>
-#include <machine/md_var.h>
#include <machine/random.h>
-#include <saver.h>
+#include <dev/fb/fbreg.h>
+#include <dev/fb/splashreg.h>
+#include <dev/syscons/syscons.h>
static u_char *vid;
static int blanked;
diff --git a/sys/i386/conf/LINT b/sys/i386/conf/LINT
index 5563146..cc51183 100644
--- a/sys/i386/conf/LINT
+++ b/sys/i386/conf/LINT
@@ -2,7 +2,7 @@
# LINT -- config file for checking all the sources, tries to pull in
# as much of the source tree as it can.
#
-# $Id: LINT,v 1.606 1999/06/15 13:14:40 des Exp $
+# $Id: LINT,v 1.607 1999/06/19 20:20:52 rnordier Exp $
#
# NB: You probably don't want to try running a kernel built from this
# file. Instead, you should start from GENERIC, and add options from
@@ -912,6 +912,9 @@ options VGA_NO_MODE_CHANGE # don't change video modes
# Older video cards may require this option for proper operation.
options VGA_SLOW_IOACCESS # do byte-wide i/o's to TS and GDC regs
+# The following option probably won't work with the LCD displays.
+options VGA_WIDTH90 # support 90 column modes
+
# To include support for VESA video modes
options VESA
@@ -939,18 +942,20 @@ options PCVT_VT220KEYB
# The syscons console driver (sco color console compatible).
device sc0 at isa?
options MAXCONS=16 # number of virtual consoles
-options STD8X16FONT # Compile font in
-makeoptions STD8X16FONT=cp850
-options SC_HISTORY_SIZE=200 # number of history buffer lines
+options SC_ALT_MOUSE_IMAGE # simplified mouse cursor in text mode
+options SC_DFLT_FONT # compile font in
+makeoptions SC_DFLT_FONT="cp850"
+options SC_DISABLE_DDBKEY # disable `debug' key
options SC_DISABLE_REBOOT # disable reboot key sequence
+options SC_HISTORY_SIZE=200 # number of history buffer lines
+options SC_MOUSE_CHAR=0x3 # char code for text mode mouse cursor
+options SC_PIXEL_MODE # add support for the raster text mode
-#
-# `flags' for sc0:
-# 0x01 Use a 'visual' bell
-# 0x02 Use a 'blink' cursor
-# 0x04 Use a 'underline' cursor
-# 0x06 Use a 'blinking underline' (destructive) cursor
-# 0x40 Make the bell quiet if it is rung in the background vty.
+# You can selectively disable features in syscons.
+options SC_NO_CUTPASTE
+options SC_NO_FONT_LOADING
+options SC_NO_HISTORY
+options SC_NO_SYSMOUSE
#
# The Numeric Processing eXtension driver. This should be configured if
@@ -2155,6 +2160,10 @@ options ULPT_DEBUG
options UMASS_DEBUG
options UMS_DEBUG
+# options for ukbd:
+options UKBD_DFLT_KEYMAP # specify the built-in keymap
+makeoptions UKBD_DFLT_KEYMAP="it.iso"
+
#
# Embedded system options:
#
diff --git a/sys/i386/conf/NOTES b/sys/i386/conf/NOTES
index 5563146..cc51183 100644
--- a/sys/i386/conf/NOTES
+++ b/sys/i386/conf/NOTES
@@ -2,7 +2,7 @@
# LINT -- config file for checking all the sources, tries to pull in
# as much of the source tree as it can.
#
-# $Id: LINT,v 1.606 1999/06/15 13:14:40 des Exp $
+# $Id: LINT,v 1.607 1999/06/19 20:20:52 rnordier Exp $
#
# NB: You probably don't want to try running a kernel built from this
# file. Instead, you should start from GENERIC, and add options from
@@ -912,6 +912,9 @@ options VGA_NO_MODE_CHANGE # don't change video modes
# Older video cards may require this option for proper operation.
options VGA_SLOW_IOACCESS # do byte-wide i/o's to TS and GDC regs
+# The following option probably won't work with the LCD displays.
+options VGA_WIDTH90 # support 90 column modes
+
# To include support for VESA video modes
options VESA
@@ -939,18 +942,20 @@ options PCVT_VT220KEYB
# The syscons console driver (sco color console compatible).
device sc0 at isa?
options MAXCONS=16 # number of virtual consoles
-options STD8X16FONT # Compile font in
-makeoptions STD8X16FONT=cp850
-options SC_HISTORY_SIZE=200 # number of history buffer lines
+options SC_ALT_MOUSE_IMAGE # simplified mouse cursor in text mode
+options SC_DFLT_FONT # compile font in
+makeoptions SC_DFLT_FONT="cp850"
+options SC_DISABLE_DDBKEY # disable `debug' key
options SC_DISABLE_REBOOT # disable reboot key sequence
+options SC_HISTORY_SIZE=200 # number of history buffer lines
+options SC_MOUSE_CHAR=0x3 # char code for text mode mouse cursor
+options SC_PIXEL_MODE # add support for the raster text mode
-#
-# `flags' for sc0:
-# 0x01 Use a 'visual' bell
-# 0x02 Use a 'blink' cursor
-# 0x04 Use a 'underline' cursor
-# 0x06 Use a 'blinking underline' (destructive) cursor
-# 0x40 Make the bell quiet if it is rung in the background vty.
+# You can selectively disable features in syscons.
+options SC_NO_CUTPASTE
+options SC_NO_FONT_LOADING
+options SC_NO_HISTORY
+options SC_NO_SYSMOUSE
#
# The Numeric Processing eXtension driver. This should be configured if
@@ -2155,6 +2160,10 @@ options ULPT_DEBUG
options UMASS_DEBUG
options UMS_DEBUG
+# options for ukbd:
+options UKBD_DFLT_KEYMAP # specify the built-in keymap
+makeoptions UKBD_DFLT_KEYMAP="it.iso"
+
#
# Embedded system options:
#
diff --git a/sys/i386/conf/files.i386 b/sys/i386/conf/files.i386
index 44c115c..ae19e96 100644
--- a/sys/i386/conf/files.i386
+++ b/sys/i386/conf/files.i386
@@ -1,7 +1,7 @@
# This file tells config what files go into building a kernel,
# files marked standard are always included.
#
-# $Id: files.i386,v 1.246 1999/06/01 18:18:38 jlemon Exp $
+# $Id: files.i386,v 1.247 1999/06/18 19:55:50 green Exp $
#
# The long compile-with and dependency lines are required because of
# limitations in config: backslash-newline doesn't work in strings, and
@@ -19,10 +19,10 @@ linux_assym.h optional compat_linux \
no-obj no-implicit-rule before-depend \
clean "linux_assym.h"
#
-font8x16.o optional std8x16font \
- compile-with "uudecode < /usr/share/syscons/fonts/${STD8X16FONT}-8x16.fnt && file2c 'unsigned char font_16[16*256] = {' '};' < ${STD8X16FONT}-8x16 > font8x16.c && ${CC} -c ${CFLAGS} font8x16.c" \
- no-implicit-rule before-depend \
- clean "${STD8X16FONT}-8x16 font8x16.c"
+font.h optional sc_dflt_font \
+ compile-with "uudecode < /usr/share/syscons/fonts/${SC_DFLT_FONT}-8x16.fnt && file2c 'static u_char dflt_font_16[16*256] = {' '};' < ${SC_DFLT_FONT}-8x16 > font.h && uudecode < /usr/share/syscons/fonts/${SC_DFLT_FONT}-8x14.fnt && file2c 'static u_char dflt_font_14[14*256] = {' '};' < ${SC_DFLT_FONT}-8x14 >> font.h && uudecode < /usr/share/syscons/fonts/${SC_DFLT_FONT}-8x8.fnt && file2c 'static u_char dflt_font_8[8*256] = {' '};' < ${SC_DFLT_FONT}-8x8 >> font.h" \
+ no-obj no-implicit-rule before-depend \
+ clean "font.h"
#
atkbdmap.h optional atkbd_dflt_keymap \
compile-with "kbdcontrol -L ${ATKBD_DFLT_KEYMAP} | sed -e 's/^static keymap_t.* = /static keymap_t key_map = /' -e 's/^static accentmap_t.* = /static accentmap_t accent_map = /' > atkbdmap.h" \
@@ -44,14 +44,19 @@ dev/ata/atapi-tape.c optional atapist device-driver
dev/fb/fb.c optional fb device-driver
dev/fb/fb.c optional vga device-driver
dev/fb/splash.c optional splash
+dev/fb/vga.c optional vga device-driver
dev/kbd/atkbd.c optional atkbd device-driver
dev/kbd/atkbdc.c optional atkbdc device-driver
dev/kbd/kbd.c optional atkbd device-driver
dev/kbd/kbd.c optional kbd device-driver
dev/kbd/kbd.c optional ukbd device-driver
dev/syscons/syscons.c optional sc device-driver
+dev/syscons/schistory.c optional sc device-driver
+dev/syscons/scmouse.c optional sc device-driver
dev/syscons/scvidctl.c optional sc device-driver
dev/syscons/scvesactl.c optional sc device-driver
+dev/syscons/scvgarndr.c optional sc device-driver
+dev/syscons/scvtb.c optional sc device-driver
i386/apm/apm.c optional apm device-driver
i386/apm/apm_setup.s optional apm
i386/eisa/dpt_eisa.c optional eisa dpt device-driver
diff --git a/sys/i386/conf/options.i386 b/sys/i386/conf/options.i386
index c3aa0d9..d7cc7b4 100644
--- a/sys/i386/conf/options.i386
+++ b/sys/i386/conf/options.i386
@@ -1,4 +1,4 @@
-# $Id: options.i386,v 1.116 1999/06/06 22:45:04 steve Exp $
+# $Id: options.i386,v 1.117 1999/06/15 13:14:43 des Exp $
DISABLE_PSE
IDE_DELAY
@@ -65,17 +65,30 @@ I586_CPU opt_global.h
I686_CPU opt_global.h
MAXCONS opt_syscons.h
-STD8X16FONT opt_syscons.h
-SC_HISTORY_SIZE opt_syscons.h
+SC_ALT_MOUSE_IMAGE opt_syscons.h
+SC_DEBUG_LEVEL opt_syscons.h
+SC_DFLT_FONT opt_syscons.h
+SC_DISABLE_DDBKEY opt_syscons.h
SC_DISABLE_REBOOT opt_syscons.h
+SC_HISTORY_SIZE opt_syscons.h
SC_MOUSE_CHAR opt_syscons.h
-
+SC_NO_CUTPASTE opt_syscons.h
+SC_NO_FONT_LOADING opt_syscons.h
+SC_NO_HISTORY opt_syscons.h
+SC_NO_SYSMOUSE opt_syscons.h
+SC_PIXEL_MODE opt_syscons.h
+SC_RENDER_DEBUG opt_syscons.h
+SC_VIDEO_DEBUG opt_syscons.h
+
+FB_DEBUG opt_fb.h
FB_INSTALL_CDEV opt_fb.h
VGA_ALT_SEQACCESS opt_vga.h
+VGA_DEBUG opt_vga.h
VGA_NO_FONT_LOADING opt_vga.h
VGA_NO_MODE_CHANGE opt_vga.h
VGA_SLOW_IOACCESS opt_vga.h
+VGA_WIDTH90 opt_vga.h
VESA opt_vesa.h
VESA_DEBUG opt_vesa.h
diff --git a/sys/i386/i386/cons.c b/sys/i386/i386/cons.c
index acc8503..cee6564 100644
--- a/sys/i386/i386/cons.c
+++ b/sys/i386/i386/cons.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* from: @(#)cons.c 7.2 (Berkeley) 5/9/91
- * $Id: cons.c,v 1.66 1999/05/30 16:52:03 phk Exp $
+ * $Id: cons.c,v 1.67 1999/05/31 11:25:41 phk Exp $
*/
#include "opt_devfs.h"
@@ -109,19 +109,19 @@ static struct tty *cn_tp; /* physical console tty struct */
static void *cn_devfs_token; /* represents the devfs entry */
#endif /* DEVFS */
-CONS_DRIVER(cons, NULL, NULL, NULL, NULL, NULL);
+CONS_DRIVER(cons, NULL, NULL, NULL, NULL, NULL, NULL);
void
cninit()
{
struct consdev *best_cp, *cp;
- struct consdev **list;
+ const struct consdev **list;
/*
* Find the first console with the highest priority.
*/
best_cp = NULL;
- list = (struct consdev **)cons_set.ls_items;
+ list = (const struct consdev **)cons_set.ls_items;
while ((cp = *list++) != NULL) {
if (cp->cn_probe == NULL)
continue;
@@ -147,6 +147,8 @@ cninit()
* If no console, give up.
*/
if (best_cp == NULL) {
+ if (cn_tab != NULL && cn_tab->cn_term != NULL)
+ (*cn_tab->cn_term)(cn_tab);
cn_tab = best_cp;
return;
}
@@ -154,10 +156,13 @@ cninit()
/*
* Initialize console, then attach to it. This ordering allows
* debugging using the previous console, if any.
- * XXX if there was a previous console, then its driver should
- * be informed when we forget about it.
*/
(*best_cp->cn_init)(best_cp);
+ if (cn_tab != NULL && cn_tab != best_cp) {
+ /* Turn off the previous console. */
+ if (cn_tab->cn_term != NULL)
+ (*cn_tab->cn_term)(cn_tab);
+ }
cn_tab = best_cp;
}
diff --git a/sys/i386/i386/cons.h b/sys/i386/i386/cons.h
index 1656b12..ea84d7e 100644
--- a/sys/i386/i386/cons.h
+++ b/sys/i386/i386/cons.h
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* from: @(#)cons.h 7.2 (Berkeley) 5/9/91
- * $Id: cons.h,v 1.18 1999/01/07 14:14:11 yokota Exp $
+ * $Id: cons.h,v 1.19 1999/01/09 14:07:37 bde Exp $
*/
#ifndef _MACHINE_CONS_H_
@@ -45,6 +45,7 @@
struct consdev;
typedef void cn_probe_t __P((struct consdev *));
typedef void cn_init_t __P((struct consdev *));
+typedef void cn_term_t __P((struct consdev *));
typedef int cn_getc_t __P((dev_t));
typedef int cn_checkc_t __P((dev_t));
typedef void cn_putc_t __P((dev_t, int));
@@ -54,6 +55,8 @@ struct consdev {
/* probe hardware and fill in consdev info */
cn_init_t *cn_init;
/* turn on as console */
+ cn_term_t *cn_term;
+ /* turn off as console */
cn_getc_t *cn_getc;
/* kernel getchar interface */
cn_checkc_t *cn_checkc;
@@ -75,10 +78,10 @@ struct consdev {
extern struct linker_set cons_set;
extern int cons_unavail;
-#define CONS_DRIVER(name, probe, init, getc, checkc, putc) \
- static struct consdev name##_consdev = { \
- probe, init, getc, checkc, putc \
- }; \
+#define CONS_DRIVER(name, probe, init, term, getc, checkc, putc) \
+ static struct consdev name##_consdev = { \
+ probe, init, term, getc, checkc, putc \
+ }; \
DATA_SET(cons_set, name##_consdev)
/* Other kernel entry points. */
diff --git a/sys/i386/include/console.h b/sys/i386/include/console.h
index 54409d0..79a6b57 100644
--- a/sys/i386/include/console.h
+++ b/sys/i386/include/console.h
@@ -1,635 +1,8 @@
-/*-
- * Copyright (c) 1991-1996 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.
- * 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 AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $Id: console.h,v 1.44 1999/02/05 11:52:09 yokota Exp $
- */
+#ifndef _MACHINE_CONSOLE_H_
+#define _MACHINE_CONSOLE_H_
-#ifndef _MACHINE_CONSOLE_H_
-#define _MACHINE_CONSOLE_H_
-
-#ifndef KERNEL
-#include <sys/types.h>
-#endif
-#include <sys/ioccom.h>
-
-#define KDGKBMODE _IOR('K', 6, int)
-#define KDSKBMODE _IO('K', 7 /*, int */)
-#define KDMKTONE _IO('K', 8 /*, int */)
-#define KDGETMODE _IOR('K', 9, int)
-#define KDSETMODE _IO('K', 10 /*, int */)
-#define KDSBORDER _IO('K', 13 /*, int */)
-#define KDGKBSTATE _IOR('K', 19, int)
-#define KDSKBSTATE _IO('K', 20 /*, int */)
-#define KDENABIO _IO('K', 60)
-#define KDDISABIO _IO('K', 61)
-#define KIOCSOUND _IO('K', 63 /*, int */)
-#define KDGKBTYPE _IOR('K', 64, int)
-#define KDGETLED _IOR('K', 65, int)
-#define KDSETLED _IO('K', 66 /*, int */)
-#define KDSETRAD _IO('K', 67 /*, int */) /* obsolete */
-#define KDRASTER _IOW('K', 100, scr_size_t)
-#define KDGKBINFO _IOR('K', 101, keyboard_info_t)
-#define KDSETREPEAT _IOW('K', 102, keyboard_delay_t)
-
-#define GETFKEY _IOWR('k', 0, fkeyarg_t)
-#define SETFKEY _IOWR('k', 1, fkeyarg_t)
-#define GIO_SCRNMAP _IOR('k', 2, scrmap_t)
-#define PIO_SCRNMAP _IOW('k', 3, scrmap_t)
-#define GIO_KEYMAP _IOR('k', 6, keymap_t)
-#define PIO_KEYMAP _IOW('k', 7, keymap_t)
-#define GIO_DEADKEYMAP _IOR('k', 8, accentmap_t)
-#define PIO_DEADKEYMAP _IOW('k', 9, accentmap_t)
-#define GIO_KEYMAPENT _IOWR('k', 10, keyarg_t)
-#define PIO_KEYMAPENT _IOW('k', 11, keyarg_t)
-
-#define GIO_ATTR _IOR('a', 0, int)
-#define GIO_COLOR _IOR('c', 0, int)
-#define CONS_CURRENT _IOR('c', 1, int)
-#define CONS_GET _IOR('c', 2, int)
-#define CONS_IO _IO('c', 3)
-#define CONS_BLANKTIME _IOW('c', 4, int)
-#define CONS_SSAVER _IOW('c', 5, ssaver_t)
-#define CONS_GSAVER _IOWR('c', 6, ssaver_t)
-#define CONS_CURSORTYPE _IOW('c', 7, int)
-#define CONS_BELLTYPE _IOW('c', 8, int)
-#define CONS_HISTORY _IOW('c', 9, int)
-#define CONS_MOUSECTL _IOWR('c', 10, mouse_info_t)
-#define CONS_IDLE _IOR('c', 11, int)
-#define CONS_SAVERMODE _IOW('c', 12, int)
-#define CONS_SAVERSTART _IOW('c', 13, int)
-#define PIO_FONT8x8 _IOW('c', 64, fnt8_t)
-#define GIO_FONT8x8 _IOR('c', 65, fnt8_t)
-#define PIO_FONT8x14 _IOW('c', 66, fnt14_t)
-#define GIO_FONT8x14 _IOR('c', 67, fnt14_t)
-#define PIO_FONT8x16 _IOW('c', 68, fnt16_t)
-#define GIO_FONT8x16 _IOR('c', 69, fnt16_t)
-#define CONS_GETINFO _IOWR('c', 73, vid_info_t)
-#define CONS_GETVERS _IOR('c', 74, int)
-#define CONS_CURRENTADP _IOR('c', 100, int)
-#define CONS_ADPINFO _IOWR('c', 101, video_adapter_info_t)
-#define CONS_MODEINFO _IOWR('c', 102, video_info_t)
-#define CONS_FINDMODE _IOWR('c', 103, video_info_t)
-#define CONS_SETWINORG _IO('c', 104 /* u_int */)
-
-#define CONS_SETKBD _IO('c', 110 /* int */)
-#define CONS_RELKBD _IO('c', 111)
-
-/* CONS_SAVERMODE */
-#define CONS_LKM_SAVER 0
-#define CONS_USR_SAVER 1
-
-#ifdef PC98
-#define ADJUST_CLOCK _IO('t',100) /* for 98note resume */
-#endif
-
-#define VT_OPENQRY _IOR('v', 1, int)
-#define VT_SETMODE _IOW('v', 2, vtmode_t)
-#define VT_GETMODE _IOR('v', 3, vtmode_t)
-#define VT_RELDISP _IO('v', 4 /*, int */)
-#define VT_ACTIVATE _IO('v', 5 /*, int */)
-#define VT_WAITACTIVE _IO('v', 6 /*, int */)
-#define VT_GETACTIVE _IOR('v', 7, int)
-
-#define VT_FALSE 0
-#define VT_TRUE 1
-#define VT_ACKACQ 2
-
-#define VT_AUTO 0 /* switching is automatic */
-#define VT_PROCESS 1 /* switching controlled by prog */
-#define VT_KERNEL 255 /* switching controlled in kernel */
-
-#ifndef _VT_MODE_DECLARED
-#define _VT_MODE_DECLARED
-struct vt_mode {
- char mode;
- char waitv; /* not implemented yet SOS */
- short relsig;
- short acqsig;
- short frsig; /* not implemented yet SOS */
-};
-
-typedef struct vt_mode vtmode_t;
-#endif /* !_VT_MODE_DECLARED */
-
-struct mouse_data {
- int x;
- int y;
- int z;
- int buttons;
-};
-
-struct mouse_mode {
- int mode;
- int signal;
-};
-
-struct mouse_event {
- int id; /* one based */
- int value;
-};
-
-#define MOUSE_SHOW 0x01
-#define MOUSE_HIDE 0x02
-#define MOUSE_MOVEABS 0x03
-#define MOUSE_MOVEREL 0x04
-#define MOUSE_GETINFO 0x05
-#define MOUSE_MODE 0x06
-#define MOUSE_ACTION 0x07
-#define MOUSE_MOTION_EVENT 0x08
-#define MOUSE_BUTTON_EVENT 0x09
-
-struct mouse_info {
- int operation;
- union {
- struct mouse_data data;
- struct mouse_mode mode;
- struct mouse_event event;
- }u;
-};
-
-#define KD_MONO 1 /* monochrome adapter */
-#define KD_HERCULES 2 /* hercules adapter */
-#define KD_CGA 3 /* color graphics adapter */
-#define KD_EGA 4 /* enhanced graphics adapter */
-#define KD_VGA 5 /* video graphics adapter */
-#define KD_PC98 6 /* PC-98 display */
-
-#define KD_TEXT 0 /* set text mode restore fonts */
-#define KD_TEXT0 0 /* ditto */
-#define KD_TEXT1 2 /* set text mode !restore fonts */
-#define KD_GRAPHICS 1 /* set graphics mode */
-#define KD_PIXEL 3 /* set pixel mode */
-
-#define K_RAW 0 /* keyboard returns scancodes */
-#define K_XLATE 1 /* keyboard returns ascii */
-#define K_CODE 2 /* keyboard returns keycodes */
-
-#define KB_84 1 /* 'old' 84 key AT-keyboard */
-#define KB_101 2 /* MF-101 or MF-102 keyboard */
-#define KB_OTHER 3 /* keyboard not known */
-
-#define CLKED 1 /* Caps locked */
-#define NLKED 2 /* Num locked */
-#define SLKED 4 /* Scroll locked */
-#define ALKED 8 /* AltGr locked */
-#define LOCK_MASK (CLKED | NLKED | SLKED | ALKED)
-#define LED_CAP 1 /* Caps lock LED */
-#define LED_NUM 2 /* Num lock LED */
-#define LED_SCR 4 /* Scroll lock LED */
-#define LED_MASK (LED_CAP | LED_NUM | LED_SCR)
-
-/* possible flag values */
-#define FLAG_LOCK_O 0
-#define FLAG_LOCK_C 1
-#define FLAG_LOCK_N 2
-
-#define NUM_KEYS 256 /* number of keys in table */
-#define NUM_STATES 8 /* states per key */
-#define ALTGR_OFFSET 128 /* offset for altlock keys */
-
-#ifndef _KEYMAP_DECLARED
-#define _KEYMAP_DECLARED
-struct keyent_t {
- u_char map[NUM_STATES];
- u_char spcl;
- u_char flgs;
-};
-
-struct keymap {
- u_short n_keys;
- struct keyent_t key[NUM_KEYS];
-};
-
-typedef struct keymap keymap_t;
-
-struct keyarg {
- u_short keynum;
- struct keyent_t key;
-};
-
-typedef struct keyarg keyarg_t;
-#endif /* !_KEYMAP_DECLARED */
-
-#define NUM_DEADKEYS 15 /* number of accent keys */
-#define NUM_ACCENTCHARS 52 /* max number of accent chars */
-
-struct acc_t {
- u_char accchar;
- u_char map[NUM_ACCENTCHARS][2];
-};
-
-struct accentmap {
- u_short n_accs;
- struct acc_t acc[NUM_DEADKEYS];
-};
-
-#define MAXFK 16
-#define NUM_FKEYS 96
-
-struct fkeytab {
- u_char str[MAXFK];
- u_char len;
-};
-
-struct fkeyarg {
- u_short keynum;
- char keydef[MAXFK];
- char flen;
-};
-
-struct colors {
- char fore;
- char back;
-};
-
-struct vid_info {
- short size;
- short m_num;
- u_short mv_row, mv_col;
- u_short mv_rsz, mv_csz;
- struct colors mv_norm,
- mv_rev,
- mv_grfc;
- u_char mv_ovscan;
- u_char mk_keylock;
-};
-
-#define MAXSSAVER 16
-
-struct ssaver {
- char name[MAXSSAVER];
- int num;
- long time;
-};
-
-/* video mode information block */
-struct video_info {
- int vi_mode;
- int vi_flags;
-#define V_INFO_COLOR (1<<0)
-#define V_INFO_GRAPHICS (1<<1)
-#define V_INFO_LINEAR (1<<2)
-#define V_INFO_VESA (1<<3)
- int vi_width;
- int vi_height;
- int vi_cwidth;
- int vi_cheight;
- int vi_depth;
- int vi_planes;
- u_int vi_window; /* physical address */
- size_t vi_window_size;
- size_t vi_window_gran;
- u_int vi_buffer; /* physical address */
- size_t vi_buffer_size;
- /* XXX pixel format, memory model,... */
-};
-
-/* adapter infromation block */
-struct video_adapter {
- int va_index;
- int va_type;
- char *va_name;
- int va_unit;
- int va_minor;
- int va_flags;
-#define V_ADP_COLOR (1<<0)
-#define V_ADP_MODECHANGE (1<<1)
-#define V_ADP_STATESAVE (1<<2)
-#define V_ADP_STATELOAD (1<<3)
-#define V_ADP_FONT (1<<4)
-#define V_ADP_PALETTE (1<<5)
-#define V_ADP_BORDER (1<<6)
-#define V_ADP_VESA (1<<7)
-#define V_ADP_PROBED (1<<16)
-#define V_ADP_INITIALIZED (1<<17)
-#define V_ADP_REGISTERED (1<<18)
- int va_io_base;
- int va_io_size;
- int va_crtc_addr;
- int va_mem_base;
- int va_mem_size;
- u_int va_window; /* virtual address */
- size_t va_window_size;
- size_t va_window_gran;
- u_int va_buffer; /* virtual address */
- size_t va_buffer_size;
- int va_initial_mode;
- int va_initial_bios_mode;
- int va_mode;
- struct video_info va_info;
- int va_line_width;
- void *va_token;
-};
-
-struct video_adapter_info {
- int va_index;
- int va_type;
- char va_name[16];
- int va_unit;
- int va_flags;
- int va_io_base;
- int va_io_size;
- int va_crtc_addr;
- int va_mem_base;
- int va_mem_size;
- u_int va_window; /* virtual address */
- size_t va_window_size;
- size_t va_window_gran;
- u_int va_buffer; /* virtual address */
- size_t va_buffer_size;
- int va_initial_mode;
- int va_initial_bios_mode;
- int va_mode;
- int va_line_width;
-};
-
-#define V_ADP_PRIMARY 0
-#define V_ADP_SECONDARY 1
-
-struct keyboard_info {
- int kb_index; /* kbdio index# */
- char kb_name[16]; /* driver name */
- int kb_unit; /* unit# */
- int kb_type; /* KB_84, KB_101, KB_OTHER,... */
- int kb_config; /* device configuration flags */
- int kb_flags; /* internal flags */
-};
-
-typedef struct accentmap accentmap_t;
-typedef struct fkeytab fkeytab_t;
-typedef struct fkeyarg fkeyarg_t;
-typedef struct vid_info vid_info_t;
-typedef struct mouse_info mouse_info_t;
-typedef struct {char scrmap[256];} scrmap_t;
-typedef struct {char fnt8x8[8*256];} fnt8_t;
-typedef struct {char fnt8x14[14*256];} fnt14_t;
-typedef struct {char fnt8x16[16*256];} fnt16_t;
-typedef struct ssaver ssaver_t;
-typedef struct video_adapter video_adapter_t;
-typedef struct video_adapter_info video_adapter_info_t;
-typedef struct video_info video_info_t;
-typedef struct keyboard_info keyboard_info_t;
-typedef struct {int scr_size[3];} scr_size_t;
-typedef struct {int kbd_delay[2];} keyboard_delay_t;
-
-/* defines for "special" keys (spcl bit set in keymap) */
-#define NOP 0x00 /* nothing (dead key) */
-#define LSH 0x02 /* left shift key */
-#define RSH 0x03 /* right shift key */
-#define CLK 0x04 /* caps lock key */
-#define NLK 0x05 /* num lock key */
-#define SLK 0x06 /* scroll lock key */
-#define LALT 0x07 /* left alt key */
-#define BTAB 0x08 /* backwards tab */
-#define LCTR 0x09 /* left control key */
-#define NEXT 0x0a /* switch to next screen */
-#define F_SCR 0x0b /* switch to first screen */
-#define L_SCR 0x1a /* switch to last screen */
-#define F_FN 0x1b /* first function key */
-#define L_FN 0x7a /* last function key */
-/* 0x7b-0x7f reserved do not use ! */
-#define RCTR 0x80 /* right control key */
-#define RALT 0x81 /* right alt (altgr) key */
-#define ALK 0x82 /* alt lock key */
-#define ASH 0x83 /* alt shift key */
-#define META 0x84 /* meta key */
-#define RBT 0x85 /* boot machine */
-#define DBG 0x86 /* call debugger */
-#define SUSP 0x87 /* suspend power (APM) */
-#define SPSC 0x88 /* toggle splash/text screen */
-
-#define F_ACC DGRA /* first accent key */
-#define DGRA 0x89 /* grave */
-#define DACU 0x8a /* acute */
-#define DCIR 0x8b /* circumflex */
-#define DTIL 0x8c /* tilde */
-#define DMAC 0x8d /* macron */
-#define DBRE 0x8e /* breve */
-#define DDOT 0x8f /* dot */
-#define DUML 0x90 /* umlaut/diaresis */
-#define DDIA 0x90 /* diaresis */
-#define DSLA 0x91 /* slash */
-#define DRIN 0x92 /* ring */
-#define DCED 0x93 /* cedilla */
-#define DAPO 0x94 /* apostrophe */
-#define DDAC 0x95 /* double acute */
-#define DOGO 0x96 /* ogonek */
-#define DCAR 0x97 /* caron */
-#define L_ACC DCAR /* last accent key */
-
-#define STBY 0x98 /* Go into standby mode (apm) */
-
-#define F(x) ((x)+F_FN-1)
-#define S(x) ((x)+F_SCR-1)
-#define ACC(x) ((x)+F_ACC)
-#define NOKEY 0x100 /* no key pressed marker */
-#define FKEY 0x200 /* function key marker */
-#define MKEY 0x400 /* meta key marker (prepend ESC)*/
-#define BKEY 0x800 /* backtab (ESC [ Z) */
-
-#define SPCLKEY 0x8000 /* special key */
-#define RELKEY 0x4000 /* key released */
-#define ERRKEY 0x2000 /* error */
-
-#define KEYCHAR(c) ((c) & 0x00ff)
-#define KEYFLAGS(c) ((c) & ~0x00ff)
-
-/* video mode definitions */
-#define M_B40x25 0 /* black & white 40 columns */
-#define M_C40x25 1 /* color 40 columns */
-#define M_B80x25 2 /* black & white 80 columns */
-#define M_C80x25 3 /* color 80 columns */
-#define M_BG320 4 /* black & white graphics 320x200 */
-#define M_CG320 5 /* color graphics 320x200 */
-#define M_BG640 6 /* black & white graphics 640x200 hi-res */
-#define M_EGAMONO80x25 7 /* ega-mono 80x25 */
-#define M_CG320_D 13 /* ega mode D */
-#define M_CG640_E 14 /* ega mode E */
-#define M_EGAMONOAPA 15 /* ega mode F */
-#define M_CG640x350 16 /* ega mode 10 */
-#define M_ENHMONOAPA2 17 /* ega mode F with extended memory */
-#define M_ENH_CG640 18 /* ega mode 10* */
-#define M_ENH_B40x25 19 /* ega enhanced black & white 40 columns */
-#define M_ENH_C40x25 20 /* ega enhanced color 40 columns */
-#define M_ENH_B80x25 21 /* ega enhanced black & white 80 columns */
-#define M_ENH_C80x25 22 /* ega enhanced color 80 columns */
-#define M_VGA_C40x25 23 /* vga 8x16 font on color */
-#define M_VGA_C80x25 24 /* vga 8x16 font on color */
-#define M_VGA_M80x25 25 /* vga 8x16 font on mono */
-
-#define M_VGA11 26 /* vga 640x480 2 colors */
-#define M_BG640x480 26
-#define M_VGA12 27 /* vga 640x480 16 colors */
-#define M_CG640x480 27
-#define M_VGA13 28 /* vga 640x200 256 colors */
-#define M_VGA_CG320 28
-
-#define M_VGA_C80x50 30 /* vga 8x8 font on color */
-#define M_VGA_M80x50 31 /* vga 8x8 font on color */
-#define M_VGA_C80x30 32 /* vga 8x16 font on color */
-#define M_VGA_M80x30 33 /* vga 8x16 font on color */
-#define M_VGA_C80x60 34 /* vga 8x8 font on color */
-#define M_VGA_M80x60 35 /* vga 8x8 font on color */
-#define M_VGA_CG640 36 /* vga 640x400 256 color */
-#define M_VGA_MODEX 37 /* vga 320x240 256 color */
-
-#define M_ENH_B80x43 0x70 /* ega black & white 80x43 */
-#define M_ENH_C80x43 0x71 /* ega color 80x43 */
-
-#define M_PC98_80x25 98 /* PC98 80x25 */
-#define M_PC98_80x30 99 /* PC98 80x30 */
-
-#define M_HGC_P0 0xe0 /* hercules graphics - page 0 @ B0000 */
-#define M_HGC_P1 0xe1 /* hercules graphics - page 1 @ B8000 */
-#define M_MCA_MODE 0xff /* monochrome adapter mode */
-
-#define M_TEXT_80x25 200 /* generic text modes */
-#define M_TEXT_80x30 201
-#define M_TEXT_80x43 202
-#define M_TEXT_80x50 203
-#define M_TEXT_80x60 204
-#define M_TEXT_132x25 205
-#define M_TEXT_132x30 206
-#define M_TEXT_132x43 207
-#define M_TEXT_132x50 208
-#define M_TEXT_132x60 209
-
-#define SW_PC98_80x25 _IO('S', M_PC98_80x25)
-#define SW_PC98_80x30 _IO('S', M_PC98_80x30)
-#define SW_B40x25 _IO('S', M_B40x25)
-#define SW_C40x25 _IO('S', M_C40x25)
-#define SW_B80x25 _IO('S', M_B80x25)
-#define SW_C80x25 _IO('S', M_C80x25)
-#define SW_BG320 _IO('S', M_BG320)
-#define SW_CG320 _IO('S', M_CG320)
-#define SW_BG640 _IO('S', M_BG640)
-#define SW_EGAMONO80x25 _IO('S', M_EGAMONO80x25)
-#define SW_CG320_D _IO('S', M_CG320_D)
-#define SW_CG640_E _IO('S', M_CG640_E)
-#define SW_EGAMONOAPA _IO('S', M_EGAMONOAPA)
-#define SW_CG640x350 _IO('S', M_CG640x350)
-#define SW_ENH_MONOAPA2 _IO('S', M_ENHMONOAPA2)
-#define SW_ENH_CG640 _IO('S', M_ENH_CG640)
-#define SW_ENH_B40x25 _IO('S', M_ENH_B40x25)
-#define SW_ENH_C40x25 _IO('S', M_ENH_C40x25)
-#define SW_ENH_B80x25 _IO('S', M_ENH_B80x25)
-#define SW_ENH_C80x25 _IO('S', M_ENH_C80x25)
-#define SW_ENH_B80x43 _IO('S', M_ENH_B80x43)
-#define SW_ENH_C80x43 _IO('S', M_ENH_C80x43)
-#define SW_MCAMODE _IO('S', M_MCA_MODE)
-#define SW_VGA_C40x25 _IO('S', M_VGA_C40x25)
-#define SW_VGA_C80x25 _IO('S', M_VGA_C80x25)
-#define SW_VGA_C80x30 _IO('S', M_VGA_C80x30)
-#define SW_VGA_C80x50 _IO('S', M_VGA_C80x50)
-#define SW_VGA_C80x60 _IO('S', M_VGA_C80x60)
-#define SW_VGA_M80x25 _IO('S', M_VGA_M80x25)
-#define SW_VGA_M80x30 _IO('S', M_VGA_M80x30)
-#define SW_VGA_M80x50 _IO('S', M_VGA_M80x50)
-#define SW_VGA_M80x60 _IO('S', M_VGA_M80x60)
-#define SW_VGA11 _IO('S', M_VGA11)
-#define SW_BG640x480 _IO('S', M_VGA11)
-#define SW_VGA12 _IO('S', M_VGA12)
-#define SW_CG640x480 _IO('S', M_VGA12)
-#define SW_VGA13 _IO('S', M_VGA13)
-#define SW_VGA_CG320 _IO('S', M_VGA13)
-#define SW_VGA_CG640 _IO('S', M_VGA_CG640)
-#define SW_VGA_MODEX _IO('S', M_VGA_MODEX)
-
-#define SW_TEXT_80x25 _IO('S', M_TEXT_80x25)
-#define SW_TEXT_80x30 _IO('S', M_TEXT_80x30)
-#define SW_TEXT_80x43 _IO('S', M_TEXT_80x43)
-#define SW_TEXT_80x50 _IO('S', M_TEXT_80x50)
-#define SW_TEXT_80x60 _IO('S', M_TEXT_80x60)
-#define SW_TEXT_132x25 _IO('S', M_TEXT_132x25)
-#define SW_TEXT_132x30 _IO('S', M_TEXT_132x30)
-#define SW_TEXT_132x43 _IO('S', M_TEXT_132x43)
-#define SW_TEXT_132x50 _IO('S', M_TEXT_132x50)
-#define SW_TEXT_132x60 _IO('S', M_TEXT_132x60)
-
-#define M_VESA_BASE 0x100 /* VESA mode number base */
-
-#define M_VESA_CG640x400 0x100 /* 640x400, 256 color */
-#define M_VESA_CG640x480 0x101 /* 640x480, 256 color */
-#define M_VESA_800x600 0x102 /* 800x600, 16 color */
-#define M_VESA_CG800x600 0x103 /* 800x600, 256 color */
-#define M_VESA_1024x768 0x104 /* 1024x768, 16 color */
-#define M_VESA_CG1024x768 0x105 /* 1024x768, 256 color */
-#define M_VESA_1280x1024 0x106 /* 1280x1024, 16 color */
-#define M_VESA_CG1280x1024 0x107 /* 1280x1024, 256 color */
-#define M_VESA_C80x60 0x108 /* 8x8 font */
-#define M_VESA_C132x25 0x109 /* 8x16 font */
-#define M_VESA_C132x43 0x10a /* 8x14 font */
-#define M_VESA_C132x50 0x10b /* 8x8 font */
-#define M_VESA_C132x60 0x10c /* 8x8 font */
-#define M_VESA_32K_320 0x10d /* 320x200, 5:5:5 */
-#define M_VESA_64K_320 0x10e /* 320x200, 5:6:5 */
-#define M_VESA_FULL_320 0x10f /* 320x200, 8:8:8 */
-#define M_VESA_32K_640 0x110 /* 640x480, 5:5:5 */
-#define M_VESA_64K_640 0x111 /* 640x480, 5:6:5 */
-#define M_VESA_FULL_640 0x112 /* 640x480, 8:8:8 */
-#define M_VESA_32K_800 0x113 /* 800x600, 5:5:5 */
-#define M_VESA_64K_800 0x114 /* 800x600, 5:6:5 */
-#define M_VESA_FULL_800 0x115 /* 800x600, 8:8:8 */
-#define M_VESA_32K_1024 0x116 /* 1024x768, 5:5:5 */
-#define M_VESA_64K_1024 0x117 /* 1024x768, 5:6:5 */
-#define M_VESA_FULL_1024 0x118 /* 1024x768, 8:8:8 */
-#define M_VESA_32K_1280 0x119 /* 1280x1024, 5:5:5 */
-#define M_VESA_64K_1280 0x11a /* 1280x1024, 5:6:5 */
-#define M_VESA_FULL_1280 0x11b /* 1280x1024, 8:8:8 */
-#define M_VESA_MODE_MAX 0x1ff
-
-#define SW_VESA_CG640x400 _IO('V', M_VESA_CG640x400 - M_VESA_BASE)
-#define SW_VESA_CG640x480 _IO('V', M_VESA_CG640x480 - M_VESA_BASE)
-#define SW_VESA_800x600 _IO('V', M_VESA_800x600 - M_VESA_BASE)
-#define SW_VESA_CG800x600 _IO('V', M_VESA_CG800x600 - M_VESA_BASE)
-#define SW_VESA_1024x768 _IO('V', M_VESA_1024x768 - M_VESA_BASE)
-#define SW_VESA_CG1024x768 _IO('V', M_VESA_CG1024x768 - M_VESA_BASE)
-#define SW_VESA_1280x1024 _IO('V', M_VESA_1280x1024 - M_VESA_BASE)
-#define SW_VESA_CG1280x1024 _IO('V', M_VESA_CG1280x1024 - M_VESA_BASE)
-#define SW_VESA_C80x60 _IO('V', M_VESA_C80x60 - M_VESA_BASE)
-#define SW_VESA_C132x25 _IO('V', M_VESA_C132x25 - M_VESA_BASE)
-#define SW_VESA_C132x43 _IO('V', M_VESA_C132x43 - M_VESA_BASE)
-#define SW_VESA_C132x50 _IO('V', M_VESA_C132x50 - M_VESA_BASE)
-#define SW_VESA_C132x60 _IO('V', M_VESA_C132x60 - M_VESA_BASE)
-#define SW_VESA_32K_320 _IO('V', M_VESA_32K_320 - M_VESA_BASE)
-#define SW_VESA_64K_320 _IO('V', M_VESA_64K_320 - M_VESA_BASE)
-#define SW_VESA_FULL_320 _IO('V', M_VESA_FULL_320 - M_VESA_BASE)
-#define SW_VESA_32K_640 _IO('V', M_VESA_32K_640 - M_VESA_BASE)
-#define SW_VESA_64K_640 _IO('V', M_VESA_64K_640 - M_VESA_BASE)
-#define SW_VESA_FULL_640 _IO('V', M_VESA_FULL_640 - M_VESA_BASE)
-#define SW_VESA_32K_800 _IO('V', M_VESA_32K_800 - M_VESA_BASE)
-#define SW_VESA_64K_800 _IO('V', M_VESA_64K_800 - M_VESA_BASE)
-#define SW_VESA_FULL_800 _IO('V', M_VESA_FULL_800 - M_VESA_BASE)
-#define SW_VESA_32K_1024 _IO('V', M_VESA_32K_1024 - M_VESA_BASE)
-#define SW_VESA_64K_1024 _IO('V', M_VESA_64K_1024 - M_VESA_BASE)
-#define SW_VESA_FULL_1024 _IO('V', M_VESA_FULL_1024 - M_VESA_BASE)
-#define SW_VESA_32K_1280 _IO('V', M_VESA_32K_1280 - M_VESA_BASE)
-#define SW_VESA_64K_1280 _IO('V', M_VESA_64K_1280 - M_VESA_BASE)
-#define SW_VESA_FULL_1280 _IO('V', M_VESA_FULL_1280 - M_VESA_BASE)
+#include <sys/fbio.h>
+#include <sys/kbio.h>
+#include <sys/consio.h>
#endif /* !_MACHINE_CONSOLE_H_ */
-
diff --git a/sys/i386/isa/pcvt/pcvt_drv.c b/sys/i386/isa/pcvt/pcvt_drv.c
index a0dd214..c988fef 100644
--- a/sys/i386/isa/pcvt/pcvt_drv.c
+++ b/sys/i386/isa/pcvt/pcvt_drv.c
@@ -93,6 +93,7 @@ static void *pcvt_devfs_token[MAXCONS];
#endif /*DEVFS*/
#if PCVT_FREEBSD >= 200
+#include <sys/bus.h>
#include <machine/stdarg.h>
#else
#include "machine/stdarg.h"
@@ -121,7 +122,7 @@ static cn_getc_t pccngetc;
static cn_checkc_t pccncheckc;
static cn_putc_t pccnputc;
-CONS_DRIVER(pc, pccnprobe, pccninit, pccngetc, pccncheckc, pccnputc);
+CONS_DRIVER(pc, pccnprobe, pccninit, NULL, pccngetc, pccncheckc, pccnputc);
static d_open_t pcopen;
static d_close_t pcclose;
@@ -1178,6 +1179,12 @@ pccnprobe(struct consdev *cp)
static int uarg = 0;
int i;
+ /* See if this driver is disabled in probe hint. */
+ if (resource_int_value("vt", 0, "disabled", &i) == 0 && i) {
+ cp->cn_pri = CN_DEAD;
+ return;
+ }
+
#ifdef _DEV_KBD_KBDREG_H_
/*
* Don't reset the keyboard via `kbdio' just yet.
diff --git a/sys/i386/isa/vesa.c b/sys/i386/isa/vesa.c
index d734c64..0756880 100644
--- a/sys/i386/isa/vesa.c
+++ b/sys/i386/isa/vesa.c
@@ -23,7 +23,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: vesa.c,v 1.23 1999/05/09 15:57:52 peter Exp $
+ * $Id: vesa.c,v 1.24 1999/06/01 18:20:18 jlemon Exp $
*/
#include "vga.h"
@@ -42,10 +42,13 @@
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/malloc.h>
+#include <sys/fbio.h>
+
#include <vm/vm.h>
+#include <vm/vm_extern.h>
+#include <vm/vm_kern.h>
#include <vm/pmap.h>
-#include <machine/console.h>
#include <machine/md_var.h>
#include <machine/vm86.h>
#include <machine/pc/bios.h>
@@ -75,12 +78,10 @@ typedef struct adp_state adp_state_t;
/* VESA video adapter */
static video_adapter_t *vesa_adp = NULL;
static int vesa_state_buf_size = 0;
-#if 0
-static void *vesa_state_buf = NULL;
-#endif
/* VESA functions */
static int vesa_nop(void);
+static int vesa_error(void);
static vi_probe_t vesa_probe;
static vi_init_t vesa_init;
static vi_get_info_t vesa_get_info;
@@ -98,8 +99,14 @@ static vi_set_win_org_t vesa_set_origin;
static vi_read_hw_cursor_t vesa_read_hw_cursor;
static vi_set_hw_cursor_t vesa_set_hw_cursor;
static vi_set_hw_cursor_shape_t vesa_set_hw_cursor_shape;
+static vi_blank_display_t vesa_blank_display;
static vi_mmap_t vesa_mmap;
+static vi_ioctl_t vesa_ioctl;
+static vi_clear_t vesa_clear;
+static vi_fill_rect_t vesa_fill_rect;
+static vi_bitblt_t vesa_bitblt;
static vi_diag_t vesa_diag;
+static int vesa_bios_info(int level);
static struct vm86context vesa_vmcontext;
static video_switch_t vesavidsw = {
@@ -120,8 +127,14 @@ static video_switch_t vesavidsw = {
vesa_read_hw_cursor,
vesa_set_hw_cursor,
vesa_set_hw_cursor_shape,
- (vi_blank_display_t *)vesa_nop,
+ vesa_blank_display,
vesa_mmap,
+ vesa_ioctl,
+ vesa_clear,
+ vesa_fill_rect,
+ vesa_bitblt,
+ vesa_error,
+ vesa_error,
vesa_diag,
};
@@ -132,9 +145,11 @@ static video_switch_t *prevvidsw;
#define EOT (-1)
#define NA (-2)
-static video_info_t vesa_vmode[VESA_MAXMODES + 1] = {
- { EOT, },
-};
+#define MODE_TABLE_DELTA 8
+
+static int vesa_vmode_max = 0;
+static video_info_t vesa_vmode_empty = { EOT };
+static video_info_t *vesa_vmode = &vesa_vmode_empty;
static int vesa_init_done = FALSE;
static int has_vesa_bios = FALSE;
@@ -155,8 +170,12 @@ static int vesa_bios_get_dac(void);
static int vesa_bios_set_dac(int bits);
static int vesa_bios_save_palette(int start, int colors, u_char *palette,
int bits);
+static int vesa_bios_save_palette2(int start, int colors, u_char *r, u_char *g,
+ u_char *b, int bits);
static int vesa_bios_load_palette(int start, int colors, u_char *palette,
int bits);
+static int vesa_bios_load_palette2(int start, int colors, u_char *r, u_char *g,
+ u_char *b, int bits);
#define STATE_SIZE 0
#define STATE_SAVE 1
#define STATE_LOAD 2
@@ -169,12 +188,20 @@ static int vesa_bios_load_palette(int start, int colors, u_char *palette,
static int vesa_bios_state_buf_size(void);
static int vesa_bios_save_restore(int code, void *p, size_t size);
static int vesa_bios_get_line_length(void);
+static int vesa_bios_set_line_length(int pixel);
+static int vesa_bios_get_start(int *x, int *y);
+static int vesa_bios_set_start(int x, int y);
static int vesa_map_gen_mode_num(int type, int color, int mode);
static int vesa_translate_flags(u_int16_t vflags);
+static int vesa_translate_mmodel(u_int8_t vmodel);
static void *vesa_fix_ptr(u_int32_t p, u_int16_t seg, u_int16_t off,
u_char *buf);
static int vesa_bios_init(void);
static void vesa_clear_modes(video_info_t *info, int color);
+static vm_offset_t vesa_map_buffer(u_int paddr, size_t size);
+static void vesa_unmap_buffer(vm_offset_t vaddr, size_t size);
+
+static int vesa_get_origin(video_adapter_t *adp, off_t *offset);
static void
dump_buffer(u_char *buf, size_t len)
@@ -294,6 +321,36 @@ vesa_bios_save_palette(int start, int colors, u_char *palette, int bits)
}
static int
+vesa_bios_save_palette2(int start, int colors, u_char *r, u_char *g, u_char *b,
+ int bits)
+{
+ struct vm86frame vmf;
+ u_char *p;
+ int err;
+ int i;
+
+ bzero(&vmf, sizeof(vmf));
+ vmf.vmf_eax = 0x4f09;
+ vmf.vmf_ebx = 1; /* get primary palette data */
+ vmf.vmf_ecx = colors;
+ vmf.vmf_edx = start;
+ p = (u_char *)vm86_getpage(&vesa_vmcontext, 1);
+ vm86_getptr(&vesa_vmcontext, (vm_offset_t)p, &vmf.vmf_es, &vmf.vmf_di);
+
+ err = vm86_datacall(0x10, &vmf, &vesa_vmcontext);
+ if ((err != 0) || (vmf.vmf_eax != 0x4f))
+ return 1;
+
+ bits = 8 - bits;
+ for (i = 0; i < colors; ++i) {
+ r[i] = p[i*4 + 2] << bits;
+ g[i] = p[i*4 + 1] << bits;
+ b[i] = p[i*4] << bits;
+ }
+ return 0;
+}
+
+static int
vesa_bios_load_palette(int start, int colors, u_char *palette, int bits)
{
struct vm86frame vmf;
@@ -322,6 +379,35 @@ vesa_bios_load_palette(int start, int colors, u_char *palette, int bits)
}
static int
+vesa_bios_load_palette2(int start, int colors, u_char *r, u_char *g, u_char *b,
+ int bits)
+{
+ struct vm86frame vmf;
+ u_char *p;
+ int err;
+ int i;
+
+ p = (u_char *)vm86_getpage(&vesa_vmcontext, 1);
+ bits = 8 - bits;
+ for (i = 0; i < colors; ++i) {
+ p[i*4] = b[i] >> bits;
+ p[i*4 + 1] = g[i] >> bits;
+ p[i*4 + 2] = r[i] >> bits;
+ p[i*4 + 3] = 0;
+ }
+
+ bzero(&vmf, sizeof(vmf));
+ vmf.vmf_eax = 0x4f09;
+ vmf.vmf_ebx = 0; /* set primary palette data */
+ vmf.vmf_ecx = colors;
+ vmf.vmf_edx = start;
+ vm86_getptr(&vesa_vmcontext, (vm_offset_t)p, &vmf.vmf_es, &vmf.vmf_di);
+
+ err = vm86_datacall(0x10, &vmf, &vesa_vmcontext);
+ return ((err != 0) || (vmf.vmf_eax != 0x4f));
+}
+
+static int
vesa_bios_state_buf_size(void)
{
struct vm86frame vmf;
@@ -371,6 +457,55 @@ vesa_bios_get_line_length(void)
return vmf.vmf_bx; /* line length in bytes */
}
+static int
+vesa_bios_set_line_length(int pixel)
+{
+ struct vm86frame vmf;
+ int err;
+
+ bzero(&vmf, sizeof(vmf));
+ vmf.vmf_eax = 0x4f06;
+ vmf.vmf_ebx = 0; /* set scan line length in pixel */
+ vmf.vmf_ecx = pixel;
+ err = vm86_intcall(0x10, &vmf);
+#if VESA_DEBUG > 1
+ printf("bx:%d, cx:%d, dx:%d\n", vmf.vmf_bx, vmf.vmf_cx, vmf.vmf_dx);
+#endif
+ return ((err != 0) || (vmf.vmf_eax != 0x4f));
+}
+
+static int
+vesa_bios_get_start(int *x, int *y)
+{
+ struct vm86frame vmf;
+ int err;
+
+ bzero(&vmf, sizeof(vmf));
+ vmf.vmf_eax = 0x4f07;
+ vmf.vmf_ebx = 1; /* get display start */
+ err = vm86_intcall(0x10, &vmf);
+ if ((err != 0) || (vmf.vmf_eax != 0x4f))
+ return 1;
+ *x = vmf.vmf_cx;
+ *y = vmf.vmf_dx;
+ return 0;
+}
+
+static int
+vesa_bios_set_start(int x, int y)
+{
+ struct vm86frame vmf;
+ int err;
+
+ bzero(&vmf, sizeof(vmf));
+ vmf.vmf_eax = 0x4f07;
+ vmf.vmf_ebx = 0x80; /* set display start */
+ vmf.vmf_edx = y;
+ vmf.vmf_ecx = x;
+ err = vm86_intcall(0x10, &vmf);
+ return ((err != 0) || (vmf.vmf_eax != 0x4f));
+}
+
/* map a generic video mode to a known mode */
static int
vesa_map_gen_mode_num(int type, int color, int mode)
@@ -415,6 +550,29 @@ vesa_translate_flags(u_int16_t vflags)
return flags;
}
+static int
+vesa_translate_mmodel(u_int8_t vmodel)
+{
+ static struct {
+ u_int8_t vmodel;
+ int mmodel;
+ } mtable[] = {
+ { V_MMTEXT, V_INFO_MM_TEXT },
+ { V_MMCGA, V_INFO_MM_CGA },
+ { V_MMHGC, V_INFO_MM_HGC },
+ { V_MMEGA, V_INFO_MM_PLANAR },
+ { V_MMPACKED, V_INFO_MM_PACKED },
+ { V_MMDIRCOLOR, V_INFO_MM_DIRECT },
+ };
+ int i;
+
+ for (i = 0; mtable[i].mmodel >= 0; ++i) {
+ if (mtable[i].vmodel == vmodel)
+ return mtable[i].mmodel;
+ }
+ return V_INFO_MM_OTHER;
+}
+
static void
*vesa_fix_ptr(u_int32_t p, u_int16_t seg, u_int16_t off, u_char *buf)
{
@@ -434,6 +592,7 @@ vesa_bios_init(void)
static u_char buf[512];
struct vm86frame vmf;
struct vesa_mode vmode;
+ video_info_t *p;
u_char *vmbuf;
int modes;
int err;
@@ -444,6 +603,7 @@ vesa_bios_init(void)
has_vesa_bios = FALSE;
vesa_adp_info = NULL;
+ vesa_vmode_max = 0;
vesa_vmode[0].vi_mode = EOT;
vmbuf = (u_char *)vm86_addpage(&vesa_vmcontext, 1, 0);
@@ -463,6 +623,15 @@ vesa_bios_init(void)
}
if (vesa_adp_info->v_flags & V_NONVGA)
return 1;
+ if (vesa_adp_info->v_version < 0x0102) {
+ printf("VESA: VBE version %d.%d is not supported; "
+ "version 1.2 or later is required.\n",
+ ((vesa_adp_info->v_version & 0xf000) >> 12) * 10
+ + ((vesa_adp_info->v_version & 0x0f00) >> 8),
+ ((vesa_adp_info->v_version & 0x00f0) >> 4) * 10
+ + (vesa_adp_info->v_version & 0x000f));
+ return 1;
+ }
/* fix string ptrs */
vesa_oemstr = (char *)vesa_fix_ptr(vesa_adp_info->v_oemstr,
@@ -480,7 +649,6 @@ vesa_bios_init(void)
}
/* obtain video mode information */
- vesa_vmode[0].vi_mode = EOT;
vesa_vmodetab = (u_int16_t *)vesa_fix_ptr(vesa_adp_info->v_modetable,
vmf.vmf_es, vmf.vmf_di, buf);
if (vesa_vmodetab == NULL)
@@ -488,8 +656,6 @@ vesa_bios_init(void)
for (i = 0, modes = 0;
(i < (M_VESA_MODE_MAX - M_VESA_BASE + 1))
&& (vesa_vmodetab[i] != 0xffff); ++i) {
- if (modes >= VESA_MAXMODES)
- break;
if (vesa_bios_get_mode(vesa_vmodetab[i], &vmode))
continue;
@@ -505,6 +671,22 @@ vesa_bios_init(void)
continue;
#endif
+ /* expand the array if necessary */
+ if (modes >= vesa_vmode_max) {
+ vesa_vmode_max += MODE_TABLE_DELTA;
+ p = malloc(sizeof(*vesa_vmode)*(vesa_vmode_max + 1),
+ M_DEVBUF, M_WAITOK);
+#if VESA_DEBUG > 1
+ printf("vesa_bios_init(): modes:%d, vesa_mode_max:%d\n",
+ modes, vesa_mode_max);
+#endif
+ if (modes > 0) {
+ bcopy(vesa_vmode, p, sizeof(*vesa_vmode)*modes);
+ free(vesa_vmode, M_DEVBUF);
+ }
+ vesa_vmode = p;
+ }
+
/* copy some fields */
bzero(&vesa_vmode[modes], sizeof(vesa_vmode[modes]));
vesa_vmode[modes].vi_mode = vesa_vmodetab[i];
@@ -518,15 +700,56 @@ vesa_bios_init(void)
/* XXX window B */
vesa_vmode[modes].vi_window_size = vmode.v_wsize*1024;
vesa_vmode[modes].vi_window_gran = vmode.v_wgran*1024;
- vesa_vmode[modes].vi_buffer = vmode.v_lfb;
+ if (vmode.v_modeattr & V_MODELFB)
+ vesa_vmode[modes].vi_buffer = vmode.v_lfb;
+ else
+ vesa_vmode[modes].vi_buffer = 0;
/* XXX */
+ vesa_vmode[modes].vi_buffer_size
+ = vesa_adp_info->v_memsize*64*1024;
+#if 0
if (vmode.v_offscreen > vmode.v_lfb)
vesa_vmode[modes].vi_buffer_size
- = vmode.v_offscreen - vmode.v_lfb;
+ = vmode.v_offscreen + vmode.v_offscreensize*1024
+ - vmode.v_lfb;
else
- vesa_vmode[modes].vi_buffer_size = vmode.v_offscreen;
- /* pixel format, memory model... */
-
+ vesa_vmode[modes].vi_buffer_size
+ = vmode.v_offscreen + vmode.v_offscreensize*1024
+#endif
+ vesa_vmode[modes].vi_mem_model
+ = vesa_translate_mmodel(vmode.v_memmodel);
+ vesa_vmode[modes].vi_pixel_fields[0] = 0;
+ vesa_vmode[modes].vi_pixel_fields[1] = 0;
+ vesa_vmode[modes].vi_pixel_fields[2] = 0;
+ vesa_vmode[modes].vi_pixel_fields[3] = 0;
+ vesa_vmode[modes].vi_pixel_fsizes[0] = 0;
+ vesa_vmode[modes].vi_pixel_fsizes[1] = 0;
+ vesa_vmode[modes].vi_pixel_fsizes[2] = 0;
+ vesa_vmode[modes].vi_pixel_fsizes[3] = 0;
+ if (vesa_vmode[modes].vi_mem_model == V_INFO_MM_PACKED) {
+ vesa_vmode[modes].vi_pixel_size = (vmode.v_bpp + 7)/8;
+ } else if (vesa_vmode[modes].vi_mem_model == V_INFO_MM_DIRECT) {
+ vesa_vmode[modes].vi_pixel_size = (vmode.v_bpp + 7)/8;
+ vesa_vmode[modes].vi_pixel_fields[0]
+ = vmode.v_redfieldpos;
+ vesa_vmode[modes].vi_pixel_fields[1]
+ = vmode.v_greenfieldpos;
+ vesa_vmode[modes].vi_pixel_fields[2]
+ = vmode.v_bluefieldpos;
+ vesa_vmode[modes].vi_pixel_fields[3]
+ = vmode.v_resfieldpos;
+ vesa_vmode[modes].vi_pixel_fsizes[0]
+ = vmode.v_redmasksize;
+ vesa_vmode[modes].vi_pixel_fsizes[1]
+ = vmode.v_greenmasksize;
+ vesa_vmode[modes].vi_pixel_fsizes[2]
+ = vmode.v_bluemasksize;
+ vesa_vmode[modes].vi_pixel_fsizes[3]
+ = vmode.v_resmasksize;
+ } else {
+ vesa_vmode[modes].vi_pixel_size = 0;
+ }
+
vesa_vmode[modes].vi_flags
= vesa_translate_flags(vmode.v_modeattr) | V_INFO_VESA;
++modes;
@@ -549,6 +772,30 @@ vesa_clear_modes(video_info_t *info, int color)
}
}
+static vm_offset_t
+vesa_map_buffer(u_int paddr, size_t size)
+{
+ vm_offset_t vaddr;
+ u_int off;
+
+ off = paddr - trunc_page(paddr);
+ vaddr = (vm_offset_t)pmap_mapdev(paddr - off, size + off);
+#if VESA_DEBUG > 1
+ printf("vesa_map_buffer: paddr:%x vaddr:%x size:%x off:%x\n",
+ paddr, vaddr, size, off);
+#endif
+ return (vaddr + off);
+}
+
+static void
+vesa_unmap_buffer(vm_offset_t vaddr, size_t size)
+{
+#if VESA_DEBUG > 1
+ printf("vesa_unmap_buffer: vaddr:%x size:%x\n", vaddr, size);
+#endif
+ kmem_free(kernel_map, vaddr, size);
+}
+
/* entry points */
static int
@@ -624,6 +871,12 @@ vesa_nop(void)
}
static int
+vesa_error(void)
+{
+ return 1;
+}
+
+static int
vesa_probe(int unit, video_adapter_t **adpp, void *arg, int flags)
{
return (*prevvidsw->probe)(unit, adpp, arg, flags);
@@ -701,43 +954,36 @@ static int
vesa_set_mode(video_adapter_t *adp, int mode)
{
video_info_t info;
- size_t len;
+ int len;
if (adp != vesa_adp)
return (*prevvidsw->set_mode)(adp, mode);
- mode = vesa_map_gen_mode_num(vesa_adp->va_type,
- vesa_adp->va_flags & V_ADP_COLOR, mode);
+ mode = vesa_map_gen_mode_num(adp->va_type,
+ adp->va_flags & V_ADP_COLOR, mode);
#if VESA_DEBUG > 0
printf("VESA: set_mode(): %d(%x) -> %d(%x)\n",
- vesa_adp->va_mode, vesa_adp->va_mode, mode, mode);
+ adp->va_mode, adp->va_mode, mode, mode);
#endif
/*
* If the current mode is a VESA mode and the new mode is not,
- * restore the state of the adapter first, so that non-standard,
- * extended SVGA registers are set to the state compatible with
- * the standard VGA modes. Otherwise (*prevvidsw->set_mode)()
- * may not be able to set up the new mode correctly.
+ * restore the state of the adapter first by setting one of the
+ * standard VGA mode, so that non-standard, extended SVGA registers
+ * are set to the state compatible with the standard VGA modes.
+ * Otherwise (*prevvidsw->set_mode)() may not be able to set up
+ * the new mode correctly.
*/
- if (VESA_MODE(vesa_adp->va_mode)) {
+ if (VESA_MODE(adp->va_mode)) {
if ((*prevvidsw->get_info)(adp, mode, &info) == 0) {
- int10_set_mode(vesa_adp->va_initial_bios_mode);
-#if 0
- /* assert(vesa_state_buf != NULL); */
- if ((vesa_state_buf == NULL)
- || vesa_load_state(adp, vesa_state_buf))
- return 1;
- free(vesa_state_buf, M_DEVBUF);
- vesa_state_buf = NULL;
-#if VESA_DEBUG > 0
- printf("VESA: restored\n");
-#endif
-#endif /* 0 */
+ int10_set_mode(adp->va_initial_bios_mode);
+ if (adp->va_info.vi_flags & V_INFO_LINEAR)
+ vesa_unmap_buffer(adp->va_buffer,
+ vesa_adp_info->v_memsize*64*1024);
+ /*
+ * Once (*prevvidsw->get_info)() succeeded,
+ * (*prevvidsw->set_mode)() below won't fail...
+ */
}
- /*
- * once (*prevvidsw->get_info)() succeeded,
- * (*prevvidsw->set_mode)() below won't fail...
- */
}
/* we may not need to handle this mode after all... */
@@ -752,33 +998,17 @@ vesa_set_mode(video_adapter_t *adp, int mode)
#if VESA_DEBUG > 0
printf("VESA: about to set a VESA mode...\n");
#endif
- /*
- * If the current mode is not a VESA mode, save the current state
- * so that the adapter state can be restored later when a non-VESA
- * mode is to be set up. See above.
- */
-#if 0
- if (!VESA_MODE(vesa_adp->va_mode) && (vesa_state_buf == NULL)) {
- len = vesa_save_state(adp, NULL, 0);
- vesa_state_buf = malloc(len, M_DEVBUF, M_WAITOK);
- if (vesa_save_state(adp, vesa_state_buf, len)) {
-#if VESA_DEBUG > 0
- printf("VESA: state save failed! (len=%d)\n", len);
-#endif
- free(vesa_state_buf, M_DEVBUF);
- vesa_state_buf = NULL;
- return 1;
- }
-#if VESA_DEBUG > 0
- printf("VESA: saved (len=%d)\n", len);
- dump_buffer(vesa_state_buf, len);
-#endif
- }
-#endif /* 0 */
+ /* don't use the linear frame buffer for text modes. XXX */
+ if (!(info.vi_flags & V_INFO_GRAPHICS))
+ info.vi_flags &= ~V_INFO_LINEAR;
- if (vesa_bios_set_mode(mode))
+ if (vesa_bios_set_mode(mode | ((info.vi_flags & V_INFO_LINEAR) ? 0x4000 : 0)))
return 1;
+ if (adp->va_info.vi_flags & V_INFO_LINEAR)
+ vesa_unmap_buffer(adp->va_buffer,
+ vesa_adp_info->v_memsize*64*1024);
+
#if VESA_DEBUG > 0
printf("VESA: mode set!\n");
#endif
@@ -788,16 +1018,25 @@ vesa_set_mode(video_adapter_t *adp, int mode)
(info.vi_flags & V_INFO_COLOR) ? V_ADP_COLOR : 0;
vesa_adp->va_crtc_addr =
(vesa_adp->va_flags & V_ADP_COLOR) ? COLOR_CRTC : MONO_CRTC;
- vesa_adp->va_window = BIOS_PADDRTOVADDR(info.vi_window);
- vesa_adp->va_window_size = info.vi_window_size;
- vesa_adp->va_window_gran = info.vi_window_gran;
- if (info.vi_buffer_size == 0) {
- vesa_adp->va_buffer = 0;
- vesa_adp->va_buffer_size = 0;
+ if (info.vi_flags & V_INFO_LINEAR) {
+#if VESA_DEBUG > 1
+ printf("VESA: setting up LFB\n");
+#endif
+ vesa_adp->va_buffer =
+ vesa_map_buffer(info.vi_buffer,
+ vesa_adp_info->v_memsize*64*1024);
+ vesa_adp->va_buffer_size = info.vi_buffer_size;
+ vesa_adp->va_window = vesa_adp->va_buffer;
+ vesa_adp->va_window_size = info.vi_buffer_size/info.vi_planes;
+ vesa_adp->va_window_gran = info.vi_buffer_size/info.vi_planes;
} else {
- vesa_adp->va_buffer = BIOS_PADDRTOVADDR(info.vi_buffer);
+ vesa_adp->va_buffer = 0;
vesa_adp->va_buffer_size = info.vi_buffer_size;
+ vesa_adp->va_window = BIOS_PADDRTOVADDR(info.vi_window);
+ vesa_adp->va_window_size = info.vi_window_size;
+ vesa_adp->va_window_gran = info.vi_window_gran;
}
+ vesa_adp->va_window_orig = 0;
len = vesa_bios_get_line_length();
if (len > 0) {
vesa_adp->va_line_width = len;
@@ -820,6 +1059,8 @@ vesa_set_mode(video_adapter_t *adp, int mode)
} else {
vesa_adp->va_line_width = info.vi_width;
}
+ vesa_adp->va_disp_start.x = 0;
+ vesa_adp->va_disp_start.y = 0;
#if VESA_DEBUG > 0
printf("vesa_set_mode(): vi_width:%d, len:%d, line_width:%d\n",
info.vi_width, len, vesa_adp->va_line_width);
@@ -927,6 +1168,22 @@ vesa_load_state(video_adapter_t *adp, void *p)
}
static int
+vesa_get_origin(video_adapter_t *adp, off_t *offset)
+{
+ struct vm86frame vmf;
+ int err;
+
+ bzero(&vmf, sizeof(vmf));
+ vmf.vmf_eax = 0x4f05;
+ vmf.vmf_ebx = 0x10; /* WINDOW_A, XXX */
+ err = vm86_intcall(0x10, &vmf);
+ if ((err != 0) || (vmf.vmf_eax != 0x4f))
+ return 1;
+ *offset = vmf.vmf_dx*adp->va_window_gran;
+ return 0;
+}
+
+static int
vesa_set_origin(video_adapter_t *adp, off_t offset)
{
struct vm86frame vmf;
@@ -941,20 +1198,26 @@ vesa_set_origin(video_adapter_t *adp, off_t offset)
if (adp != vesa_adp)
return (*prevvidsw->set_win_org)(adp, offset);
- if (vesa_adp->va_window_gran == 0)
+ /* if this is a linear frame buffer, do nothing */
+ if (adp->va_info.vi_flags & V_INFO_LINEAR)
+ return 0;
+ /* XXX */
+ if (adp->va_window_gran == 0)
return 1;
+
bzero(&vmf, sizeof(vmf));
vmf.vmf_eax = 0x4f05;
vmf.vmf_ebx = 0; /* WINDOW_A, XXX */
- vmf.vmf_edx = offset/vesa_adp->va_window_gran;
+ vmf.vmf_edx = offset/adp->va_window_gran;
err = vm86_intcall(0x10, &vmf);
if ((err != 0) || (vmf.vmf_eax != 0x4f))
return 1;
bzero(&vmf, sizeof(vmf));
vmf.vmf_eax = 0x4f05;
vmf.vmf_ebx = 1; /* WINDOW_B, XXX */
- vmf.vmf_edx = offset/vesa_adp->va_window_gran;
+ vmf.vmf_edx = offset/adp->va_window_gran;
err = vm86_intcall(0x10, &vmf);
+ adp->va_window_orig = (offset/adp->va_window_gran)*adp->va_window_gran;
return 0; /* XXX */
}
@@ -979,25 +1242,222 @@ vesa_set_hw_cursor_shape(video_adapter_t *adp, int base, int height,
}
static int
-vesa_mmap(video_adapter_t *adp, vm_offset_t offset)
+vesa_blank_display(video_adapter_t *adp, int mode)
{
- return (*prevvidsw->mmap)(adp, offset);
+ /* XXX: use VESA DPMS */
+ return (*prevvidsw->blank_display)(adp, mode);
}
static int
-vesa_diag(video_adapter_t *adp, int level)
+vesa_mmap(video_adapter_t *adp, vm_offset_t offset, int prot)
{
-#if VESA_DEBUG > 1
- struct vesa_mode vmode;
- int i;
+#if VESA_DEBUG > 0
+ printf("vesa_mmap(): window:0x%x, buffer:0x%x, offset:0x%x\n",
+ adp->va_info.vi_window, adp->va_info.vi_buffer, offset);
#endif
- if (adp != vesa_adp)
+ if ((adp == vesa_adp) && (adp->va_info.vi_flags & V_INFO_LINEAR)) {
+ /* va_window_size == va_buffer_size/vi_planes */
+ /* XXX: is this correct? */
+ if (offset > adp->va_window_size - PAGE_SIZE)
+ return -1;
+#ifdef __i386__
+ return i386_btop(adp->va_info.vi_buffer + offset);
+#endif
+#ifdef __alpha__ /* XXX */
+ return alpha_btop(adp->va_info.vi_buffer + offset);
+#endif
+ } else {
+ return (*prevvidsw->mmap)(adp, offset, prot);
+ }
+}
+
+static int
+vesa_clear(video_adapter_t *adp)
+{
+ return (*prevvidsw->clear)(adp);
+}
+
+static int
+vesa_fill_rect(video_adapter_t *adp, int val, int x, int y, int cx, int cy)
+{
+ return (*prevvidsw->fill_rect)(adp, val, x, y, cx, cy);
+}
+
+static int
+vesa_bitblt(video_adapter_t *adp,...)
+{
+ /* FIXME */
+ return 1;
+}
+
+static int
+get_palette(video_adapter_t *adp, int base, int count,
+ u_char *red, u_char *green, u_char *blue, u_char *trans)
+{
+ u_char *r;
+ u_char *g;
+ u_char *b;
+ int bits;
+ int error;
+
+ if ((base < 0) || (base >= 256) || (base + count > 256))
+ return 1;
+ if (!(vesa_adp_info->v_flags & V_DAC8) || !VESA_MODE(adp->va_mode))
return 1;
-#ifndef KLD_MODULE
+ bits = vesa_bios_get_dac();
+ if (bits <= 6)
+ return 1;
+
+ r = malloc(count*3, M_DEVBUF, M_WAITOK);
+ g = r + count;
+ b = g + count;
+ error = vesa_bios_save_palette2(base, count, r, g, b, bits);
+ if (error == 0) {
+ copyout(r, red, count);
+ copyout(g, green, count);
+ copyout(b, blue, count);
+ if (trans != NULL) {
+ bzero(r, count);
+ copyout(r, trans, count);
+ }
+ }
+ free(r, M_DEVBUF);
+
+ /* if error && bits != 6 at this point, we are in in trouble... XXX */
+ return error;
+}
+
+static int
+set_palette(video_adapter_t *adp, int base, int count,
+ u_char *red, u_char *green, u_char *blue, u_char *trans)
+{
+ return 1;
+#if notyet
+ u_char *r;
+ u_char *g;
+ u_char *b;
+ int bits;
+ int error;
+
+ if ((base < 0) || (base >= 256) || (base + count > 256))
+ return 1;
+ if (!(vesa_adp_info->v_flags & V_DAC8) || !VESA_MODE(adp->va_mode)
+ || ((bits = vesa_bios_set_dac(8)) <= 6))
+ return 1;
+
+ r = malloc(count*3, M_DEVBUF, M_WAITOK);
+ g = r + count;
+ b = g + count;
+ copyin(red, r, count);
+ copyin(green, g, count);
+ copyin(blue, b, count);
+
+ error = vesa_bios_load_palette2(base, count, r, g, b, bits);
+ free(r, M_DEVBUF);
+ if (error == 0)
+ return 0;
+
+ /* if the following call fails, we are in trouble... XXX */
+ vesa_bios_set_dac(6);
+ return 1;
+#endif /* notyet */
+}
+
+static int
+vesa_ioctl(video_adapter_t *adp, u_long cmd, caddr_t arg)
+{
+ if (adp != vesa_adp)
+ return (*prevvidsw->ioctl)(adp, cmd, arg);
+
+ switch (cmd) {
+ case FBIO_SETWINORG: /* set frame buffer window origin */
+ return (vesa_set_origin(adp, *(off_t *)arg) ? ENODEV : 0);
+
+ case FBIO_SETDISPSTART: /* set display start address */
+ if (vesa_bios_set_start(((video_display_start_t *)arg)->x,
+ ((video_display_start_t *)arg)->y))
+ return ENODEV;
+ adp->va_disp_start.x = ((video_display_start_t *)arg)->x;
+ adp->va_disp_start.y = ((video_display_start_t *)arg)->y;
+ return 0;
+
+ case FBIO_SETLINEWIDTH: /* set line length in pixel */
+ if (vesa_bios_set_line_length(*(u_int *)arg))
+ return ENODEV;
+ adp->va_line_width = (*(u_int *)arg + 7)/8;
+ return 0;
+
+ case FBIO_GETPALETTE: /* get color palette */
+ if (get_palette(adp, ((video_color_palette_t *)arg)->index,
+ ((video_color_palette_t *)arg)->count,
+ ((video_color_palette_t *)arg)->red,
+ ((video_color_palette_t *)arg)->green,
+ ((video_color_palette_t *)arg)->blue,
+ ((video_color_palette_t *)arg)->transparent))
+ return (*prevvidsw->ioctl)(adp, cmd, arg);
+ return 0;
+
+
+ case FBIO_SETPALETTE: /* set color palette */
+ if (set_palette(adp, ((video_color_palette_t *)arg)->index,
+ ((video_color_palette_t *)arg)->count,
+ ((video_color_palette_t *)arg)->red,
+ ((video_color_palette_t *)arg)->green,
+ ((video_color_palette_t *)arg)->blue,
+ ((video_color_palette_t *)arg)->transparent))
+ return (*prevvidsw->ioctl)(adp, cmd, arg);
+ return 0;
+
+ case FBIOGETCMAP: /* get color palette */
+ if (get_palette(adp, ((struct fbcmap *)arg)->index,
+ ((struct fbcmap *)arg)->count,
+ ((struct fbcmap *)arg)->red,
+ ((struct fbcmap *)arg)->green,
+ ((struct fbcmap *)arg)->blue, NULL))
+ return (*prevvidsw->ioctl)(adp, cmd, arg);
+ return 0;
+
+ case FBIOPUTCMAP: /* set color palette */
+ if (set_palette(adp, ((struct fbcmap *)arg)->index,
+ ((struct fbcmap *)arg)->count,
+ ((struct fbcmap *)arg)->red,
+ ((struct fbcmap *)arg)->green,
+ ((struct fbcmap *)arg)->blue, NULL))
+ return (*prevvidsw->ioctl)(adp, cmd, arg);
+ return 0;
+
+ default:
+ return (*prevvidsw->ioctl)(adp, cmd, arg);
+ }
+}
+
+static int
+vesa_diag(video_adapter_t *adp, int level)
+{
+ int error;
+
/* call the previous handler first */
- (*prevvidsw->diag)(adp, level);
+ error = (*prevvidsw->diag)(adp, level);
+ if (error)
+ return error;
+
+ if (adp != vesa_adp)
+ return 1;
+
+ if (level <= 0)
+ return 0;
+
+ return 0;
+}
+
+static int
+vesa_bios_info(int level)
+{
+#if VESA_DEBUG > 1
+ struct vesa_mode vmode;
+ int i;
#endif
/* general adapter information */
@@ -1016,15 +1476,11 @@ vesa_diag(video_adapter_t *adp, int level)
return 0;
if (vesa_adp_info->v_version >= 0x0200) {
- /* vendor name */
- if (vesa_venderstr != NULL)
- printf("VESA: %s\n", vesa_venderstr);
- /* product name */
- if (vesa_prodstr != NULL)
- printf("VESA: %s\n", vesa_prodstr);
- /* product revision */
- if (vesa_revstr != NULL)
- printf("VESA: %s\n", vesa_revstr);
+ /* vender name, product name, product revision */
+ printf("VESA: %s %s %s\n",
+ (vesa_venderstr != NULL) ? vesa_venderstr : "unknown",
+ (vesa_prodstr != NULL) ? vesa_prodstr : "unknown",
+ (vesa_revstr != NULL) ? vesa_revstr : "?");
}
#if VESA_DEBUG > 1
@@ -1047,13 +1503,15 @@ vesa_diag(video_adapter_t *adp, int level)
printf(", T %dx%d, ",
vmode.v_width, vmode.v_height);
}
- printf("font:%dx%d",
+ printf("font:%dx%d, ",
vmode.v_cwidth, vmode.v_cheight);
+ printf("pages:%d, mem:%d",
+ vmode.v_ipages + 1, vmode.v_memmodel);
}
if (vmode.v_modeattr & V_MODELFB) {
- printf(", mem:%d, LFB:0x%x, off:0x%x",
- vmode.v_memmodel, vmode.v_lfb,
- vmode.v_offscreen);
+ printf("\nVESA: LFB:0x%x, off:0x%x, off_size:0x%x",
+ vmode.v_lfb, vmode.v_offscreen,
+ vmode.v_offscreensize*1024);
}
printf("\n");
printf("VESA: window A:0x%x (%x), window B:0x%x (%x), ",
@@ -1062,7 +1520,7 @@ vesa_diag(video_adapter_t *adp, int level)
printf("size:%dk, gran:%dk\n",
vmode.v_wsize, vmode.v_wgran);
}
-#endif
+#endif /* VESA_DEBUG > 1 */
return 0;
}
@@ -1084,14 +1542,14 @@ vesa_load(void)
error = vesa_configure(0);
splx(s);
-#ifdef KLD_MODULE
if (error == 0)
- vesa_diag(vesa_adp, bootverbose);
-#endif
+ vesa_bios_info(bootverbose);
return error;
}
+#ifdef KLD_MODULE
+
static int
vesa_unload(void)
{
@@ -1130,6 +1588,8 @@ vesa_unload(void)
return error;
}
+#endif /* KLD_MODULE */
+
static int
vesa_mod_event(module_t mod, int type, void *data)
{
@@ -1137,7 +1597,11 @@ vesa_mod_event(module_t mod, int type, void *data)
case MOD_LOAD:
return vesa_load();
case MOD_UNLOAD:
+#ifdef KLD_MODULE
return vesa_unload();
+#else
+ return EBUSY;
+#endif
default:
break;
}
diff --git a/sys/isa/sio.c b/sys/isa/sio.c
index c3be310..6c17bc1 100644
--- a/sys/isa/sio.c
+++ b/sys/isa/sio.c
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: sio.c,v 1.248 1999/06/19 08:14:56 grog Exp $
+ * $Id: sio.c,v 1.249 1999/06/20 13:10:09 peter Exp $
* from: @(#)com.c 7.5 (Berkeley) 5/16/91
* from: i386/isa sio.c,v 1.234
*/
@@ -2656,7 +2656,7 @@ static cn_checkc_t siocncheckc;
static cn_getc_t siocngetc;
static cn_putc_t siocnputc;
-CONS_DRIVER(sio, siocnprobe, siocninit, siocngetc, siocncheckc, siocnputc);
+CONS_DRIVER(sio, siocnprobe, siocninit, NULL, siocngetc, siocncheckc, siocnputc);
/* To get the GDB related variables */
#if DDB > 0
@@ -2855,7 +2855,6 @@ siocnprobe(cp)
cp->cn_pri = COM_FORCECONSOLE(flags)
|| boothowto & RB_SERIAL
? CN_REMOTE : CN_NORMAL;
- printf("sio%d: system console\n", unit);
siocniobase = iobase;
siocnunit = unit;
}
@@ -2897,10 +2896,7 @@ siocnprobe(cp)
#ifdef __alpha__
-struct consdev siocons = {
- NULL, NULL, siocngetc, siocncheckc, siocnputc,
- NULL, 0, CN_NORMAL,
-};
+CONS_DRIVER(sio, NULL, NULL, NULL, siocngetc, siocncheckc, siocnputc);
extern struct consdev *cn_tab;
@@ -2915,6 +2911,8 @@ siocnattach(port, speed)
siocniobase = port;
comdefaultrate = speed;
+ sio_consdev.cn_pri = CN_NORMAL;
+ sio_consdev.cn_dev = makedev(CDEV_MAJOR, 0);
s = spltty();
@@ -2938,8 +2936,7 @@ siocnattach(port, speed)
siocnopen(&sp, siocniobase, comdefaultrate);
splx(s);
- siocons.cn_dev = makedev(CDEV_MAJOR, 0);
- cn_tab = &siocons;
+ cn_tab = &sio_consdev;
return 0;
}
diff --git a/sys/isa/syscons_isa.c b/sys/isa/syscons_isa.c
index 85e626e..fcb2b06 100644
--- a/sys/isa/syscons_isa.c
+++ b/sys/isa/syscons_isa.c
@@ -23,7 +23,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: syscons_isa.c,v 1.3 1999/05/08 21:59:31 dfr Exp $
+ * $Id: syscons_isa.c,v 1.4 1999/05/30 11:12:29 dfr Exp $
*/
#include "sc.h"
@@ -37,33 +37,53 @@
#include <sys/module.h>
#include <sys/bus.h>
+#include <machine/cons.h>
#include <machine/console.h>
+
#ifdef __i386__
-#include <machine/apm_bios.h>
-#endif
+
+#include <machine/clock.h>
+#include <machine/md_var.h>
+#include <machine/pc/bios.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <i386/isa/timerreg.h>
+
+#define BIOS_CLKED (1 << 6)
+#define BIOS_NLKED (1 << 5)
+#define BIOS_SLKED (1 << 4)
+#define BIOS_ALKED 0
+
+#endif /* __i386__ */
#include <dev/syscons/syscons.h>
#include <isa/isareg.h>
#include <isa/isavar.h>
-devclass_t sc_devclass;
+static devclass_t sc_devclass;
static int scprobe(device_t dev);
static int scattach(device_t dev);
+static int scresume(device_t dev);
static device_method_t sc_methods[] = {
DEVMETHOD(device_probe, scprobe),
DEVMETHOD(device_attach, scattach),
+ DEVMETHOD(device_resume, scresume),
{ 0, 0 }
};
static driver_t sc_driver = {
- "sc",
+ SC_DRIVER_NAME,
sc_methods,
1, /* XXX */
};
+static sc_softc_t main_softc = { 0, 0, 0, -1, NULL, -1, NULL, };
+
static int
scprobe(device_t dev)
{
@@ -81,6 +101,146 @@ scattach(device_t dev)
return sc_attach_unit(device_get_unit(dev), isa_get_flags(dev));
}
+static int
+scresume(device_t dev)
+{
+ return sc_resume_unit(device_get_unit(dev));
+}
+
+int
+sc_max_unit(void)
+{
+ return devclass_get_maxunit(sc_devclass);
+}
+
+sc_softc_t
+*sc_get_softc(int unit, int flags)
+{
+ sc_softc_t *sc;
+
+ if ((unit < 0) || (unit >= NSC))
+ return NULL;
+ if (flags & SC_KERNEL_CONSOLE) {
+ /* FIXME: clear if it is wired to another unit! */
+ main_softc.unit = unit;
+ return &main_softc;
+ } else {
+ sc = (sc_softc_t *)devclass_get_softc(sc_devclass, unit);
+ if (!(sc->flags & SC_INIT_DONE)) {
+ sc->unit = unit;
+ sc->keyboard = -1;
+ sc->adapter = -1;
+ }
+ return sc;
+ }
+}
+
+sc_softc_t
+*sc_find_softc(struct video_adapter *adp, struct keyboard *kbd)
+{
+ sc_softc_t *sc;
+ int units;
+ int i;
+
+ sc = &main_softc;
+ if (((adp == NULL) || (adp == sc->adp))
+ && ((kbd == NULL) || (kbd == sc->kbd)))
+ return sc;
+ units = devclass_get_maxunit(sc_devclass);
+ for (i = 0; i < units; ++i) {
+ sc = (sc_softc_t *)devclass_get_softc(sc_devclass, i);
+ if (sc == NULL)
+ continue;
+ if (((adp == NULL) || (adp == sc->adp))
+ && ((kbd == NULL) || (kbd == sc->kbd)))
+ return sc;
+ }
+ return NULL;
+}
+
+int
+sc_get_cons_priority(int *unit, int *flags)
+{
+ int disabled;
+ int u, f;
+ int i;
+
+ *unit = -1;
+ for (i = -1; (i = resource_locate(i, SC_DRIVER_NAME)) >= 0;) {
+ u = resource_query_unit(i);
+ if ((resource_int_value(SC_DRIVER_NAME, u, "disabled",
+ &disabled) == 0) && disabled)
+ continue;
+ if (resource_int_value(SC_DRIVER_NAME, u, "flags", &f) != 0)
+ f = 0;
+ if (f & SC_KERNEL_CONSOLE) {
+ /* the user designates this unit to be the console */
+ *unit = u;
+ *flags = f;
+ break;
+ }
+ if (*unit < 0) {
+ /* ...otherwise remember the first found unit */
+ *unit = u;
+ *flags = f;
+ }
+ }
+ if ((i < 0) && (*unit < 0))
+ return CN_DEAD;
+#if 0
+ return ((*flags & SC_KERNEL_CONSOLE) ? CN_INTERNAL : CN_NORMAL);
+#endif
+ return CN_INTERNAL;
+}
+
+void
+sc_get_bios_values(bios_values_t *values)
+{
+#ifdef __i386__
+ u_int8_t shift;
+
+ values->cursor_start = *(u_int8_t *)BIOS_PADDRTOVADDR(0x461);
+ values->cursor_end = *(u_int8_t *)BIOS_PADDRTOVADDR(0x460);
+ shift = *(u_int8_t *)BIOS_PADDRTOVADDR(0x417);
+ values->shift_state = ((shift & BIOS_CLKED) ? CLKED : 0)
+ | ((shift & BIOS_NLKED) ? NLKED : 0)
+ | ((shift & BIOS_SLKED) ? SLKED : 0)
+ | ((shift & BIOS_ALKED) ? ALKED : 0);
+ values->bell_pitch = BELL_PITCH;
+#else /* !__i386__ */
+ values->cursor_start = 0;
+ values->cursor_end = 32;
+ values->shift_state = 0;
+ values->bell_pitch = BELL_PITCH;
+#endif /* __i386__ */
+}
+
+int
+sc_tone(int herz)
+{
+#ifdef __i386__
+ int pitch;
+
+ if (herz) {
+ /* set command for counter 2, 2 byte write */
+ if (acquire_timer2(TIMER_16BIT | TIMER_SQWAVE))
+ return EBUSY;
+ /* set pitch */
+ pitch = timer_freq/herz;
+ outb(TIMER_CNTR2, pitch);
+ outb(TIMER_CNTR2, pitch >> 8);
+ /* enable counter 2 output to speaker */
+ outb(IO_PPI, inb(IO_PPI) | 3);
+ } else {
+ /* disable counter 2 output to speaker */
+ outb(IO_PPI, inb(IO_PPI) & 0xFC);
+ release_timer2();
+ }
+#endif /* __i386__ */
+
+ return 0;
+}
+
DRIVER_MODULE(sc, isa, sc_driver, sc_devclass, 0, 0);
#endif /* NSC > 0 */
diff --git a/sys/isa/vga_isa.c b/sys/isa/vga_isa.c
index 07bffa8..813458e 100644
--- a/sys/isa/vga_isa.c
+++ b/sys/isa/vga_isa.c
@@ -1,6 +1,5 @@
/*-
* Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
- * Copyright (c) 1992-1998 Søren Schmidt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -12,8 +11,6 @@
* 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 AUTHORS ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@@ -26,7 +23,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: vga_isa.c,v 1.9 1999/05/30 11:12:30 dfr Exp $
+ * $Id: vga_isa.c,v 1.10 1999/05/30 16:52:49 phk Exp $
*/
#include "vga.h"
@@ -39,13 +36,18 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
+#include <sys/conf.h>
#include <sys/bus.h>
-#include <sys/malloc.h>
+#include <sys/fbio.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+
+#include <sys/rman.h>
#include <vm/vm.h>
#include <vm/pmap.h>
-#include <machine/console.h>
#include <machine/md_var.h>
#include <machine/pc/bios.h>
@@ -55,21 +57,10 @@
#include <isa/isareg.h>
#include <isa/isavar.h>
-#define DRIVER_NAME "vga"
-
-/* cdev driver declaration */
-
-#define ISAVGA_UNIT(dev) minor(dev)
-#define ISAVGA_MKMINOR(unit) (unit)
+#define VGA_SOFTC(unit) \
+ ((vga_softc_t *)devclass_get_softc(isavga_devclass, unit))
-typedef struct isavga_softc {
- video_adapter_t *adp;
-} isavga_softc_t;
-
-#define ISAVGA_SOFTC(unit) \
- ((isavga_softc_t *)devclass_get_softc(isavga_devclass, unit))
-
-devclass_t isavga_devclass;
+static devclass_t isavga_devclass;
static int isavga_probe(device_t dev);
static int isavga_attach(device_t dev);
@@ -77,42 +68,41 @@ static int isavga_attach(device_t dev);
static device_method_t isavga_methods[] = {
DEVMETHOD(device_probe, isavga_probe),
DEVMETHOD(device_attach, isavga_attach),
+
+ DEVMETHOD(bus_print_child, bus_generic_print_child),
{ 0, 0 }
};
static driver_t isavga_driver = {
- DRIVER_NAME,
+ VGA_DRIVER_NAME,
isavga_methods,
- sizeof(isavga_softc_t),
+ sizeof(vga_softc_t),
};
DRIVER_MODULE(vga, isa, isavga_driver, isavga_devclass, 0, 0);
-static int isavga_probe_unit(int unit, isavga_softc_t *sc,
- int flags);
-static int isavga_attach_unit(int unit, isavga_softc_t *sc,
- int flags);
-
#ifdef FB_INSTALL_CDEV
-static d_open_t isavgaopen;
-static d_close_t isavgaclose;
-static d_read_t isavgaread;
-static d_ioctl_t isavgaioctl;
-
-static struct cdevsw vga_cdevsw = {
- /* open */ isavgaopen,
- /* close */ isavgaclose,
- /* read */ noread,
- /* write */ nowrite,
- /* ioctl */ isavgaioctl,
+static d_open_t isavga_open;
+static d_close_t isavga_close;
+static d_read_t isavga_read;
+static d_write_t isavga_write;
+static d_ioctl_t isavga_ioctl;
+static d_mmap_t isavga_mmap;
+
+static struct cdevsw isavga_cdevsw = {
+ /* open */ isavga_open,
+ /* close */ isavga_close,
+ /* read */ isavga_read,
+ /* write */ isavga_write,
+ /* ioctl */ isavga_ioctl,
/* stop */ nostop,
/* reset */ noreset,
/* devtotty */ nodevtotty,
/* poll */ nopoll,
- /* mmap */ nommap,
+ /* mmap */ isavga_mmap,
/* strategy */ nostrategy,
- /* name */ DRIVER_NAME,
+ /* name */ VGA_DRIVER_NAME,
/* parms */ noparms,
/* maj */ -1,
/* dump */ nodump,
@@ -127,56 +117,59 @@ static struct cdevsw vga_cdevsw = {
static int
isavga_probe(device_t dev)
{
- isavga_softc_t *sc;
+ video_adapter_t adp;
+ device_t bus;
+ int error;
/* No pnp support */
if (isa_get_vendorid(dev))
return (ENXIO);
device_set_desc(dev, "Generic ISA VGA");
- sc = device_get_softc(dev);
- return isavga_probe_unit(device_get_unit(dev), sc, isa_get_flags(dev));
+ error = vga_probe_unit(device_get_unit(dev), &adp, isa_get_flags(dev));
+ if (error == 0) {
+ bus = device_get_parent(dev);
+ ISA_SET_RESOURCE(bus, dev, SYS_RES_IOPORT, 0,
+ adp.va_io_base, adp.va_io_size);
+ ISA_SET_RESOURCE(bus, dev, SYS_RES_MEMORY, 0,
+ adp.va_mem_base, adp.va_mem_size);
+#if 0
+ isa_set_port(dev, adp.va_io_base);
+ isa_set_portsize(dev, adp.va_io_size);
+ isa_set_maddr(dev, adp.va_mem_base);
+ isa_set_msize(dev, adp.va_mem_size);
+#endif
+ }
+ return error;
}
static int
isavga_attach(device_t dev)
{
- isavga_softc_t *sc;
+ vga_softc_t *sc;
+ struct resource *port;
+ struct resource *mem;
+ int unit;
+ int rid;
+ int error;
+ unit = device_get_unit(dev);
sc = device_get_softc(dev);
- return isavga_attach_unit(device_get_unit(dev), sc, isa_get_flags(dev));
-}
-
-static int
-isavga_probe_unit(int unit, isavga_softc_t *sc, int flags)
-{
- video_switch_t *sw;
-
- bzero(sc, sizeof(*sc));
- sw = vid_get_switch(DRIVER_NAME);
- if (sw == NULL)
- return 0;
- return (*sw->probe)(unit, &sc->adp, NULL, flags);
-}
-
-static int
-isavga_attach_unit(int unit, isavga_softc_t *sc, int flags)
-{
- video_switch_t *sw;
- int error;
- sw = vid_get_switch(DRIVER_NAME);
- if (sw == NULL)
- return ENXIO;
+ rid = 0;
+ port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
+ 0, ~0, 0, RF_ACTIVE | RF_SHAREABLE);
+ rid = 0;
+ mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
+ 0, ~0, 0, RF_ACTIVE | RF_SHAREABLE);
- error = (*sw->init)(unit, sc->adp, flags);
+ error = vga_attach_unit(unit, sc, isa_get_flags(dev));
if (error)
- return ENXIO;
+ return error;
#ifdef FB_INSTALL_CDEV
/* attach a virtual frame buffer device */
- error = fb_attach(makedev(0, ISAVGA_MKMINOR(unit)), scp->adp,
- &vga_cdevsw);
+ error = fb_attach(makedev(0, VGA_MKMINOR(unit)), sc->adp, &isavga_cdevsw);
if (error)
return error;
#endif /* FB_INSTALL_CDEV */
@@ -184,2010 +177,52 @@ isavga_attach_unit(int unit, isavga_softc_t *sc, int flags)
if (bootverbose)
(*vidsw[sc->adp->va_index]->diag)(sc->adp, bootverbose);
- return 0;
-}
-
-/* LOW-LEVEL */
-
-#include <machine/clock.h>
-#include <machine/pc/vesa.h>
-
-#define probe_done(adp) ((adp)->va_flags & V_ADP_PROBED)
-#define init_done(adp) ((adp)->va_flags & V_ADP_INITIALIZED)
-#define config_done(adp) ((adp)->va_flags & V_ADP_REGISTERED)
-
-/* for compatibility with old kernel options */
-#ifdef SC_ALT_SEQACCESS
-#undef SC_ALT_SEQACCESS
-#undef VGA_ALT_SEQACCESS
-#define VGA_ALT_SEQACCESS 1
-#endif
-
-#ifdef SLOW_VGA
-#undef SLOW_VGA
-#undef VGA_SLOW_IOACCESS
-#define VGA_SLOW_IOACCESS 1
-#endif
-
-/* architecture dependent option */
-#ifdef __alpha__
-#define VGA_NO_BIOS 1
-#endif
-
-/* this should really be in `rtc.h' */
-#define RTC_EQUIPMENT 0x14
-
-/* various sizes */
-#define V_MODE_MAP_SIZE (M_VGA_CG320 + 1)
-#define V_MODE_PARAM_SIZE 64
-
-/* 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[] = {
- /* DCC_MONO */
- { 0, KD_MONO, "mda", 0, 0, 0, IO_MDA, IO_MDASIZE, MONO_CRTC,
- MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE,
- 0, 0, 0, 7, 0, },
- /* DCC_CGA40 */
- { 0, KD_CGA, "cga", 0, 0, V_ADP_COLOR, IO_CGA, IO_CGASIZE, COLOR_CRTC,
- CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE,
- 0, 0, 0, 3, 0, },
- /* DCC_CGA80 */
- { 0, KD_CGA, "cga", 0, 0, V_ADP_COLOR, IO_CGA, IO_CGASIZE, COLOR_CRTC,
- CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE,
- 0, 0, 0, 3, 0, },
- /* DCC_EGAMONO */
- { 0, KD_EGA, "ega", 0, 0, 0, IO_MDA, 48, MONO_CRTC,
- EGA_BUF_BASE, EGA_BUF_SIZE, MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE,
- 0, 0, 0, 7, 0, },
- /* DCC_EGA40 */
- { 0, KD_EGA, "ega", 0, 0, V_ADP_COLOR, IO_MDA, 48, COLOR_CRTC,
- EGA_BUF_BASE, EGA_BUF_SIZE, CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE,
- 0, 0, 0, 3, 0, },
- /* DCC_EGA80 */
- { 0, KD_EGA, "ega", 0, 0, V_ADP_COLOR, IO_MDA, 48, COLOR_CRTC,
- EGA_BUF_BASE, EGA_BUF_SIZE, CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE,
- 0, 0, 0, 3, 0, },
-};
-
-static video_adapter_t biosadapter[2];
-static int biosadapters = 0;
-
-/* video driver declarations */
-static int vga_configure(int flags);
- int (*vga_sub_configure)(int flags);
-static int vga_nop(void);
-static vi_probe_t vga_probe;
-static vi_init_t vga_init;
-static vi_get_info_t vga_get_info;
-static vi_query_mode_t vga_query_mode;
-static vi_set_mode_t vga_set_mode;
-static vi_save_font_t vga_save_font;
-static vi_load_font_t vga_load_font;
-static vi_show_font_t vga_show_font;
-static vi_save_palette_t vga_save_palette;
-static vi_load_palette_t vga_load_palette;
-static vi_set_border_t vga_set_border;
-static vi_save_state_t vga_save_state;
-static vi_load_state_t vga_load_state;
-static vi_set_win_org_t vga_set_origin;
-static vi_read_hw_cursor_t vga_read_hw_cursor;
-static vi_set_hw_cursor_t vga_set_hw_cursor;
-static vi_set_hw_cursor_shape_t vga_set_hw_cursor_shape;
-static vi_mmap_t vga_mmap;
-static vi_diag_t vga_diag;
-
-static video_switch_t vgavidsw = {
- vga_probe,
- vga_init,
- vga_get_info,
- vga_query_mode,
- vga_set_mode,
- vga_save_font,
- vga_load_font,
- vga_show_font,
- vga_save_palette,
- vga_load_palette,
- vga_set_border,
- vga_save_state,
- vga_load_state,
- vga_set_origin,
- vga_read_hw_cursor,
- vga_set_hw_cursor,
- vga_set_hw_cursor_shape,
- (vi_blank_display_t *)vga_nop,
- vga_mmap,
- vga_diag,
-};
-
-VIDEO_DRIVER(mda, vgavidsw, NULL);
-VIDEO_DRIVER(cga, vgavidsw, NULL);
-VIDEO_DRIVER(ega, vgavidsw, NULL);
-VIDEO_DRIVER(vga, vgavidsw, vga_configure);
-
-/* 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,
- CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0 },
- { M_C40x25, V_INFO_COLOR, 40, 25, 8, 8, 4, 1,
- CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0 },
- { M_B80x25, V_INFO_COLOR, 80, 25, 8, 8, 2, 1,
- CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0 },
- { M_C80x25, V_INFO_COLOR, 80, 25, 8, 8, 4, 1,
- CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0 },
- /* EGA */
- { M_ENH_B40x25, V_INFO_COLOR, 40, 25, 8, 14, 2, 1,
- CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0 },
- { M_ENH_C40x25, V_INFO_COLOR, 40, 25, 8, 14, 4, 1,
- CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0 },
- { M_ENH_B80x25, V_INFO_COLOR, 80, 25, 8, 14, 2, 1,
- CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0 },
- { M_ENH_C80x25, V_INFO_COLOR, 80, 25, 8, 14, 4, 1,
- CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0 },
- /* VGA */
- { M_VGA_C40x25, V_INFO_COLOR, 40, 25, 8, 16, 4, 1,
- CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0 },
- { M_VGA_M80x25, 0, 80, 25, 8, 16, 2, 1,
- MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE, 0, 0 },
- { M_VGA_C80x25, V_INFO_COLOR, 80, 25, 8, 16, 4, 1,
- CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0 },
- /* MDA */
- { M_EGAMONO80x25, 0, 80, 25, 8, 14, 2, 1,
- MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE, 0, 0 },
- /* EGA */
- { M_ENH_B80x43, V_INFO_COLOR, 80, 43, 8, 8, 2, 1,
- CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0 },
- { M_ENH_C80x43, V_INFO_COLOR, 80, 43, 8, 8, 4, 1,
- CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0 },
- /* VGA */
- { M_VGA_M80x30, 0, 80, 30, 8, 16, 2, 1,
- MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE, 0, 0 },
- { M_VGA_C80x30, V_INFO_COLOR, 80, 30, 8, 16, 4, 1,
- CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0 },
- { M_VGA_M80x50, 0, 80, 50, 8, 8, 2, 1,
- MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE, 0, 0 },
- { M_VGA_C80x50, V_INFO_COLOR, 80, 50, 8, 8, 4, 1,
- CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0 },
- { M_VGA_M80x60, 0, 80, 60, 8, 8, 2, 1,
- MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE, 0, 0 },
- { M_VGA_C80x60, V_INFO_COLOR, 80, 60, 8, 8, 4, 1,
- CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0 },
-#ifndef VGA_NO_MODE_CHANGE
- /* CGA */
- { M_BG320, V_INFO_COLOR | V_INFO_GRAPHICS, 320, 200, 8, 8, 2, 1,
- CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0 },
- { M_CG320, V_INFO_COLOR | V_INFO_GRAPHICS, 320, 200, 8, 8, 2, 1,
- CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0 },
- { M_BG640, V_INFO_COLOR | V_INFO_GRAPHICS, 640, 200, 8, 8, 1, 1,
- CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0 },
- /* EGA */
- { M_CG320_D, V_INFO_COLOR | V_INFO_GRAPHICS, 320, 200, 8, 8, 4, 4,
- GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0 },
- { M_CG640_E, V_INFO_COLOR | V_INFO_GRAPHICS, 640, 200, 8, 8, 4, 4,
- GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0 },
- { M_EGAMONOAPA, V_INFO_GRAPHICS, 640, 350, 8, 14, 4, 4,
- GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, 64*1024, 0, 0 },
- { M_ENHMONOAPA2,V_INFO_GRAPHICS, 640, 350, 8, 14, 4, 4,
- GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0 },
- { M_CG640x350, V_INFO_COLOR | V_INFO_GRAPHICS, 640, 350, 8, 14, 2, 2,
- GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0 },
- { M_ENH_CG640, V_INFO_COLOR | V_INFO_GRAPHICS, 640, 350, 8, 14, 4, 4,
- GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0 },
- /* VGA */
- { M_BG640x480, V_INFO_COLOR | V_INFO_GRAPHICS, 640, 480, 8, 16, 4, 4,
- GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0 },
- { M_CG640x480, V_INFO_COLOR | V_INFO_GRAPHICS, 640, 480, 8, 16, 4, 4,
- GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0 },
- { M_VGA_CG320, V_INFO_COLOR | V_INFO_GRAPHICS, 320, 200, 8, 8, 8, 1,
- GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0 },
- { M_VGA_MODEX, V_INFO_COLOR | V_INFO_GRAPHICS, 320, 240, 8, 8, 8, 1,
- GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0 },
-#endif /* VGA_NO_MODE_CHANGE */
-
- { EOT },
-};
-
-static int init_done = FALSE;
-#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE)
-static u_char *video_mode_ptr = NULL; /* EGA/VGA */
-static u_char *video_mode_ptr2 = NULL; /* CGA/MDA */
-#endif
-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))
-
-#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE)
-static void map_mode_table(u_char *map[], u_char *table, int max);
-#endif
-static void clear_mode_map(video_adapter_t *adp, u_char *map[], int max,
- int color);
-#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE)
-static int map_mode_num(int mode);
-#endif
-static int map_gen_mode_num(int type, int color, int mode);
-static int map_bios_mode_num(int type, int color, int bios_mode);
-static u_char *get_mode_param(int mode);
-#ifndef VGA_NO_BIOS
-static void fill_adapter_param(int code, video_adapter_t *adp);
-#endif
-static int verify_adapter(video_adapter_t *adp);
-static void update_adapter_info(video_adapter_t *adp, video_info_t *info);
-#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE)
-#define COMP_IDENTICAL 0
-#define COMP_SIMILAR 1
-#define COMP_DIFFERENT 2
-static int comp_adpregs(u_char *buf1, u_char *buf2);
-#endif
-static int probe_adapters(void);
-
-#ifndef VGA_NO_FONT_LOADING
-#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);
+#if experimental
+ device_add_child(dev, "fb", -1, NULL);
+ bus_generic_attach(dev);
#endif
-static void dump_buffer(u_char *buf, size_t len);
-
-#define ISMAPPED(pa, width) \
- (((pa) <= (u_long)0x1000 - (width)) \
- || ((pa) >= ISA_HOLE_START && (pa) <= 0x100000 - (width)))
-
-#define prologue(adp, flag, err) \
- if (!init_done || !((adp)->va_flags & (flag))) \
- return (err)
-
-/* a backdoor for the console driver */
-static int
-vga_configure(int flags)
-{
- int i;
-
- probe_adapters();
- for (i = 0; i < biosadapters; ++i) {
- if (!probe_done(&biosadapter[i]))
- continue;
- biosadapter[i].va_flags |= V_ADP_INITIALIZED;
- if (!config_done(&biosadapter[i])) {
- if (vid_register(&biosadapter[i]) < 0)
- continue;
- biosadapter[i].va_flags |= V_ADP_REGISTERED;
- }
- }
- if (vga_sub_configure != NULL)
- (*vga_sub_configure)(flags);
-
- return biosadapters;
-}
-
-/* local subroutines */
-
-#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE)
-/* 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;
-}
-#endif /* !VGA_NO_BIOS && !VGA_NO_MODE_CHANGE */
-
-static void
-clear_mode_map(video_adapter_t *adp, 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 (vga_get_info(adp, i, &info))
- continue;
- if ((info.vi_flags & V_INFO_COLOR) != color)
- map[i] = NULL;
- }
-}
-
-#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE)
-/* map the non-standard video mode to a known mode number */
-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;
-}
-#endif /* !VGA_NO_BIOS && !VGA_NO_MODE_CHANGE */
-
-/* map a generic video mode to a known mode number */
-static int
-map_gen_mode_num(int type, int color, int mode)
-{
- static struct {
- int from;
- int to_color;
- int to_mono;
- } mode_map[] = {
- { M_TEXT_80x30, M_VGA_C80x30, M_VGA_M80x30, },
- { M_TEXT_80x43, M_ENH_C80x43, M_ENH_B80x43, },
- { M_TEXT_80x50, M_VGA_C80x50, M_VGA_M80x50, },
- { M_TEXT_80x60, M_VGA_C80x60, M_VGA_M80x60, },
- };
- int i;
-
- if (mode == M_TEXT_80x25) {
- switch (type) {
-
- case KD_VGA:
- if (color)
- return M_VGA_C80x25;
- else
- return M_VGA_M80x25;
- break;
-
- case KD_EGA:
- if (color)
- return M_ENH_C80x25;
- else
- return M_EGAMONO80x25;
- break;
-
- case KD_CGA:
- return M_C80x25;
-
- case KD_MONO:
- case KD_HERCULES:
- return M_EGAMONO80x25; /* XXX: this name is confusing */
-
- default:
- return -1;
- }
- }
-
- for (i = 0; i < sizeof(mode_map)/sizeof(mode_map[0]); ++i) {
- if (mode_map[i].from == mode)
- return ((color) ? mode_map[i].to_color : mode_map[i].to_mono);
- }
- 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 !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE)
- if (mode >= V_MODE_MAP_SIZE)
- mode = map_mode_num(mode);
-#endif
- if ((mode >= 0) && (mode < V_MODE_MAP_SIZE))
- return mode_map[mode];
- else
- return NULL;
-}
-
-#ifndef VGA_NO_BIOS
-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];
- }
-}
-#endif /* VGA_NO_BIOS */
-
-static int
-verify_adapter(video_adapter_t *adp)
-{
- vm_offset_t buf;
- u_int16_t v;
-#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE)
- u_int32_t p;
-#endif
-
- 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_name = "vga";
- adp->va_flags |= V_ADP_STATESAVE | V_ADP_PALETTE;
- }
- adp->va_flags |= V_ADP_STATELOAD | V_ADP_BORDER;
- /* the color adapter may be in the 40x25 mode... XXX */
-
-#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE)
- /* 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 */
-#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE)
- /* get the BIOS video mode pointer */
- p = *(u_int32_t *)BIOS_PADDRTOVADDR(0x1d*4);
- p = BIOS_SADDRTOLADDR(p);
- video_mode_ptr2 = (u_char *)BIOS_PADDRTOVADDR(p);
-#endif
- break;
-
- case KD_MONO:
-#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE)
- /* get the BIOS video mode pointer */
- p = *(u_int32_t *)BIOS_PADDRTOVADDR(0x1d*4);
- p = BIOS_SADDRTOLADDR(p);
- video_mode_ptr2 = (u_char *)BIOS_PADDRTOVADDR(p);
-#endif
- break;
- }
-
- return 0;
-}
-
-static void
-update_adapter_info(video_adapter_t *adp, video_info_t *info)
-{
- adp->va_flags &= ~V_ADP_COLOR;
- adp->va_flags |=
- (info->vi_flags & V_INFO_COLOR) ? V_ADP_COLOR : 0;
- adp->va_crtc_addr =
- (adp->va_flags & V_ADP_COLOR) ? COLOR_CRTC : MONO_CRTC;
- adp->va_window = BIOS_PADDRTOVADDR(info->vi_window);
- adp->va_window_size = info->vi_window_size;
- adp->va_window_gran = info->vi_window_gran;
- if (info->vi_buffer_size == 0) {
- adp->va_buffer = 0;
- adp->va_buffer_size = 0;
- } else {
- adp->va_buffer = BIOS_PADDRTOVADDR(info->vi_buffer);
- adp->va_buffer_size = info->vi_buffer_size;
- }
- if (info->vi_flags & V_INFO_GRAPHICS) {
- switch (info->vi_depth/info->vi_planes) {
- case 1:
- adp->va_line_width = info->vi_width/8;
- break;
- case 2:
- adp->va_line_width = info->vi_width/4;
- break;
- case 4:
- adp->va_line_width = info->vi_width/2;
- break;
- case 8:
- default: /* shouldn't happen */
- adp->va_line_width = info->vi_width;
- break;
- }
- } else {
- adp->va_line_width = info->vi_width;
- }
- bcopy(info, &adp->va_info, sizeof(adp->va_info));
-}
-
-#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE)
-/* 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 regs */
- {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;
-}
-#endif /* !VGA_NO_BIOS && !VGA_NO_MODE_CHANGE */
-
-/* probe video adapters and return the number of detected adapters */
-static int
-probe_adapters(void)
-{
- video_adapter_t *adp;
- video_info_t info;
- int i;
-
- /* do this test only once */
- if (init_done)
- return biosadapters;
- 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 data area.
- * XXX: we don't use BIOSDATA_EQUIPMENT, since it is not a dead
- * copy of RTC_EQUIPMENT. Bits 4 and 5 of ETC_EQUIPMENT are
- * zeros for EGA and VGA. However, the EGA/VGA BIOS sets
- * these bits in BIOSDATA_EQUIPMENT according to the monitor
- * type detected.
- */
-#ifndef VGA_NO_BIOS
- switch ((rtcin(RTC_EQUIPMENT) >> 4) & 3) { /* bit 4 and 5 */
- case 0:
- /* EGA/VGA */
- fill_adapter_param(readb(BIOS_PADDRTOVADDR(0x488)) & 0x0f,
- biosadapter);
- break;
- case 1:
- /* CGA 40x25 */
- /* FIXME: switch to the 80x25 mode? XXX */
- biosadapter[V_ADP_PRIMARY] = adapter_init_value[DCC_CGA40];
- biosadapter[V_ADP_SECONDARY] = adapter_init_value[DCC_MONO];
- break;
- case 2:
- /* CGA 80x25 */
- biosadapter[V_ADP_PRIMARY] = adapter_init_value[DCC_CGA80];
- biosadapter[V_ADP_SECONDARY] = adapter_init_value[DCC_MONO];
- break;
- case 3:
- /* MDA */
- biosadapter[V_ADP_PRIMARY] = adapter_init_value[DCC_MONO];
- biosadapter[V_ADP_SECONDARY] = adapter_init_value[DCC_CGA80];
- break;
- }
-#else
- /* assume EGA/VGA? XXX */
- biosadapter[V_ADP_PRIMARY] = adapter_init_value[DCC_EGA80];
- biosadapter[V_ADP_SECONDARY] = adapter_init_value[DCC_MONO];
-#endif /* VGA_NO_BIOS */
-
- biosadapters = 0;
- if (verify_adapter(&biosadapter[V_ADP_SECONDARY]) == 0) {
- ++biosadapters;
- biosadapter[V_ADP_SECONDARY].va_flags |= V_ADP_PROBED;
- biosadapter[V_ADP_SECONDARY].va_mode =
- biosadapter[V_ADP_SECONDARY].va_initial_mode =
- map_bios_mode_num(biosadapter[V_ADP_SECONDARY].va_type,
- biosadapter[V_ADP_SECONDARY].va_flags
- & V_ADP_COLOR,
- biosadapter[V_ADP_SECONDARY].va_initial_bios_mode);
- } else {
- biosadapter[V_ADP_SECONDARY].va_type = -1;
- }
- if (verify_adapter(&biosadapter[V_ADP_PRIMARY]) == 0) {
- ++biosadapters;
- biosadapter[V_ADP_PRIMARY].va_flags |= V_ADP_PROBED;
-#ifndef VGA_NO_BIOS
- biosadapter[V_ADP_PRIMARY].va_initial_bios_mode =
- readb(BIOS_PADDRTOVADDR(0x449));
-#else
- biosadapter[V_ADP_PRIMARY].va_initial_bios_mode = 3; /* XXX */
-#endif
- biosadapter[V_ADP_PRIMARY].va_mode =
- biosadapter[V_ADP_PRIMARY].va_initial_mode =
- map_bios_mode_num(biosadapter[V_ADP_PRIMARY].va_type,
- biosadapter[V_ADP_PRIMARY].va_flags & V_ADP_COLOR,
- biosadapter[V_ADP_PRIMARY].va_initial_bios_mode);
- } else {
- biosadapter[V_ADP_PRIMARY] = biosadapter[V_ADP_SECONDARY];
- biosadapter[V_ADP_SECONDARY].va_type = -1;
- }
- if (biosadapters == 0)
- return biosadapters;
- biosadapter[V_ADP_PRIMARY].va_unit = V_ADP_PRIMARY;
- biosadapter[V_ADP_SECONDARY].va_unit = V_ADP_SECONDARY;
-
-#if 0 /* we don't need these... */
- fb_init_struct(&biosadapter[V_ADP_PRIMARY], ...);
- fb_init_struct(&biosadapter[V_ADP_SECONDARY], ...);
-#endif
-
-#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 (biosadapters > 1) {
- if (!((biosadapter[0].va_flags ^ biosadapter[1].va_flags)
- & V_ADP_COLOR))
- /* we have two mono or color adapters!! */
- return (biosadapters = 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 vga_save_state() for VGA.
- */
- outb(biosadapter[V_ADP_PRIMARY].va_crtc_addr, 12);
- outb(biosadapter[V_ADP_PRIMARY].va_crtc_addr + 1, 0);
- outb(biosadapter[V_ADP_PRIMARY].va_crtc_addr, 13);
- outb(biosadapter[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 ((biosadapter[V_ADP_PRIMARY].va_type == KD_EGA) ||
- (biosadapter[V_ADP_PRIMARY].va_type == KD_VGA)) {
- adp = &biosadapter[V_ADP_PRIMARY];
- } else if ((biosadapter[V_ADP_SECONDARY].va_type == KD_EGA) ||
- (biosadapter[V_ADP_SECONDARY].va_type == KD_VGA)) {
- adp = &biosadapter[V_ADP_SECONDARY];
- } else {
- adp = NULL;
- }
- bzero(mode_map, sizeof(mode_map));
- if (adp != NULL) {
- if (adp->va_type == KD_VGA) {
- vga_save_state(adp, &adpstate, sizeof(adpstate));
-#if defined(VGA_NO_BIOS) || defined(VGA_NO_MODE_CHANGE)
- mode_map[adp->va_initial_mode] = adpstate.regs;
- rows_offset = 1;
-#else /* VGA_NO_BIOS || VGA_NO_MODE_CHANGE */
- if (video_mode_ptr == NULL) {
- mode_map[adp->va_initial_mode] = adpstate.regs;
- rows_offset = 1;
- } else {
- /* discard the table if we are not familiar with it... */
- u_char *mp;
- 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[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[adp->va_initial_mode] = adpstate.regs;
- rows_offset = 1;
- break;
- }
- }
-#endif /* VGA_NO_BIOS || VGA_NO_MODE_CHANGE */
-
-#ifndef VGA_NO_MODE_CHANGE
- adp->va_flags |= V_ADP_MODECHANGE;
-#endif
-#ifndef VGA_NO_FONT_LOADING
- adp->va_flags |= V_ADP_FONT;
-#endif
- } else if (adp->va_type == KD_EGA) {
-#if defined(VGA_NO_BIOS) || defined(VGA_NO_MODE_CHANGE)
- rows_offset = 1;
-#else /* VGA_NO_BIOS || VGA_NO_MODE_CHANGE */
- if (video_mode_ptr == NULL) {
- rows_offset = 1;
- } else {
- u_char *mp;
- 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;
-#ifndef VGA_NO_FONT_LOADING
- adp->va_flags |= V_ADP_FONT;
-#endif
- rows_offset = 1;
- } else {
- /*
- * This is serious. We will not be able to switch video
- * modes at all...
- */
- video_mode_ptr = NULL;
- bzero(mode_map, sizeof(mode_map));
- rows_offset = 1;
- }
- }
-#endif /* VGA_NO_BIOS || VGA_NO_MODE_CHANGE */
- }
- }
-
- /* remove conflicting modes if we have more than one adapter */
- if (biosadapters > 1) {
- for (i = 0; i < biosadapters; ++i) {
- if (!(biosadapter[i].va_flags & V_ADP_MODECHANGE))
- continue;
- clear_mode_map(&biosadapter[i], mode_map, M_VGA_CG320 + 1,
- (biosadapter[i].va_flags & V_ADP_COLOR) ?
- V_INFO_COLOR : 0);
- if ((biosadapter[i].va_type == KD_VGA)
- || (biosadapter[i].va_type == KD_EGA)) {
- biosadapter[i].va_io_base =
- (biosadapter[i].va_flags & V_ADP_COLOR) ?
- IO_VGA : IO_MDA;
- biosadapter[i].va_io_size = 32;
- }
- }
- }
-
- /* buffer address */
- vga_get_info(&biosadapter[V_ADP_PRIMARY],
- biosadapter[V_ADP_PRIMARY].va_initial_mode, &info);
- update_adapter_info(&biosadapter[V_ADP_PRIMARY], &info);
-
- if (biosadapters > 1) {
- vga_get_info(&biosadapter[V_ADP_SECONDARY],
- biosadapter[V_ADP_SECONDARY].va_initial_mode, &info);
- update_adapter_info(&biosadapter[V_ADP_SECONDARY], &info);
- }
-
- /*
- * 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 biosadapters;
-}
-
-/* entry points */
-
-static int
-vga_nop(void)
-{
- return 0;
-}
-
-static int
-vga_probe(int unit, video_adapter_t **adpp, void *arg, int flags)
-{
- probe_adapters();
- if (unit >= biosadapters)
- return ENXIO;
-
- *adpp = &biosadapter[unit];
-
- return 0;
-}
-
-static int
-vga_init(int unit, video_adapter_t *adp, int flags)
-{
- if ((unit >= biosadapters) || (adp == NULL) || !probe_done(adp))
- return ENXIO;
-
- if (!init_done(adp)) {
- /* nothing to do really... */
- adp->va_flags |= V_ADP_INITIALIZED;
- }
-
- if (!config_done(adp)) {
- if (vid_register(adp) < 0)
- return ENXIO;
- adp->va_flags |= V_ADP_REGISTERED;
- }
- if (vga_sub_configure != NULL)
- (*vga_sub_configure)(0);
-
- return 0;
-}
-
-/*
- * get_info():
- * Return the video_info structure of the requested video mode.
- *
- * all adapters
- */
-static int
-vga_get_info(video_adapter_t *adp, int mode, video_info_t *info)
-{
- int i;
-
- if (!init_done)
- return 1;
-
- mode = map_gen_mode_num(adp->va_type, adp->va_flags & V_ADP_COLOR, mode);
-#ifndef VGA_NO_MODE_CHANGE
- if (adp->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
-#endif /* VGA_NO_MODE_CHANGE */
- {
- /*
- * 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 != adp->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;
-}
-
-/*
- * query_mode():
- * Find a video mode matching the requested parameters.
- * Fields filled with 0 are considered "don't care" fields and
- * match any modes.
- *
- * all adapters
- */
-static int
-vga_query_mode(video_adapter_t *adp, video_info_t *info)
-{
- video_info_t buf;
- int i;
-
- if (!init_done)
- 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 (vga_get_info(adp, bios_vmode[i].vi_mode, &buf))
- continue;
- return bios_vmode[i].vi_mode;
- }
- return -1;
-}
-
-/*
- * set_mode():
- * Change the video mode.
- *
- * EGA/VGA
- */
-static int
-vga_set_mode(video_adapter_t *adp, int mode)
-{
-#ifndef VGA_NO_MODE_CHANGE
- video_info_t info;
- adp_state_t params;
-
- prologue(adp, V_ADP_MODECHANGE, 1);
-
- mode = map_gen_mode_num(adp->va_type,
- adp->va_flags & V_ADP_COLOR, mode);
- if (vga_get_info(adp, 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:
- vga_load_state(adp, &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:
- vga_load_state(adp, &params);
- break;
-
- default:
- return 1;
- }
-
- adp->va_mode = mode;
- update_adapter_info(adp, &info);
-
- /* move hardware cursor out of the way */
- (*vidsw[adp->va_index]->set_hw_cursor)(adp, -1, -1);
-
- return 0;
-#else /* VGA_NO_MODE_CHANGE */
- return 1;
-#endif /* VGA_NO_MODE_CHANGE */
-}
-
-#ifndef VGA_NO_FONT_LOADING
-
-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 VGA_SLOW_IOACCESS
-#ifdef VGA_ALT_SEQACCESS
- outb(TSIDX, 0x00); outb(TSREG, 0x01);
-#endif
- outb(TSIDX, 0x02); outb(TSREG, 0x04);
- outb(TSIDX, 0x04); outb(TSREG, 0x07);
-#ifdef VGA_ALT_SEQACCESS
- 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 /* VGA_SLOW_IOACCESS */
-#ifdef VGA_ALT_SEQACCESS
- outw(TSIDX, 0x0100);
-#endif
- outw(TSIDX, 0x0402);
- outw(TSIDX, 0x0704);
-#ifdef VGA_ALT_SEQACCESS
- outw(TSIDX, 0x0300);
-#endif
- outw(GDCIDX, 0x0204);
- outw(GDCIDX, 0x0005);
- outw(GDCIDX, 0x0406); /* addr = a0000, 64kb */
-#endif /* VGA_SLOW_IOACCESS */
-
- 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 VGA_SLOW_IOACCESS
-#ifdef VGA_ALT_SEQACCESS
- outb(TSIDX, 0x00); outb(TSREG, 0x01);
-#endif
- outb(TSIDX, 0x02); outb(TSREG, buf[0]);
- outb(TSIDX, 0x04); outb(TSREG, buf[1]);
-#ifdef VGA_ALT_SEQACCESS
- 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_CRTC) {
- outb(GDCIDX, 0x06); outb(GDCREG,(buf[4] & 0x03) | 0x08);
- } else {
- outb(GDCIDX, 0x06); outb(GDCREG,(buf[4] & 0x03) | 0x0c);
- }
-#else /* VGA_SLOW_IOACCESS */
-#ifdef VGA_ALT_SEQACCESS
- outw(TSIDX, 0x0100);
-#endif
- outw(TSIDX, 0x0002 | (buf[0] << 8));
- outw(TSIDX, 0x0004 | (buf[1] << 8));
-#ifdef VGA_ALT_SEQACCESS
- outw(TSIDX, 0x0300);
-#endif
- outw(GDCIDX, 0x0004 | (buf[2] << 8));
- outw(GDCIDX, 0x0005 | (buf[3] << 8));
- if (adp->va_crtc_addr == MONO_CRTC)
- outw(GDCIDX, 0x0006 | (((buf[4] & 0x03) | 0x08)<<8));
- else
- outw(GDCIDX, 0x0006 | (((buf[4] & 0x03) | 0x0c)<<8));
-#endif /* VGA_SLOW_IOACCESS */
-
- splx(s);
-}
-
-#endif /* VGA_NO_FONT_LOADING */
-
-/*
- * save_font():
- * Read the font data in the requested font page from the video adapter.
- *
- * EGA/VGA
- */
-static int
-vga_save_font(video_adapter_t *adp, int page, int fontsize, u_char *data,
- int ch, int count)
-{
-#ifndef VGA_NO_FONT_LOADING
- u_char buf[PARAM_BUFSIZE];
- u_int32_t segment;
- int c;
-#ifdef VGA_ALT_SEQACCESS
- int s;
- u_char val = 0;
-#endif
-
- prologue(adp, 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 = FONT_BUF + 0x4000*page;
- if (page > 3)
- segment -= 0xe000;
-
-#ifdef VGA_ALT_SEQACCESS
- if (adp->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);
- }
-#endif
-
- set_font_mode(adp, buf);
- if (fontsize == 32) {
- bcopy_fromio(segment + ch*32, data, fontsize*count);
- } else {
- for (c = ch; count > 0; ++c, --count) {
- bcopy_fromio(segment + c*32, data, fontsize);
- data += fontsize;
- }
- }
- set_normal_mode(adp, buf);
-
-#ifdef VGA_ALT_SEQACCESS
- if (adp->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);
- }
-#endif
-
- return 0;
-#else /* VGA_NO_FONT_LOADING */
- return 1;
-#endif /* VGA_NO_FONT_LOADING */
-}
-
-/*
- * load_font():
- * Set the font data in the requested font page.
- * NOTE: it appears that some recent video adapters do not support
- * the font page other than 0... XXX
- *
- * EGA/VGA
- */
-static int
-vga_load_font(video_adapter_t *adp, int page, int fontsize, u_char *data,
- int ch, int count)
-{
-#ifndef VGA_NO_FONT_LOADING
- u_char buf[PARAM_BUFSIZE];
- u_int32_t segment;
- int c;
-#ifdef VGA_ALT_SEQACCESS
- int s;
- u_char val = 0;
-#endif
-
- prologue(adp, 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 = FONT_BUF + 0x4000*page;
- if (page > 3)
- segment -= 0xe000;
-
-#ifdef VGA_ALT_SEQACCESS
- if (adp->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);
- }
-#endif
-
- set_font_mode(adp, buf);
- if (fontsize == 32) {
- bcopy_toio(data, segment + ch*32, fontsize*count);
- } else {
- for (c = ch; count > 0; ++c, --count) {
- bcopy_toio(data, segment + c*32, fontsize);
- data += fontsize;
- }
- }
- set_normal_mode(adp, buf);
-
-#ifdef VGA_ALT_SEQACCESS
- if (adp->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);
- }
-#endif
-
- return 0;
-#else /* VGA_NO_FONT_LOADING */
- return 1;
-#endif /* VGA_NO_FONT_LOADING */
-}
-
-/*
- * show_font():
- * Activate the requested font page.
- * NOTE: it appears that some recent video adapters do not support
- * the font page other than 0... XXX
- *
- * EGA/VGA
- */
-static int
-vga_show_font(video_adapter_t *adp, int page)
-{
-#ifndef VGA_NO_FONT_LOADING
- static u_char cg[] = { 0x00, 0x05, 0x0a, 0x0f, 0x30, 0x35, 0x3a, 0x3f };
- int s;
-
- prologue(adp, V_ADP_FONT, 1);
- if (page < 0 || page >= 8)
- return 1;
-
- s = splhigh();
- outb(TSIDX, 0x03); outb(TSREG, cg[page]);
- splx(s);
-
- return 0;
-#else /* VGA_NO_FONT_LOADING */
- return 1;
-#endif /* VGA_NO_FONT_LOADING */
-}
-
-/*
- * save_palette():
- * Read DAC values. The values have expressed in 8 bits.
- *
- * VGA
- */
-static int
-vga_save_palette(video_adapter_t *adp, u_char *palette)
-{
- int i;
-
- prologue(adp, 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(adp->va_crtc_addr + 6); /* reset flip/flop */
- return 0;
+ return 0;
}
-/*
- * load_palette():
- * Set DAC values.
- *
- * VGA
- */
-static int
-vga_load_palette(video_adapter_t *adp, u_char *palette)
-{
- int i;
-
- prologue(adp, 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(adp->va_crtc_addr + 6); /* reset flip/flop */
- outb(ATC, 0x20); /* enable palette */
- return 0;
-}
+#ifdef FB_INSTALL_CDEV
-/*
- * set_border():
- * Change the border color.
- *
- * CGA/EGA/VGA
- */
static int
-vga_set_border(video_adapter_t *adp, int color)
+isavga_open(dev_t dev, int flag, int mode, struct proc *p)
{
- prologue(adp, V_ADP_BORDER, 1);
-
- switch (adp->va_type) {
- case KD_EGA:
- case KD_VGA:
- inb(adp->va_crtc_addr + 6); /* reset flip-flop */
- outb(ATC, 0x31); outb(ATC, color & 0xff);
- break;
- case KD_CGA:
- outb(adp->va_crtc_addr + 5, color & 0x0f); /* color select register */
- break;
- case KD_MONO:
- case KD_HERCULES:
- default:
- break;
- }
- return 0;
+ return vga_open(dev, VGA_SOFTC(VGA_UNIT(dev)), flag, mode, p);
}
-/*
- * save_state():
- * Read video register values.
- * NOTE: this function only reads the standard EGA/VGA registers.
- * any extra/extended registers of SVGA adapters are not saved.
- *
- * VGA
- */
static int
-vga_save_state(video_adapter_t *adp, void *p, size_t size)
+isavga_close(dev_t dev, int flag, int mode, struct proc *p)
{
- video_info_t info;
- u_char *buf;
- int crtc_addr;
- int i, j;
- int s;
-
- if (size == 0) {
- /* return the required buffer size */
- prologue(adp, V_ADP_STATESAVE, 0);
- return sizeof(adp_state_t);
- } else {
- prologue(adp, 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 = adp->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 (vga_get_info(adp, adp->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("vga%d: %s: failed to obtain mode info. (vga_save_state())\n",
- adp->va_unit, adp->va_name);
- }
-#else
- buf[0] = readb(BIOS_PADDRTOVADDR(0x44a)); /* COLS */
- buf[1] = readb(BIOS_PADDRTOVADDR(0x484)); /* ROWS */
- buf[2] = readb(BIOS_PADDRTOVADDR(0x485)); /* POINTS */
- buf[3] = readb(BIOS_PADDRTOVADDR(0x44c));
- buf[4] = readb(BIOS_PADDRTOVADDR(0x44d));
-#endif
-
- return 0;
+ return vga_close(dev, VGA_SOFTC(VGA_UNIT(dev)), flag, mode, p);
}
-/*
- * load_state():
- * Set video registers at once.
- * NOTE: this function only updates the standard EGA/VGA registers.
- * any extra/extended registers of SVGA adapters are not changed.
- *
- * EGA/VGA
- */
static int
-vga_load_state(video_adapter_t *adp, void *p)
+isavga_read(dev_t dev, struct uio *uio, int flag)
{
- u_char *buf;
- int crtc_addr;
- int s;
- int i;
-
- prologue(adp, V_ADP_STATELOAD, 1);
- if (((adp_state_t *)p)->sig != V_STATE_SIG)
- return 1;
-
- buf = ((adp_state_t *)p)->regs;
- crtc_addr = adp->va_crtc_addr;
-
- s = splhigh();
-
- outb(TSIDX, 0x00); outb(TSREG, 0x01); /* stop sequencer */
- for (i = 0; i < 4; ++i) { /* program sequencer */
- outb(TSIDX, i + 1);
- outb(TSREG, buf[i + 5]);
- }
- outb(MISC, buf[9]); /* set dot-clock */
- outb(TSIDX, 0x00); outb(TSREG, 0x03); /* start sequencer */
- outb(crtc_addr, 0x11);
- outb(crtc_addr + 1, inb(crtc_addr + 1) & 0x7F);
- for (i = 0; i < 25; ++i) { /* program crtc */
- outb(crtc_addr, i);
- outb(crtc_addr + 1, buf[i + 10]);
- }
- inb(crtc_addr+6); /* reset flip-flop */
- for (i = 0; i < 20; ++i) { /* program attribute ctrl */
- outb(ATC, i);
- outb(ATC, buf[i + 35]);
- }
- for (i = 0; i < 9; ++i) { /* program graph data ctrl */
- outb(GDCIDX, i);
- outb(GDCREG, buf[i + 55]);
- }
- inb(crtc_addr + 6); /* reset flip-flop */
- outb(ATC, 0x20); /* enable palette */
-
-#if notyet /* a temporary workaround for kernel panic, XXX */
-#ifndef VGA_NO_BIOS
- if (adp->va_unit == V_ADP_PRIMARY) {
- writeb(BIOS_PADDRTOVADDR(0x44a), buf[0]); /* COLS */
- writeb(BIOS_PADDRTOVADDR(0x484), buf[1] + rows_offset - 1); /* ROWS */
- writeb(BIOS_PADDRTOVADDR(0x485), buf[2]); /* POINTS */
-#if 0
- writeb(BIOS_PADDRTOVADDR(0x44c), buf[3]);
- writeb(BIOS_PADDRTOVADDR(0x44d), buf[4]);
-#endif
- }
-#endif /* VGA_NO_BIOS */
-#endif /* notyet */
-
- splx(s);
- return 0;
+ return vga_read(dev, VGA_SOFTC(VGA_UNIT(dev)), uio, flag);
}
-/*
- * set_origin():
- * Change the origin (window mapping) of the banked frame buffer.
- */
static int
-vga_set_origin(video_adapter_t *adp, off_t offset)
+isavga_write(dev_t dev, struct uio *uio, int flag)
{
- /*
- * The standard video modes do not require window mapping;
- * always return error.
- */
- return 1;
+ return vga_write(dev, VGA_SOFTC(VGA_UNIT(dev)), uio, flag);
}
-/*
- * read_hw_cursor():
- * Read the position of the hardware text cursor.
- *
- * all adapters
- */
static int
-vga_read_hw_cursor(video_adapter_t *adp, int *col, int *row)
+isavga_ioctl(dev_t dev, u_long cmd, caddr_t arg, int flag, struct proc *p)
{
- u_int16_t off;
- int s;
-
- if (!init_done)
- return 1;
-
- if (adp->va_info.vi_flags & V_INFO_GRAPHICS)
- return 1;
-
- s = spltty();
- outb(adp->va_crtc_addr, 14);
- off = inb(adp->va_crtc_addr + 1);
- outb(adp->va_crtc_addr, 15);
- off = (off << 8) | inb(adp->va_crtc_addr + 1);
- splx(s);
-
- *row = off / adp->va_info.vi_width;
- *col = off % adp->va_info.vi_width;
-
- return 0;
+ return vga_ioctl(dev, VGA_SOFTC(VGA_UNIT(dev)), cmd, arg, flag, p);
}
-/*
- * set_hw_cursor():
- * Move the hardware text cursor. If col and row are both -1,
- * the cursor won't be shown.
- *
- * all adapters
- */
static int
-vga_set_hw_cursor(video_adapter_t *adp, int col, int row)
+isavga_mmap(dev_t dev, vm_offset_t offset, int prot)
{
- u_int16_t off;
- int s;
-
- if (!init_done)
- return 1;
-
- if ((col == -1) && (row == -1)) {
- off = -1;
- } else {
- if (adp->va_info.vi_flags & V_INFO_GRAPHICS)
- return 1;
- off = row*adp->va_info.vi_width + col;
- }
-
- s = spltty();
- outb(adp->va_crtc_addr, 14);
- outb(adp->va_crtc_addr + 1, off >> 8);
- outb(adp->va_crtc_addr, 15);
- outb(adp->va_crtc_addr + 1, off & 0x00ff);
- splx(s);
-
- return 0;
+ return vga_mmap(dev, VGA_SOFTC(VGA_UNIT(dev)), offset, prot);
}
-/*
- * set_hw_cursor_shape():
- * Change the shape of the hardware text cursor. If the height is
- * zero or negative, the cursor won't be shown.
- *
- * all adapters
- */
-static int
-vga_set_hw_cursor_shape(video_adapter_t *adp, int base, int height,
- int celsize, int blink)
-{
- int s;
-
- if (!init_done)
- return 1;
-
- s = spltty();
- switch (adp->va_type) {
- case KD_VGA:
- case KD_CGA:
- case KD_MONO:
- case KD_HERCULES:
- default:
- if (height <= 0) {
- /* make the cursor invisible */
- outb(adp->va_crtc_addr, 10);
- outb(adp->va_crtc_addr + 1, 32);
- outb(adp->va_crtc_addr, 11);
- outb(adp->va_crtc_addr + 1, 0);
- } else {
- outb(adp->va_crtc_addr, 10);
- outb(adp->va_crtc_addr + 1, celsize - base - height);
- outb(adp->va_crtc_addr, 11);
- outb(adp->va_crtc_addr + 1, celsize - base - 1);
- }
- break;
- case KD_EGA:
- if (height <= 0) {
- /* make the cursor invisible */
- outb(adp->va_crtc_addr, 10);
- outb(adp->va_crtc_addr + 1, celsize);
- outb(adp->va_crtc_addr, 11);
- outb(adp->va_crtc_addr + 1, 0);
- } else {
- outb(adp->va_crtc_addr, 10);
- outb(adp->va_crtc_addr + 1, celsize - base - height);
- outb(adp->va_crtc_addr, 11);
- outb(adp->va_crtc_addr + 1, celsize - base);
- }
- break;
- }
- splx(s);
-
- return 0;
-}
-
-/*
- * mmap():
- * Mmap frame buffer.
- *
- * all adapters
- */
-static int
-vga_mmap(video_adapter_t *adp, vm_offset_t offset)
-{
- if (offset > 0x20000 - PAGE_SIZE)
- return -1;
-#ifdef __i386__
- return i386_btop((VIDEO_BUF_BASE + offset));
-#endif
-#ifdef __alpha__
- return alpha_btop((VIDEO_BUF_BASE + offset));
-#endif
-}
-
-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");
- }
-}
-
-/*
- * diag():
- * Print some information about the video adapter and video modes,
- * with requested level of details.
- *
- * all adapters
- */
-static int
-vga_diag(video_adapter_t *adp, int level)
-{
-#if FB_DEBUG > 1
- video_info_t info;
-#endif
- u_char *mp;
-
- if (!init_done)
- return 1;
-
-#if FB_DEBUG > 1
-#ifndef VGA_NO_BIOS
- printf("vga: RTC equip. code:0x%02x, DCC code:0x%02x\n",
- rtcin(RTC_EQUIPMENT), readb(BIOS_PADDRTOVADDR(0x488)));
- printf("vga: CRTC:0x%x, video option:0x%02x, ",
- readw(BIOS_PADDRTOVADDR(0x463)),
- readb(BIOS_PADDRTOVADDR(0x487)));
- printf("rows:%d, cols:%d, font height:%d\n",
- readb(BIOS_PADDRTOVADDR(0x44a)),
- readb(BIOS_PADDRTOVADDR(0x484)) + 1,
- readb(BIOS_PADDRTOVADDR(0x485)));
-#endif /* VGA_NO_BIOS */
-#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE)
- printf("vga: param table EGA/VGA:%p", video_mode_ptr);
- printf(", CGA/MDA:%p\n", video_mode_ptr2);
-#endif
- printf("vga: rows_offset:%d\n", rows_offset);
-#endif /* FB_DEBUG > 1 */
-
- fb_dump_adp_info(DRIVER_NAME, adp, level);
-
-#if FB_DEBUG > 1
- if (adp->va_flags & V_ADP_MODECHANGE) {
- 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;
- fb_dump_mode_info(DRIVER_NAME, adp, &bios_vmode[i], level);
- }
- } else {
- vga_get_info(adp, adp->va_initial_mode, &info); /* shouldn't fail */
- fb_dump_mode_info(DRIVER_NAME, adp, &info, level);
- }
-#endif /* FB_DEBUG > 1 */
-
- if ((adp->va_type != KD_EGA) && (adp->va_type != KD_VGA))
- return 0;
-#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE)
- if (video_mode_ptr == NULL)
- printf("vga%d: %s: WARNING: video mode switching is not "
- "fully supported on this adapter\n",
- adp->va_unit, adp->va_name);
-#endif
- if (level <= 0)
- return 0;
-
- if (adp->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", adp->va_initial_mode);
- dump_buffer(adpstate2.regs, sizeof(adpstate2.regs));
- }
-
- mp = get_mode_param(adp->va_initial_mode);
- if (mp == NULL) /* this shouldn't be happening */
- return 0;
- printf("EGA/VGA parameters to be used for mode %d\n", adp->va_initial_mode);
- dump_buffer(mp, V_MODE_PARAM_SIZE);
-
- return 0;
-}
+#endif /* FB_INSTALL_CDEV */
#endif /* NVGA > 0 */
diff --git a/sys/kern/tty_cons.c b/sys/kern/tty_cons.c
index acc8503..cee6564 100644
--- a/sys/kern/tty_cons.c
+++ b/sys/kern/tty_cons.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* from: @(#)cons.c 7.2 (Berkeley) 5/9/91
- * $Id: cons.c,v 1.66 1999/05/30 16:52:03 phk Exp $
+ * $Id: cons.c,v 1.67 1999/05/31 11:25:41 phk Exp $
*/
#include "opt_devfs.h"
@@ -109,19 +109,19 @@ static struct tty *cn_tp; /* physical console tty struct */
static void *cn_devfs_token; /* represents the devfs entry */
#endif /* DEVFS */
-CONS_DRIVER(cons, NULL, NULL, NULL, NULL, NULL);
+CONS_DRIVER(cons, NULL, NULL, NULL, NULL, NULL, NULL);
void
cninit()
{
struct consdev *best_cp, *cp;
- struct consdev **list;
+ const struct consdev **list;
/*
* Find the first console with the highest priority.
*/
best_cp = NULL;
- list = (struct consdev **)cons_set.ls_items;
+ list = (const struct consdev **)cons_set.ls_items;
while ((cp = *list++) != NULL) {
if (cp->cn_probe == NULL)
continue;
@@ -147,6 +147,8 @@ cninit()
* If no console, give up.
*/
if (best_cp == NULL) {
+ if (cn_tab != NULL && cn_tab->cn_term != NULL)
+ (*cn_tab->cn_term)(cn_tab);
cn_tab = best_cp;
return;
}
@@ -154,10 +156,13 @@ cninit()
/*
* Initialize console, then attach to it. This ordering allows
* debugging using the previous console, if any.
- * XXX if there was a previous console, then its driver should
- * be informed when we forget about it.
*/
(*best_cp->cn_init)(best_cp);
+ if (cn_tab != NULL && cn_tab != best_cp) {
+ /* Turn off the previous console. */
+ if (cn_tab->cn_term != NULL)
+ (*cn_tab->cn_term)(cn_tab);
+ }
cn_tab = best_cp;
}
diff --git a/sys/modules/splash/bmp/splash_bmp.c b/sys/modules/splash/bmp/splash_bmp.c
index 44ac914..6de5a28 100644
--- a/sys/modules/splash/bmp/splash_bmp.c
+++ b/sys/modules/splash/bmp/splash_bmp.c
@@ -24,15 +24,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: splash_bmp.c,v 1.7 1999/03/29 15:13:53 yokota Exp $
+ * $Id: splash_bmp.c,v 1.8 1999/06/16 14:04:45 yokota Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/linker.h>
-
-#include <machine/console.h>
+#include <sys/fbio.h>
#include <dev/fb/fbreg.h>
#include <dev/fb/splashreg.h>
diff --git a/sys/modules/splash/pcx/splash_pcx.c b/sys/modules/splash/pcx/splash_pcx.c
index 3066bb3..5423295 100644
--- a/sys/modules/splash/pcx/splash_pcx.c
+++ b/sys/modules/splash/pcx/splash_pcx.c
@@ -27,15 +27,14 @@
* (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$
+ * $Id: splash_pcx.c,v 1.1 1999/04/12 13:39:11 des Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/linker.h>
-
-#include <machine/console.h>
+#include <sys/fbio.h>
#include <dev/fb/fbreg.h>
#include <dev/fb/splashreg.h>
diff --git a/sys/modules/syscons/blank/blank_saver.c b/sys/modules/syscons/blank/blank_saver.c
index 89dd199..2979c0d 100644
--- a/sys/modules/syscons/blank/blank_saver.c
+++ b/sys/modules/syscons/blank/blank_saver.c
@@ -25,82 +25,35 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: blank_saver.c,v 1.14 1998/11/04 03:49:38 peter Exp $
+ * $Id: blank_saver.c,v 1.15 1999/01/11 03:18:44 yokota Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/module.h>
+#include <sys/consio.h>
+#include <sys/fbio.h>
-#include <dev/fb/vgareg.h>
-
-#include <i386/isa/isa.h>
-
-#include <saver.h>
+#include <dev/fb/fbreg.h>
+#include <dev/fb/splashreg.h>
+#include <dev/syscons/syscons.h>
static int
blank_saver(video_adapter_t *adp, int blank)
{
- u_char val;
- if (blank) {
- switch (adp->va_type) {
- case KD_VGA:
- outb(TSIDX, 0x01); val = inb(TSREG);
- outb(TSIDX, 0x01); outb(TSREG, val | 0x20);
- break;
- case KD_EGA:
- /* not yet done XXX */
- break;
- case KD_CGA:
- outb(adp->va_crtc_addr + 4, 0x25);
- break;
- case KD_MONO:
- case KD_HERCULES:
- outb(adp->va_crtc_addr + 4, 0x21);
- break;
- default:
- break;
- }
- }
- else {
- switch (adp->va_type) {
- case KD_VGA:
- outb(TSIDX, 0x01); val = inb(TSREG);
- outb(TSIDX, 0x01); outb(TSREG, val & 0xDF);
- break;
- case KD_EGA:
- /* not yet done XXX */
- break;
- case KD_CGA:
- outb(adp->va_crtc_addr + 4, 0x2d);
- break;
- case KD_MONO:
- case KD_HERCULES:
- outb(adp->va_crtc_addr + 4, 0x29);
- break;
- default:
- break;
- }
- }
+ (*vidsw[adp->va_index]->blank_display)(adp,
+ (blank) ? V_DISPLAY_BLANK
+ : V_DISPLAY_ON);
return 0;
}
static int
blank_init(video_adapter_t *adp)
{
- switch (adp->va_type) {
- case KD_MONO:
- case KD_HERCULES:
- case KD_CGA:
- case KD_VGA:
- break;
- case KD_EGA:
- /* EGA is yet to be supported */
- default:
- return ENODEV;
- }
- return 0;
+ if ((*vidsw[adp->va_index]->blank_display)(adp, V_DISPLAY_ON) == 0)
+ return 0;
+ return ENODEV;
}
static int
diff --git a/sys/modules/syscons/daemon/daemon_saver.c b/sys/modules/syscons/daemon/daemon_saver.c
index 423e6c7..ebedfaa 100644
--- a/sys/modules/syscons/daemon/daemon_saver.c
+++ b/sys/modules/syscons/daemon/daemon_saver.c
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: daemon_saver.c,v 1.14 1999/01/17 14:25:08 yokota Exp $
+ * $Id: daemon_saver.c,v 1.15 1999/02/05 12:40:15 des Exp $
*/
#include <sys/param.h>
@@ -34,21 +34,20 @@
#include <sys/malloc.h>
#include <sys/kernel.h>
#include <sys/sysctl.h>
+#include <sys/consio.h>
+#include <sys/fbio.h>
-#include <machine/md_var.h>
#include <machine/pc/display.h>
-#include <saver.h>
-
-#define CONSOLE_VECT(x, y) \
- (window + (y)*cur_console->xsize + (x))
+#include <dev/fb/fbreg.h>
+#include <dev/fb/splashreg.h>
+#include <dev/syscons/syscons.h>
#define DAEMON_MAX_WIDTH 32
#define DAEMON_MAX_HEIGHT 19
static char *message;
static int messagelen;
-static u_short *window;
static int blanked;
/* Who is the author of this ASCII pic? */
@@ -119,20 +118,23 @@ xflip_symbol(char symbol)
}
static void
-clear_daemon(int xpos, int ypos, int dxdir, int xoff, int yoff,
+clear_daemon(sc_softc_t *sc, int xpos, int ypos, int dxdir, int xoff, int yoff,
int xlen, int ylen)
{
int y;
if (xlen <= 0)
return;
- for (y = yoff; y < ylen; y++)
- fillw(((FG_LIGHTGREY|BG_BLACK) << 8) | scr_map[0x20],
- CONSOLE_VECT(xpos + xoff, ypos + y), xlen - xoff);
+ for (y = yoff; y < ylen; y++) {
+ sc_vtb_erase(&sc->cur_scp->scr,
+ (ypos + y)*sc->cur_scp->xsize + xpos + xoff,
+ xlen - xoff,
+ sc->scr_map[0x20], (FG_LIGHTGREY | BG_BLACK) << 8);
+ }
}
static void
-draw_daemon(int xpos, int ypos, int dxdir, int xoff, int yoff,
+draw_daemon(sc_softc_t *sc, int xpos, int ypos, int dxdir, int xoff, int yoff,
int xlen, int ylen)
{
int x, y;
@@ -148,41 +150,60 @@ draw_daemon(int xpos, int ypos, int dxdir, int xoff, int yoff,
continue;
for (x = xoff; (x < xlen) && (daemon_pic[y][px] != '\0'); x++, px++) {
switch (daemon_attr[y][px]) {
+#ifndef PC98
case 'R': attr = (FG_LIGHTRED|BG_BLACK)<<8; break;
case 'Y': attr = (FG_YELLOW|BG_BLACK)<<8; break;
case 'B': attr = (FG_LIGHTBLUE|BG_BLACK)<<8; break;
case 'W': attr = (FG_LIGHTGREY|BG_BLACK)<<8; break;
case 'C': attr = (FG_CYAN|BG_BLACK)<<8; break;
default: attr = (FG_WHITE|BG_BLACK)<<8; break;
+#else /* PC98 */
+ case 'R': attr = (FG_RED|BG_BLACK)<<8; break;
+ case 'Y': attr = (FG_BROWN|BG_BLACK)<<8; break;
+ case 'B': attr = (FG_BLUE|BG_BLACK)<<8; break;
+ case 'W': attr = (FG_LIGHTGREY|BG_BLACK)<<8; break;
+ case 'C': attr = (FG_CYAN|BG_BLACK)<<8; break;
+ default: attr = (FG_LIGHTGREY|BG_BLACK)<<8; break;
+#endif /* PC98 */
}
if (dxdir < 0) { /* Moving left */
- *CONSOLE_VECT(xpos + x, ypos + y) =
- scr_map[daemon_pic[y][px]]|attr;
+ sc_vtb_putc(&sc->cur_scp->scr,
+ (ypos + y)*sc->cur_scp->xsize
+ + xpos + x,
+ sc->scr_map[daemon_pic[y][px]],
+ attr);
} else { /* Moving right */
- *CONSOLE_VECT(xpos + DAEMON_MAX_WIDTH - px - 1, ypos + y) =
- scr_map[xflip_symbol(daemon_pic[y][px])]|attr;
+ sc_vtb_putc(&sc->cur_scp->scr,
+ (ypos + y)*sc->cur_scp->xsize
+ + xpos + DAEMON_MAX_WIDTH
+ - px - 1,
+ sc->scr_map[xflip_symbol(daemon_pic[y][px])],
+ attr);
}
}
}
}
static void
-clear_string(int xpos, int ypos, int xoff, char *s, int len)
+clear_string(sc_softc_t *sc, int xpos, int ypos, int xoff, char *s, int len)
{
if (len <= 0)
return;
- fillw(((FG_LIGHTGREY|BG_BLACK) << 8) | scr_map[0x20],
- CONSOLE_VECT(xpos + xoff, ypos), len - xoff);
+ sc_vtb_erase(&sc->cur_scp->scr,
+ ypos*sc->cur_scp->xsize + xpos + xoff, len - xoff,
+ sc->scr_map[0x20], (FG_LIGHTGREY | BG_BLACK) << 8);
}
static void
-draw_string(int xpos, int ypos, int xoff, char *s, int len)
+draw_string(sc_softc_t *sc, int xpos, int ypos, int xoff, char *s, int len)
{
int x;
- for (x = xoff; x < len; x++)
- *CONSOLE_VECT(xpos + x, ypos) =
- scr_map[s[x]]|(FG_LIGHTGREEN|BG_BLACK)<<8;
+ for (x = xoff; x < len; x++) {
+ sc_vtb_putc(&sc->cur_scp->scr,
+ ypos*sc->cur_scp->xsize + xpos + x,
+ sc->scr_map[s[x]], (FG_LIGHTGREEN | BG_BLACK) << 8);
+ }
}
static int
@@ -195,17 +216,30 @@ daemon_saver(video_adapter_t *adp, int blank)
static int moved_daemon = 0;
static int xoff, yoff, toff;
static int xlen, ylen, tlen;
- scr_stat *scp = cur_console;
+ sc_softc_t *sc;
+ scr_stat *scp;
int min, max;
+ sc = sc_find_softc(adp, NULL);
+ if (sc == NULL)
+ return EAGAIN;
+ scp = sc->cur_scp;
+
if (blank) {
if (adp->va_info.vi_flags & V_INFO_GRAPHICS)
return EAGAIN;
if (blanked == 0) {
- window = (u_short *)adp->va_window;
+#ifdef PC98
+ if (epson_machine_id == 0x20) {
+ outb(0x43f, 0x42);
+ outb(0x0c17, inb(0xc17) & ~0x08);
+ outb(0x43f, 0x40);
+ }
+#endif /* PC98 */
/* clear the screen and set the border color */
- fillw(((FG_LIGHTGREY|BG_BLACK) << 8) | scr_map[0x20],
- window, scp->xsize * scp->ysize);
+ sc_vtb_clear(&scp->scr, sc->scr_map[0x20],
+ (FG_LIGHTGREY | BG_BLACK) << 8);
+ (*vidsw[adp->va_index]->set_hw_cursor)(adp, -1, -1);
set_border(scp, 0);
xlen = ylen = tlen = 0;
}
@@ -213,8 +247,8 @@ daemon_saver(video_adapter_t *adp, int blank)
return 0;
blanked = 1;
- clear_daemon(dxpos, dypos, dxdir, xoff, yoff, xlen, ylen);
- clear_string(txpos, typos, toff, (char *)message, tlen);
+ clear_daemon(sc, dxpos, dypos, dxdir, xoff, yoff, xlen, ylen);
+ clear_string(sc, txpos, typos, toff, (char *)message, tlen);
if (++moved_daemon) {
/*
@@ -319,9 +353,16 @@ daemon_saver(video_adapter_t *adp, int blank)
else if (txpos + tlen > scp->xsize)
tlen = scp->xsize - txpos;
- draw_daemon(dxpos, dypos, dxdir, xoff, yoff, xlen, ylen);
- draw_string(txpos, typos, toff, (char *)message, tlen);
+ draw_daemon(sc, dxpos, dypos, dxdir, xoff, yoff, xlen, ylen);
+ draw_string(sc, txpos, typos, toff, (char *)message, tlen);
} else {
+#ifdef PC98
+ if (epson_machine_id == 0x20) {
+ outb(0x43f, 0x42);
+ outb(0x0c17, inb(0xc17) | 0x08);
+ outb(0x43f, 0x40);
+ }
+#endif /* PC98 */
blanked = 0;
}
return 0;
diff --git a/sys/modules/syscons/fade/fade_saver.c b/sys/modules/syscons/fade/fade_saver.c
index 70d36c9..4a44c85 100644
--- a/sys/modules/syscons/fade/fade_saver.c
+++ b/sys/modules/syscons/fade/fade_saver.c
@@ -25,17 +25,19 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: fade_saver.c,v 1.15 1998/11/04 03:49:38 peter Exp $
+ * $Id: fade_saver.c,v 1.16 1999/01/11 03:18:46 yokota Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/module.h>
+#include <sys/consio.h>
+#include <sys/fbio.h>
-#include <i386/isa/isa.h>
-
-#include <saver.h>
+#include <dev/fb/fbreg.h>
+#include <dev/fb/splashreg.h>
+#include <dev/syscons/syscons.h>
static u_char palette[256*3];
static int blanked;
@@ -49,11 +51,10 @@ fade_saver(video_adapter_t *adp, int blank)
if (blank) {
blanked = TRUE;
- switch (adp->va_type) {
- case KD_VGA:
+ if (ISPALAVAIL(adp->va_flags)) {
if (count <= 0)
save_palette(adp, palette);
- if (count < 64) {
+ if (count < 256) {
pal[0] = pal[1] = pal[2] = 0;
for (i = 3; i < 256*3; i++) {
if (palette[i] - count > 60)
@@ -64,39 +65,17 @@ fade_saver(video_adapter_t *adp, int blank)
load_palette(adp, pal);
count++;
}
- break;
- case KD_EGA:
- /* not yet done XXX */
- break;
- case KD_CGA:
- outb(adp->va_crtc_addr + 4, 0x25);
- break;
- case KD_MONO:
- case KD_HERCULES:
- outb(adp->va_crtc_addr + 4, 0x21);
- break;
- default:
- break;
+ } else {
+ (*vidsw[adp->va_index]->blank_display)(adp,
+ V_DISPLAY_BLANK);
}
- }
- else {
- switch (adp->va_type) {
- case KD_VGA:
+ } else {
+ if (ISPALAVAIL(adp->va_flags)) {
load_palette(adp, palette);
count = 0;
- break;
- case KD_EGA:
- /* not yet done XXX */
- break;
- case KD_CGA:
- outb(adp->va_crtc_addr + 4, 0x2d);
- break;
- case KD_MONO:
- case KD_HERCULES:
- outb(adp->va_crtc_addr + 4, 0x29);
- break;
- default:
- break;
+ } else {
+ (*vidsw[adp->va_index]->blank_display)(adp,
+ V_DISPLAY_ON);
}
blanked = FALSE;
}
@@ -106,21 +85,9 @@ fade_saver(video_adapter_t *adp, int blank)
static int
fade_init(video_adapter_t *adp)
{
- switch (adp->va_type) {
- case KD_MONO:
- case KD_HERCULES:
- case KD_CGA:
- /*
- * `fade' saver is not fully implemented for MDA and CGA.
- * It simply blanks the display instead.
- */
- case KD_VGA:
- break;
- case KD_EGA:
- /* EGA is yet to be supported */
- default:
+ if (!ISPALAVAIL(adp->va_flags)
+ && (*vidsw[adp->va_index]->blank_display)(adp, V_DISPLAY_ON) != 0)
return ENODEV;
- }
blanked = FALSE;
return 0;
}
diff --git a/sys/modules/syscons/fire/fire_saver.c b/sys/modules/syscons/fire/fire_saver.c
index aea36a9..db4b80b 100644
--- a/sys/modules/syscons/fire/fire_saver.c
+++ b/sys/modules/syscons/fire/fire_saver.c
@@ -23,7 +23,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: fire_saver.c,v 1.2.2.1 1999/05/10 15:20:30 des Exp $
+ * $Id: fire_saver.c,v 1.4 1999/05/10 15:25:50 des Exp $
*/
/*
@@ -38,11 +38,14 @@
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/syslog.h>
+#include <sys/consio.h>
+#include <sys/fbio.h>
-#include <machine/md_var.h>
#include <machine/random.h>
-#include <saver.h>
+#include <dev/fb/fbreg.h>
+#include <dev/fb/splashreg.h>
+#include <dev/syscons/syscons.h>
#define X_SIZE 320
#define Y_SIZE 200
diff --git a/sys/modules/syscons/green/green_saver.c b/sys/modules/syscons/green/green_saver.c
index 9decd72..103154b 100644
--- a/sys/modules/syscons/green/green_saver.c
+++ b/sys/modules/syscons/green/green_saver.c
@@ -25,93 +25,35 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: green_saver.c,v 1.14 1998/11/04 03:49:38 peter Exp $
+ * $Id: green_saver.c,v 1.15 1999/01/11 03:18:48 yokota Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/module.h>
+#include <sys/consio.h>
+#include <sys/fbio.h>
-#include <dev/fb/vgareg.h>
-
-#include <i386/isa/isa.h>
-
-#include <saver.h>
+#include <dev/fb/fbreg.h>
+#include <dev/fb/splashreg.h>
+#include <dev/syscons/syscons.h>
static int
green_saver(video_adapter_t *adp, int blank)
{
- int crtc_addr;
- u_char val;
-
- crtc_addr = adp->va_crtc_addr;
- if (blank) {
- switch (adp->va_type) {
- case KD_VGA:
- outb(TSIDX, 0x01); val = inb(TSREG);
- outb(TSIDX, 0x01); outb(TSREG, val | 0x20);
- outb(crtc_addr, 0x17); val = inb(crtc_addr + 1);
- outb(crtc_addr + 1, val & ~0x80);
- break;
- case KD_EGA:
- /* not yet done XXX */
- break;
- case KD_CGA:
- outb(crtc_addr + 4, 0x25);
- break;
- case KD_MONO:
- case KD_HERCULES:
- outb(crtc_addr + 4, 0x21);
- break;
- default:
- break;
- }
- }
- else {
- switch (adp->va_type) {
- case KD_VGA:
- outb(TSIDX, 0x01); val = inb(TSREG);
- outb(TSIDX, 0x01); outb(TSREG, val & 0xDF);
- outb(crtc_addr, 0x17); val = inb(crtc_addr + 1);
- outb(crtc_addr + 1, val | 0x80);
- break;
- case KD_EGA:
- /* not yet done XXX */
- break;
- case KD_CGA:
- outb(crtc_addr + 4, 0x2d);
- break;
- case KD_MONO:
- case KD_HERCULES:
- outb(crtc_addr + 4, 0x29);
- break;
- default:
- break;
- }
- }
+ (*vidsw[adp->va_index]->blank_display)(adp,
+ (blank) ? V_DISPLAY_STAND_BY
+ : V_DISPLAY_ON);
return 0;
}
static int
green_init(video_adapter_t *adp)
{
- switch (adp->va_type) {
- case KD_MONO:
- case KD_HERCULES:
- case KD_CGA:
- /*
- * `green' saver is not fully implemented for MDA and CGA.
- * It simply blanks the display instead.
- */
- case KD_VGA:
- break;
- case KD_EGA:
- /* EGA is yet to be supported */
- default:
- return ENODEV;
- }
- return 0;
+ if ((*vidsw[adp->va_index]->blank_display)(adp, V_DISPLAY_ON) == 0)
+ return 0;
+ return ENODEV;
}
static int
diff --git a/sys/modules/syscons/logo/logo_saver.c b/sys/modules/syscons/logo/logo_saver.c
index b6a46ac..24da964 100644
--- a/sys/modules/syscons/logo/logo_saver.c
+++ b/sys/modules/syscons/logo/logo_saver.c
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: logo_saver.c,v 1.5 1999/02/05 12:40:15 des Exp $
+ * $Id: logo_saver.c,v 1.6 1999/04/12 13:34:57 des Exp $
*/
#include <sys/param.h>
@@ -33,8 +33,12 @@
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/syslog.h>
+#include <sys/consio.h>
+#include <sys/fbio.h>
-#include <saver.h>
+#include <dev/fb/fbreg.h>
+#include <dev/fb/splashreg.h>
+#include <dev/syscons/syscons.h>
static u_char *vid;
static int banksize, scrmode, bpsl, scrw, scrh;
@@ -104,6 +108,7 @@ logo_saver(video_adapter_t *adp, int blank)
#endif
blanked++;
vid = (u_char *)adp->va_window;
+ banksize = adp->va_window_size;
bpsl = adp->va_line_width;
splx(pl);
for (i = 0; i < bpsl*scrh; i += banksize) {
@@ -132,7 +137,6 @@ logo_init(video_adapter_t *adp)
return ENODEV;
}
- banksize = info.vi_window_size;
scrw = info.vi_width;
scrh = info.vi_height;
blanked = 0;
diff --git a/sys/modules/syscons/rain/rain_saver.c b/sys/modules/syscons/rain/rain_saver.c
index 9aa7370..200dc59 100644
--- a/sys/modules/syscons/rain/rain_saver.c
+++ b/sys/modules/syscons/rain/rain_saver.c
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: rain_saver.c,v 1.2 1999/01/11 03:18:50 yokota Exp $
+ * $Id: rain_saver.c,v 1.3 1999/04/12 13:34:57 des Exp $
*/
#include <sys/param.h>
@@ -33,10 +33,14 @@
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/syslog.h>
+#include <sys/consio.h>
+#include <sys/fbio.h>
#include <machine/random.h>
-#include <saver.h>
+#include <dev/fb/fbreg.h>
+#include <dev/fb/splashreg.h>
+#include <dev/syscons/syscons.h>
static u_char *vid;
diff --git a/sys/modules/syscons/saver.h b/sys/modules/syscons/saver.h
deleted file mode 100644
index 748dfdd..0000000
--- a/sys/modules/syscons/saver.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*-
- * 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,
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $Id: saver.h,v 1.16 1999/01/16 10:20:13 des Exp $
- */
-#include <machine/apm_bios.h>
-#include <machine/console.h>
-
-#include <dev/fb/fbreg.h>
-#include <dev/fb/splashreg.h>
-
-#include <dev/syscons/syscons.h>
-
-extern scr_stat *cur_console;
-extern char scr_map[];
diff --git a/sys/modules/syscons/snake/snake_saver.c b/sys/modules/syscons/snake/snake_saver.c
index ef64741..51e1746 100644
--- a/sys/modules/syscons/snake/snake_saver.c
+++ b/sys/modules/syscons/snake/snake_saver.c
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: snake_saver.c,v 1.22 1999/01/17 14:25:19 yokota Exp $
+ * $Id: snake_saver.c,v 1.23 1999/02/05 12:40:15 des Exp $
*/
#include <sys/param.h>
@@ -34,16 +34,18 @@
#include <sys/malloc.h>
#include <sys/kernel.h>
#include <sys/sysctl.h>
+#include <sys/consio.h>
+#include <sys/fbio.h>
-#include <machine/md_var.h>
#include <machine/pc/display.h>
-#include <saver.h>
+#include <dev/fb/fbreg.h>
+#include <dev/fb/splashreg.h>
+#include <dev/syscons/syscons.h>
static char *message;
-static u_char **messagep;
+static int *messagep;
static int messagelen;
-static u_short *window;
static int blanked;
static int
@@ -51,36 +53,50 @@ snake_saver(video_adapter_t *adp, int blank)
{
static int dirx, diry;
int f;
- scr_stat *scp = cur_console;
+ sc_softc_t *sc;
+ scr_stat *scp;
/* XXX hack for minimal changes. */
#define save message
#define savs messagep
+ sc = sc_find_softc(adp, NULL);
+ if (sc == NULL)
+ return EAGAIN;
+ scp = sc->cur_scp;
+
if (blank) {
if (adp->va_info.vi_flags & V_INFO_GRAPHICS)
return EAGAIN;
if (blanked <= 0) {
- window = (u_short *)adp->va_window;
- fillw(((FG_LIGHTGREY|BG_BLACK)<<8) | scr_map[0x20],
- window, scp->xsize * scp->ysize);
+#ifdef PC98
+ if (epson_machine_id == 0x20) {
+ outb(0x43f, 0x42);
+ outb(0x0c17, inb(0xc17) & ~0x08);
+ outb(0x43f, 0x40);
+ }
+#endif /* PC98 */
+ sc_vtb_clear(&scp->scr, sc->scr_map[0x20],
+ (FG_LIGHTGREY | BG_BLACK) << 8);
+ (*vidsw[adp->va_index]->set_hw_cursor)(adp, -1, -1);
set_border(scp, 0);
dirx = (scp->xpos ? 1 : -1);
diry = (scp->ypos ?
scp->xsize : -scp->xsize);
for (f=0; f< messagelen; f++)
- savs[f] = (u_char *)window + 2 *
- (scp->xpos+scp->ypos*scp->xsize);
- *(savs[0]) = scr_map[*save];
+ savs[f] = scp->xpos + scp->ypos*scp->xsize;
+ sc_vtb_putc(&scp->scr, savs[0], sc->scr_map[*save],
+ (FG_LIGHTGREY | BG_BLACK) << 8);
blanked = 1;
}
if (blanked++ < 4)
return 0;
blanked = 1;
- *(savs[messagelen-1]) = scr_map[0x20];
+ sc_vtb_putc(&scp->scr, savs[messagelen - 1], sc->scr_map[0x20],
+ (FG_LIGHTGREY | BG_BLACK) << 8);
for (f=messagelen-1; f > 0; f--)
savs[f] = savs[f-1];
- f = (savs[0] - (u_char *)window) / 2;
+ f = savs[0];
if ((f % scp->xsize) == 0 ||
(f % scp->xsize) == scp->xsize - 1 ||
(random() % 50) == 0)
@@ -89,11 +105,19 @@ snake_saver(video_adapter_t *adp, int blank)
(f / scp->xsize) == scp->ysize - 1 ||
(random() % 20) == 0)
diry = -diry;
- savs[0] += 2*dirx + 2*diry;
+ savs[0] += dirx + diry;
for (f=messagelen-1; f>=0; f--)
- *(savs[f]) = scr_map[save[f]];
+ sc_vtb_putc(&scp->scr, savs[f], sc->scr_map[save[f]],
+ (FG_LIGHTGREY | BG_BLACK) << 8);
}
else {
+#ifdef PC98
+ if (epson_machine_id == 0x20) {
+ outb(0x43f, 0x42);
+ outb(0x0c17, inb(0xc17) | 0x08);
+ outb(0x43f, 0x40);
+ }
+#endif /* PC98 */
blanked = 0;
}
return 0;
diff --git a/sys/modules/syscons/star/star_saver.c b/sys/modules/syscons/star/star_saver.c
index aaa23fb..56408dc 100644
--- a/sys/modules/syscons/star/star_saver.c
+++ b/sys/modules/syscons/star/star_saver.c
@@ -25,22 +25,24 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: star_saver.c,v 1.19 1999/01/17 14:25:19 yokota Exp $
+ * $Id: star_saver.c,v 1.20 1999/02/05 12:40:16 des Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/module.h>
+#include <sys/consio.h>
+#include <sys/fbio.h>
-#include <machine/md_var.h>
#include <machine/pc/display.h>
-#include <saver.h>
+#include <dev/fb/fbreg.h>
+#include <dev/fb/splashreg.h>
+#include <dev/syscons/syscons.h>
#define NUM_STARS 50
-static u_short *window;
static int blanked;
/*
@@ -50,21 +52,39 @@ static int blanked;
static int
star_saver(video_adapter_t *adp, int blank)
{
- scr_stat *scp = cur_console;
+ sc_softc_t *sc;
+ scr_stat *scp;
int cell, i;
char pattern[] = {"...........++++*** "};
+#ifndef PC98
char colors[] = {FG_DARKGREY, FG_LIGHTGREY,
FG_WHITE, FG_LIGHTCYAN};
+#else
+ char colors[] = {FG_BLUE, FG_LIGHTGREY,
+ FG_LIGHTGREY, FG_CYAN};
+#endif /* PC98 */
static u_short stars[NUM_STARS][2];
+ sc = sc_find_softc(adp, NULL);
+ if (sc == NULL)
+ return EAGAIN;
+ scp = sc->cur_scp;
+
if (blank) {
if (adp->va_info.vi_flags & V_INFO_GRAPHICS)
return EAGAIN;
if (!blanked) {
- window = (u_short *)adp->va_window;
+#ifdef PC98
+ if (epson_machine_id == 0x20) {
+ outb(0x43f, 0x42);
+ outb(0x0c17, inb(0xc17) & ~0x08);
+ outb(0x43f, 0x40);
+ }
+#endif /* PC98 */
/* clear the screen and set the border color */
- fillw(((FG_LIGHTGREY|BG_BLACK) << 8) | scr_map[0x20],
- window, scp->xsize * scp->ysize);
+ sc_vtb_clear(&scp->scr, sc->scr_map[0x20],
+ (FG_LIGHTGREY | BG_BLACK) << 8);
+ (*vidsw[adp->va_index]->set_hw_cursor)(adp, -1, -1);
set_border(scp, 0);
blanked = TRUE;
for(i=0; i<NUM_STARS; i++) {
@@ -74,15 +94,22 @@ star_saver(video_adapter_t *adp, int blank)
}
}
cell = random() % NUM_STARS;
- *((u_short*)(window + stars[cell][0])) =
- scr_map[pattern[stars[cell][1]]] |
- colors[random()%sizeof(colors)] << 8;
+ sc_vtb_putc(&scp->scr, stars[cell][0],
+ sc->scr_map[pattern[stars[cell][1]]],
+ colors[random()%sizeof(colors)] << 8);
if ((stars[cell][1]+=(random()%4)) >= sizeof(pattern)-1) {
stars[cell][0] = random() % (scp->xsize*scp->ysize);
stars[cell][1] = 0;
}
}
else {
+#ifdef PC98
+ if (epson_machine_id == 0x20) {
+ outb(0x43f, 0x42);
+ outb(0x0c17, inb(0xc17) | 0x08);
+ outb(0x43f, 0x40);
+ }
+#endif /* PC98 */
blanked = FALSE;
}
return 0;
diff --git a/sys/modules/syscons/warp/warp_saver.c b/sys/modules/syscons/warp/warp_saver.c
index 3476c36..cd6f42b 100644
--- a/sys/modules/syscons/warp/warp_saver.c
+++ b/sys/modules/syscons/warp/warp_saver.c
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: warp_saver.c,v 1.4 1999/01/11 03:18:55 yokota Exp $
+ * $Id: warp_saver.c,v 1.5 1999/04/12 13:34:58 des Exp $
*/
#include <sys/param.h>
@@ -33,11 +33,14 @@
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/syslog.h>
+#include <sys/consio.h>
+#include <sys/fbio.h>
-#include <machine/md_var.h>
#include <machine/random.h>
-#include <saver.h>
+#include <dev/fb/fbreg.h>
+#include <dev/fb/splashreg.h>
+#include <dev/syscons/syscons.h>
static u_char *vid;
static int blanked;
diff --git a/sys/sys/cons.h b/sys/sys/cons.h
index 1656b12..ea84d7e 100644
--- a/sys/sys/cons.h
+++ b/sys/sys/cons.h
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* from: @(#)cons.h 7.2 (Berkeley) 5/9/91
- * $Id: cons.h,v 1.18 1999/01/07 14:14:11 yokota Exp $
+ * $Id: cons.h,v 1.19 1999/01/09 14:07:37 bde Exp $
*/
#ifndef _MACHINE_CONS_H_
@@ -45,6 +45,7 @@
struct consdev;
typedef void cn_probe_t __P((struct consdev *));
typedef void cn_init_t __P((struct consdev *));
+typedef void cn_term_t __P((struct consdev *));
typedef int cn_getc_t __P((dev_t));
typedef int cn_checkc_t __P((dev_t));
typedef void cn_putc_t __P((dev_t, int));
@@ -54,6 +55,8 @@ struct consdev {
/* probe hardware and fill in consdev info */
cn_init_t *cn_init;
/* turn on as console */
+ cn_term_t *cn_term;
+ /* turn off as console */
cn_getc_t *cn_getc;
/* kernel getchar interface */
cn_checkc_t *cn_checkc;
@@ -75,10 +78,10 @@ struct consdev {
extern struct linker_set cons_set;
extern int cons_unavail;
-#define CONS_DRIVER(name, probe, init, getc, checkc, putc) \
- static struct consdev name##_consdev = { \
- probe, init, getc, checkc, putc \
- }; \
+#define CONS_DRIVER(name, probe, init, term, getc, checkc, putc) \
+ static struct consdev name##_consdev = { \
+ probe, init, term, getc, checkc, putc \
+ }; \
DATA_SET(cons_set, name##_consdev)
/* Other kernel entry points. */
diff --git a/sys/sys/consio.h b/sys/sys/consio.h
new file mode 100644
index 0000000..abc9c1f
--- /dev/null
+++ b/sys/sys/consio.h
@@ -0,0 +1,385 @@
+/*-
+ * Copyright (c) 1991-1996 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.
+ * 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 AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: console.h,v 1.45 1999/03/10 10:36:47 yokota Exp $
+ */
+
+#ifndef _SYS_CONSIO_H_
+#define _SYS_CONSIO_H_
+
+#ifndef KERNEL
+#include <sys/types.h>
+#endif
+#include <sys/ioccom.h>
+
+/*
+ * Console ioctl commands. Some commands are named as KDXXXX, GIO_XXX, and
+ * PIO_XXX, rather than CONS_XXX, for historical and compatibility reasons.
+ * Some other CONS_XXX commands are works as wrapper around frame buffer
+ * ioctl commands FBIO_XXX. Do not try to change all these commands,
+ * otherwise we shall have compatibility problems.
+ */
+
+/* get/set video mode */
+#define KD_TEXT 0 /* set text mode restore fonts */
+#define KD_TEXT0 0 /* ditto */
+#define KD_GRAPHICS 1 /* set graphics mode */
+#define KD_TEXT1 2 /* set text mode !restore fonts */
+#define KD_PIXEL 3 /* set pixel mode */
+#define KDGETMODE _IOR('K', 9, int)
+#define KDSETMODE _IO('K', 10 /*, int */)
+
+/* set border color */
+#define KDSBORDER _IO('K', 13 /*, int */)
+
+/* set up raster(pixel) text mode */
+struct scr_size {
+ int scr_size[3];
+};
+typedef struct scr_size scr_size_t;
+
+#define KDRASTER _IOW('K', 100, scr_size_t)
+
+/* get/set screen char map */
+struct scrmap {
+ char scrmap[256];
+};
+typedef struct scrmap scrmap_t;
+
+#define GIO_SCRNMAP _IOR('k', 2, scrmap_t)
+#define PIO_SCRNMAP _IOW('k', 3, scrmap_t)
+
+/* get the current text attribute */
+#define GIO_ATTR _IOR('a', 0, int)
+
+/* get the current text color */
+#define GIO_COLOR _IOR('c', 0, int)
+
+/* get the adapter type (equivalent to FBIO_ADPTYPE) */
+#define CONS_CURRENT _IOR('c', 1, int)
+
+/* get the current video mode (equivalent to FBIO_GETMODE) */
+#define CONS_GET _IOR('c', 2, int)
+
+/* not supported? */
+#define CONS_IO _IO('c', 3)
+
+/* set blank time interval */
+#define CONS_BLANKTIME _IOW('c', 4, int)
+
+/* set/get the screen saver (these ioctls are current noop) */
+struct ssaver {
+#define MAXSSAVER 16
+ char name[MAXSSAVER];
+ int num;
+ long time;
+};
+typedef struct ssaver ssaver_t;
+
+#define CONS_SSAVER _IOW('c', 5, ssaver_t)
+#define CONS_GSAVER _IOWR('c', 6, ssaver_t)
+
+/* set the text cursor shape */
+#define CONS_BLINK_CURSOR (1 << 0)
+#define CONS_CHAR_CURSOR (1 << 1)
+#define CONS_CURSORTYPE _IOW('c', 7, int)
+
+/* set the bell type to audible or visual */
+#define CONS_VISUAL_BELL (1 << 0)
+#define CONS_QUIET_BELL (1 << 1)
+#define CONS_BELLTYPE _IOW('c', 8, int)
+
+/* set the history (scroll back) buffer size (in lines) */
+#define CONS_HISTORY _IOW('c', 9, int)
+
+/* mouse cursor ioctl */
+struct mouse_data {
+ int x;
+ int y;
+ int z;
+ int buttons;
+};
+typedef struct mouse_data mouse_data_t;
+
+struct mouse_mode {
+ int mode;
+ int signal;
+};
+typedef struct mouse_mode mouse_mode_t;
+
+struct mouse_event {
+ int id; /* one based */
+ int value;
+};
+typedef struct mouse_event mouse_event_t;
+
+struct mouse_info {
+ int operation;
+#define MOUSE_SHOW 0x01
+#define MOUSE_HIDE 0x02
+#define MOUSE_MOVEABS 0x03
+#define MOUSE_MOVEREL 0x04
+#define MOUSE_GETINFO 0x05
+#define MOUSE_MODE 0x06
+#define MOUSE_ACTION 0x07
+#define MOUSE_MOTION_EVENT 0x08
+#define MOUSE_BUTTON_EVENT 0x09
+ union {
+ mouse_data_t data;
+ mouse_mode_t mode;
+ mouse_event_t event;
+ } u;
+};
+typedef struct mouse_info mouse_info_t;
+
+#define CONS_MOUSECTL _IOWR('c', 10, mouse_info_t)
+
+/* see if the vty has been idle */
+#define CONS_IDLE _IOR('c', 11, int)
+
+/* set the screen saver mode */
+#define CONS_LKM_SAVER 0
+#define CONS_USR_SAVER 1
+#define CONS_SAVERMODE _IOW('c', 12, int)
+
+/* start the screen saver */
+#define CONS_SAVERSTART _IOW('c', 13, int)
+
+/* set/get font data */
+struct fnt8 {
+ char fnt8x8[8*256];
+};
+typedef struct fnt8 fnt8_t;
+
+struct fnt14 {
+ char fnt8x14[14*256];
+};
+typedef struct fnt14 fnt14_t;
+
+struct fnt16 {
+ char fnt8x16[16*256];
+};
+typedef struct fnt16 fnt16_t;
+
+#define PIO_FONT8x8 _IOW('c', 64, fnt8_t)
+#define GIO_FONT8x8 _IOR('c', 65, fnt8_t)
+#define PIO_FONT8x14 _IOW('c', 66, fnt14_t)
+#define GIO_FONT8x14 _IOR('c', 67, fnt14_t)
+#define PIO_FONT8x16 _IOW('c', 68, fnt16_t)
+#define GIO_FONT8x16 _IOR('c', 69, fnt16_t)
+
+/* get video mode information */
+struct colors {
+ char fore;
+ char back;
+};
+
+struct vid_info {
+ short size;
+ short m_num;
+ u_short mv_row, mv_col;
+ u_short mv_rsz, mv_csz;
+ struct colors mv_norm,
+ mv_rev,
+ mv_grfc;
+ u_char mv_ovscan;
+ u_char mk_keylock;
+};
+typedef struct vid_info vid_info_t;
+
+#define CONS_GETINFO _IOWR('c', 73, vid_info_t)
+
+/* get version */
+#define CONS_GETVERS _IOR('c', 74, int)
+
+/* get the video adapter index (equivalent to FBIO_ADAPTER) */
+#define CONS_CURRENTADP _IOR('c', 100, int)
+
+/* get the video adapter information (equivalent to FBIO_ADPINFO) */
+#define CONS_ADPINFO _IOWR('c', 101, video_adapter_info_t)
+
+/* get the video mode information (equivalent to FBIO_MODEINFO) */
+#define CONS_MODEINFO _IOWR('c', 102, video_info_t)
+
+/* find a video mode (equivalent to FBIO_FINDMODE) */
+#define CONS_FINDMODE _IOWR('c', 103, video_info_t)
+
+/* set the frame buffer window origin (equivalent to FBIO_SETWINORG) */
+#define CONS_SETWINORG _IO('c', 104 /*, u_int */)
+
+/* use the specified keyboard */
+#define CONS_SETKBD _IO('c', 110 /*, int */)
+
+/* release the current keyboard */
+#define CONS_RELKBD _IO('c', 111)
+
+#ifdef PC98
+#define ADJUST_CLOCK _IO('t',100) /* for 98note resume */
+#endif
+
+/*
+ * Vty switching ioctl commands.
+ */
+
+/* get the next available vty */
+#define VT_OPENQRY _IOR('v', 1, int)
+
+/* set/get vty switching mode */
+#ifndef _VT_MODE_DECLARED
+#define _VT_MODE_DECLARED
+struct vt_mode {
+ char mode;
+#define VT_AUTO 0 /* switching is automatic */
+#define VT_PROCESS 1 /* switching controlled by prog */
+#define VT_KERNEL 255 /* switching controlled in kernel */
+ char waitv; /* not implemented yet SOS */
+ short relsig;
+ short acqsig;
+ short frsig; /* not implemented yet SOS */
+};
+typedef struct vt_mode vtmode_t;
+#endif /* !_VT_MODE_DECLARED */
+
+#define VT_SETMODE _IOW('v', 2, vtmode_t)
+#define VT_GETMODE _IOR('v', 3, vtmode_t)
+
+/* acknowledge release or acquisition of a vty */
+#define VT_FALSE 0
+#define VT_TRUE 1
+#define VT_ACKACQ 2
+#define VT_RELDISP _IO('v', 4 /*, int */)
+
+/* activate the specified vty */
+#define VT_ACTIVATE _IO('v', 5 /*, int */)
+
+/* wait until the specified vty is activate */
+#define VT_WAITACTIVE _IO('v', 6 /*, int */)
+
+/* get the currently active vty */
+#define VT_GETACTIVE _IOR('v', 7, int)
+
+/* get the index of the vty */
+#define VT_GETINDEX _IOR('v', 8, int)
+
+/*
+ * Video mode switching ioctl. See sys/fbio.h for mode numbers.
+ */
+
+#define SW_B40x25 _IO('S', M_B40x25)
+#define SW_C40x25 _IO('S', M_C40x25)
+#define SW_B80x25 _IO('S', M_B80x25)
+#define SW_C80x25 _IO('S', M_C80x25)
+#define SW_BG320 _IO('S', M_BG320)
+#define SW_CG320 _IO('S', M_CG320)
+#define SW_BG640 _IO('S', M_BG640)
+#define SW_EGAMONO80x25 _IO('S', M_EGAMONO80x25)
+#define SW_CG320_D _IO('S', M_CG320_D)
+#define SW_CG640_E _IO('S', M_CG640_E)
+#define SW_EGAMONOAPA _IO('S', M_EGAMONOAPA)
+#define SW_CG640x350 _IO('S', M_CG640x350)
+#define SW_ENH_MONOAPA2 _IO('S', M_ENHMONOAPA2)
+#define SW_ENH_CG640 _IO('S', M_ENH_CG640)
+#define SW_ENH_B40x25 _IO('S', M_ENH_B40x25)
+#define SW_ENH_C40x25 _IO('S', M_ENH_C40x25)
+#define SW_ENH_B80x25 _IO('S', M_ENH_B80x25)
+#define SW_ENH_C80x25 _IO('S', M_ENH_C80x25)
+#define SW_ENH_B80x43 _IO('S', M_ENH_B80x43)
+#define SW_ENH_C80x43 _IO('S', M_ENH_C80x43)
+#define SW_MCAMODE _IO('S', M_MCA_MODE)
+#define SW_VGA_C40x25 _IO('S', M_VGA_C40x25)
+#define SW_VGA_C80x25 _IO('S', M_VGA_C80x25)
+#define SW_VGA_C80x30 _IO('S', M_VGA_C80x30)
+#define SW_VGA_C80x50 _IO('S', M_VGA_C80x50)
+#define SW_VGA_C80x60 _IO('S', M_VGA_C80x60)
+#define SW_VGA_M80x25 _IO('S', M_VGA_M80x25)
+#define SW_VGA_M80x30 _IO('S', M_VGA_M80x30)
+#define SW_VGA_M80x50 _IO('S', M_VGA_M80x50)
+#define SW_VGA_M80x60 _IO('S', M_VGA_M80x60)
+#define SW_VGA11 _IO('S', M_VGA11)
+#define SW_BG640x480 _IO('S', M_VGA11)
+#define SW_VGA12 _IO('S', M_VGA12)
+#define SW_CG640x480 _IO('S', M_VGA12)
+#define SW_VGA13 _IO('S', M_VGA13)
+#define SW_VGA_CG320 _IO('S', M_VGA13)
+#define SW_VGA_CG640 _IO('S', M_VGA_CG640)
+#define SW_VGA_MODEX _IO('S', M_VGA_MODEX)
+
+#define SW_PC98_80x25 _IO('S', M_PC98_80x25)
+#define SW_PC98_80x30 _IO('S', M_PC98_80x30)
+
+#define SW_VGA_C90x25 _IO('S', M_VGA_C90x25)
+#define SW_VGA_M90x25 _IO('S', M_VGA_M90x25)
+#define SW_VGA_C90x30 _IO('S', M_VGA_C90x30)
+#define SW_VGA_M90x30 _IO('S', M_VGA_M90x30)
+#define SW_VGA_C90x43 _IO('S', M_VGA_C90x43)
+#define SW_VGA_M90x43 _IO('S', M_VGA_M90x43)
+#define SW_VGA_C90x50 _IO('S', M_VGA_C90x50)
+#define SW_VGA_M90x50 _IO('S', M_VGA_M90x50)
+#define SW_VGA_C90x60 _IO('S', M_VGA_C90x60)
+#define SW_VGA_M90x60 _IO('S', M_VGA_M90x60)
+
+#define SW_TEXT_80x25 _IO('S', M_TEXT_80x25)
+#define SW_TEXT_80x30 _IO('S', M_TEXT_80x30)
+#define SW_TEXT_80x43 _IO('S', M_TEXT_80x43)
+#define SW_TEXT_80x50 _IO('S', M_TEXT_80x50)
+#define SW_TEXT_80x60 _IO('S', M_TEXT_80x60)
+#define SW_TEXT_132x25 _IO('S', M_TEXT_132x25)
+#define SW_TEXT_132x30 _IO('S', M_TEXT_132x30)
+#define SW_TEXT_132x43 _IO('S', M_TEXT_132x43)
+#define SW_TEXT_132x50 _IO('S', M_TEXT_132x50)
+#define SW_TEXT_132x60 _IO('S', M_TEXT_132x60)
+
+#define SW_VESA_CG640x400 _IO('V', M_VESA_CG640x400 - M_VESA_BASE)
+#define SW_VESA_CG640x480 _IO('V', M_VESA_CG640x480 - M_VESA_BASE)
+#define SW_VESA_800x600 _IO('V', M_VESA_800x600 - M_VESA_BASE)
+#define SW_VESA_CG800x600 _IO('V', M_VESA_CG800x600 - M_VESA_BASE)
+#define SW_VESA_1024x768 _IO('V', M_VESA_1024x768 - M_VESA_BASE)
+#define SW_VESA_CG1024x768 _IO('V', M_VESA_CG1024x768 - M_VESA_BASE)
+#define SW_VESA_1280x1024 _IO('V', M_VESA_1280x1024 - M_VESA_BASE)
+#define SW_VESA_CG1280x1024 _IO('V', M_VESA_CG1280x1024 - M_VESA_BASE)
+#define SW_VESA_C80x60 _IO('V', M_VESA_C80x60 - M_VESA_BASE)
+#define SW_VESA_C132x25 _IO('V', M_VESA_C132x25 - M_VESA_BASE)
+#define SW_VESA_C132x43 _IO('V', M_VESA_C132x43 - M_VESA_BASE)
+#define SW_VESA_C132x50 _IO('V', M_VESA_C132x50 - M_VESA_BASE)
+#define SW_VESA_C132x60 _IO('V', M_VESA_C132x60 - M_VESA_BASE)
+#define SW_VESA_32K_320 _IO('V', M_VESA_32K_320 - M_VESA_BASE)
+#define SW_VESA_64K_320 _IO('V', M_VESA_64K_320 - M_VESA_BASE)
+#define SW_VESA_FULL_320 _IO('V', M_VESA_FULL_320 - M_VESA_BASE)
+#define SW_VESA_32K_640 _IO('V', M_VESA_32K_640 - M_VESA_BASE)
+#define SW_VESA_64K_640 _IO('V', M_VESA_64K_640 - M_VESA_BASE)
+#define SW_VESA_FULL_640 _IO('V', M_VESA_FULL_640 - M_VESA_BASE)
+#define SW_VESA_32K_800 _IO('V', M_VESA_32K_800 - M_VESA_BASE)
+#define SW_VESA_64K_800 _IO('V', M_VESA_64K_800 - M_VESA_BASE)
+#define SW_VESA_FULL_800 _IO('V', M_VESA_FULL_800 - M_VESA_BASE)
+#define SW_VESA_32K_1024 _IO('V', M_VESA_32K_1024 - M_VESA_BASE)
+#define SW_VESA_64K_1024 _IO('V', M_VESA_64K_1024 - M_VESA_BASE)
+#define SW_VESA_FULL_1024 _IO('V', M_VESA_FULL_1024 - M_VESA_BASE)
+#define SW_VESA_32K_1280 _IO('V', M_VESA_32K_1280 - M_VESA_BASE)
+#define SW_VESA_64K_1280 _IO('V', M_VESA_64K_1280 - M_VESA_BASE)
+#define SW_VESA_FULL_1280 _IO('V', M_VESA_FULL_1280 - M_VESA_BASE)
+
+#endif /* !_SYS_CONSIO_H_ */
diff --git a/sys/sys/fbio.h b/sys/sys/fbio.h
index 5dca599..c4b5153 100644
--- a/sys/sys/fbio.h
+++ b/sys/sys/fbio.h
@@ -36,12 +36,17 @@
*
* @(#)fbio.h 8.2 (Berkeley) 10/30/93
*
- * $Id$
+ * $Id: fbio.h,v 1.5 1997/02/22 09:45:12 peter Exp $
*/
#ifndef _SYS_FBIO_H_
#define _SYS_FBIO_H_
+#ifndef KERNEL
+#include <sys/types.h>
+#endif
+#include <sys/ioccom.h>
+
/*
* Frame buffer ioctls (from Sprite, trimmed to essentials for X11).
*/
@@ -72,7 +77,15 @@
#define FBTYPE_RESERVED2 18 /* reserved, do not use */
#define FBTYPE_RESERVED1 19 /* reserved, do not use */
-#define FBTYPE_LASTPLUSONE 20 /* max number of fbs (change as add) */
+#define FBTYPE_MDA 20
+#define FBTYPE_HERCULES 21
+#define FBTYPE_CGA 22
+#define FBTYPE_EGA 23
+#define FBTYPE_VGA 24
+#define FBTYPE_PC98 25
+#define FBTYPE_TGA 26
+
+#define FBTYPE_LASTPLUSONE 27 /* max number of fbs (change as add) */
/*
* Frame buffer descriptor as returned by FBIOGTYPE.
@@ -188,4 +201,274 @@ struct fbcursor {
/* get maximum cursor size */
#define FBIOGCURMAX _IOR('F', 28, struct fbcurpos)
-#endif
+/* The new style frame buffer ioctls. */
+
+/* video mode information block */
+struct video_info {
+ int vi_mode; /* mode number, see below */
+ int vi_flags;
+#define V_INFO_COLOR (1 << 0)
+#define V_INFO_GRAPHICS (1 << 1)
+#define V_INFO_LINEAR (1 << 2)
+#define V_INFO_VESA (1 << 3)
+ int vi_width;
+ int vi_height;
+ int vi_cwidth;
+ int vi_cheight;
+ int vi_depth;
+ int vi_planes;
+ u_int vi_window; /* physical address */
+ size_t vi_window_size;
+ size_t vi_window_gran;
+ u_int vi_buffer; /* physical address */
+ size_t vi_buffer_size;
+ int vi_mem_model;
+#define V_INFO_MM_OTHER (-1)
+#define V_INFO_MM_TEXT 0
+#define V_INFO_MM_PLANAR 1
+#define V_INFO_MM_PACKED 2
+#define V_INFO_MM_DIRECT 3
+#define V_INFO_MM_CGA 100
+#define V_INFO_MM_HGC 101
+ /* for MM_PACKED and MM_DIRECT only */
+ int vi_pixel_size; /* in bytes */
+ /* for MM_DIRECT only */
+ int vi_pixel_fields[4]; /* RGB and reserved fields */
+ int vi_pixel_fsizes[4];
+ /* reserved */
+ u_char vi_reserved[64];
+};
+typedef struct video_info video_info_t;
+
+/* adapter infromation block */
+struct video_adapter {
+ int va_index;
+ int va_type;
+#define KD_OTHER 0 /* unknown */
+#define KD_MONO 1 /* monochrome adapter */
+#define KD_HERCULES 2 /* hercules adapter */
+#define KD_CGA 3 /* color graphics adapter */
+#define KD_EGA 4 /* enhanced graphics adapter */
+#define KD_VGA 5 /* video graphics adapter */
+#define KD_PC98 6 /* PC-98 display */
+#define KD_TGA 7 /* TGA */
+ char *va_name;
+ int va_unit;
+ int va_minor;
+ int va_flags;
+#define V_ADP_COLOR (1 << 0)
+#define V_ADP_MODECHANGE (1 << 1)
+#define V_ADP_STATESAVE (1 << 2)
+#define V_ADP_STATELOAD (1 << 3)
+#define V_ADP_FONT (1 << 4)
+#define V_ADP_PALETTE (1 << 5)
+#define V_ADP_BORDER (1 << 6)
+#define V_ADP_VESA (1 << 7)
+#define V_ADP_PROBED (1 << 16)
+#define V_ADP_INITIALIZED (1 << 17)
+#define V_ADP_REGISTERED (1 << 18)
+ int va_io_base;
+ int va_io_size;
+ int va_crtc_addr;
+ int va_mem_base;
+ int va_mem_size;
+ vm_offset_t va_window; /* virtual address */
+ size_t va_window_size;
+ size_t va_window_gran;
+ u_int va_window_orig;
+ vm_offset_t va_buffer; /* virtual address */
+ size_t va_buffer_size;
+ int va_initial_mode;
+ int va_initial_bios_mode;
+ int va_mode;
+ struct video_info va_info;
+ int va_line_width;
+ struct {
+ int x;
+ int y;
+ } va_disp_start;
+ void *va_token;
+};
+typedef struct video_adapter video_adapter_t;
+
+struct video_adapter_info {
+ int va_index;
+ int va_type;
+ char va_name[16];
+ int va_unit;
+ int va_flags;
+ int va_io_base;
+ int va_io_size;
+ int va_crtc_addr;
+ int va_mem_base;
+ int va_mem_size;
+ u_int va_window; /* virtual address */
+ size_t va_window_size;
+ size_t va_window_gran;
+ u_int va_unused0;
+ size_t va_buffer_size;
+ int va_initial_mode;
+ int va_initial_bios_mode;
+ int va_mode;
+ int va_line_width;
+ struct {
+ int x;
+ int y;
+ } va_disp_start;
+ u_int va_window_orig;
+ /* reserved */
+ u_char va_reserved[64];
+};
+typedef struct video_adapter_info video_adapter_info_t;
+
+/* some useful video adapter index */
+#define V_ADP_PRIMARY 0
+#define V_ADP_SECONDARY 1
+
+/* video mode numbers */
+
+#define M_B40x25 0 /* black & white 40 columns */
+#define M_C40x25 1 /* color 40 columns */
+#define M_B80x25 2 /* black & white 80 columns */
+#define M_C80x25 3 /* color 80 columns */
+#define M_BG320 4 /* black & white graphics 320x200 */
+#define M_CG320 5 /* color graphics 320x200 */
+#define M_BG640 6 /* black & white graphics 640x200 hi-res */
+#define M_EGAMONO80x25 7 /* ega-mono 80x25 */
+#define M_CG320_D 13 /* ega mode D */
+#define M_CG640_E 14 /* ega mode E */
+#define M_EGAMONOAPA 15 /* ega mode F */
+#define M_CG640x350 16 /* ega mode 10 */
+#define M_ENHMONOAPA2 17 /* ega mode F with extended memory */
+#define M_ENH_CG640 18 /* ega mode 10* */
+#define M_ENH_B40x25 19 /* ega enhanced black & white 40 columns */
+#define M_ENH_C40x25 20 /* ega enhanced color 40 columns */
+#define M_ENH_B80x25 21 /* ega enhanced black & white 80 columns */
+#define M_ENH_C80x25 22 /* ega enhanced color 80 columns */
+#define M_VGA_C40x25 23 /* vga 8x16 font on color */
+#define M_VGA_C80x25 24 /* vga 8x16 font on color */
+#define M_VGA_M80x25 25 /* vga 8x16 font on mono */
+
+#define M_VGA11 26 /* vga 640x480 2 colors */
+#define M_BG640x480 26
+#define M_VGA12 27 /* vga 640x480 16 colors */
+#define M_CG640x480 27
+#define M_VGA13 28 /* vga 320x200 256 colors */
+#define M_VGA_CG320 28
+
+#define M_VGA_C80x50 30 /* vga 8x8 font on color */
+#define M_VGA_M80x50 31 /* vga 8x8 font on color */
+#define M_VGA_C80x30 32 /* vga 8x16 font on color */
+#define M_VGA_M80x30 33 /* vga 8x16 font on color */
+#define M_VGA_C80x60 34 /* vga 8x8 font on color */
+#define M_VGA_M80x60 35 /* vga 8x8 font on color */
+#define M_VGA_CG640 36 /* vga 640x400 256 color */
+#define M_VGA_MODEX 37 /* vga 320x240 256 color */
+
+#define M_VGA_C90x25 40 /* vga 8x16 font on color */
+#define M_VGA_M90x25 41 /* vga 8x16 font on mono */
+#define M_VGA_C90x30 42 /* vga 8x16 font on color */
+#define M_VGA_M90x30 43 /* vga 8x16 font on mono */
+#define M_VGA_C90x43 44 /* vga 8x8 font on color */
+#define M_VGA_M90x43 45 /* vga 8x8 font on mono */
+#define M_VGA_C90x50 46 /* vga 8x8 font on color */
+#define M_VGA_M90x50 47 /* vga 8x8 font on mono */
+#define M_VGA_C90x60 48 /* vga 8x8 font on color */
+#define M_VGA_M90x60 49 /* vga 8x8 font on mono */
+
+#define M_ENH_B80x43 0x70 /* ega black & white 80x43 */
+#define M_ENH_C80x43 0x71 /* ega color 80x43 */
+
+#define M_PC98_80x25 98 /* PC98 80x25 */
+#define M_PC98_80x30 99 /* PC98 80x30 */
+
+#define M_HGC_P0 0xe0 /* hercules graphics - page 0 @ B0000 */
+#define M_HGC_P1 0xe1 /* hercules graphics - page 1 @ B8000 */
+#define M_MCA_MODE 0xff /* monochrome adapter mode */
+
+#define M_TEXT_80x25 200 /* generic text modes */
+#define M_TEXT_80x30 201
+#define M_TEXT_80x43 202
+#define M_TEXT_80x50 203
+#define M_TEXT_80x60 204
+#define M_TEXT_132x25 205
+#define M_TEXT_132x30 206
+#define M_TEXT_132x43 207
+#define M_TEXT_132x50 208
+#define M_TEXT_132x60 209
+
+#define M_VESA_BASE 0x100 /* VESA mode number base */
+#define M_VESA_CG640x400 0x100 /* 640x400, 256 color */
+#define M_VESA_CG640x480 0x101 /* 640x480, 256 color */
+#define M_VESA_800x600 0x102 /* 800x600, 16 color */
+#define M_VESA_CG800x600 0x103 /* 800x600, 256 color */
+#define M_VESA_1024x768 0x104 /* 1024x768, 16 color */
+#define M_VESA_CG1024x768 0x105 /* 1024x768, 256 color */
+#define M_VESA_1280x1024 0x106 /* 1280x1024, 16 color */
+#define M_VESA_CG1280x1024 0x107 /* 1280x1024, 256 color */
+#define M_VESA_C80x60 0x108 /* 8x8 font */
+#define M_VESA_C132x25 0x109 /* 8x16 font */
+#define M_VESA_C132x43 0x10a /* 8x14 font */
+#define M_VESA_C132x50 0x10b /* 8x8 font */
+#define M_VESA_C132x60 0x10c /* 8x8 font */
+#define M_VESA_32K_320 0x10d /* 320x200, 5:5:5 */
+#define M_VESA_64K_320 0x10e /* 320x200, 5:6:5 */
+#define M_VESA_FULL_320 0x10f /* 320x200, 8:8:8 */
+#define M_VESA_32K_640 0x110 /* 640x480, 5:5:5 */
+#define M_VESA_64K_640 0x111 /* 640x480, 5:6:5 */
+#define M_VESA_FULL_640 0x112 /* 640x480, 8:8:8 */
+#define M_VESA_32K_800 0x113 /* 800x600, 5:5:5 */
+#define M_VESA_64K_800 0x114 /* 800x600, 5:6:5 */
+#define M_VESA_FULL_800 0x115 /* 800x600, 8:8:8 */
+#define M_VESA_32K_1024 0x116 /* 1024x768, 5:5:5 */
+#define M_VESA_64K_1024 0x117 /* 1024x768, 5:6:5 */
+#define M_VESA_FULL_1024 0x118 /* 1024x768, 8:8:8 */
+#define M_VESA_32K_1280 0x119 /* 1280x1024, 5:5:5 */
+#define M_VESA_64K_1280 0x11a /* 1280x1024, 5:6:5 */
+#define M_VESA_FULL_1280 0x11b /* 1280x1024, 8:8:8 */
+#define M_VESA_MODE_MAX 0x1ff
+
+struct video_display_start {
+ int x;
+ int y;
+};
+typedef struct video_display_start video_display_start_t;
+
+struct video_color_palette {
+ int index; /* first element (zero-based) */
+ int count; /* number of elements */
+ u_char *red; /* red */
+ u_char *green; /* green */
+ u_char *blue; /* blue */
+ u_char *transparent; /* may be NULL */
+};
+typedef struct video_color_palette video_color_palette_t;
+
+/* adapter info. */
+#define FBIO_ADAPTER _IOR('F', 100, int)
+#define FBIO_ADPTYPE _IOR('F', 101, int)
+#define FBIO_ADPINFO _IOR('F', 102, struct video_adapter_info)
+
+/* video mode control */
+#define FBIO_MODEINFO _IOWR('F', 103, struct video_info)
+#define FBIO_FINDMODE _IOWR('F', 104, struct video_info)
+#define FBIO_GETMODE _IOR('F', 105, int)
+#define FBIO_SETMODE _IOW('F', 106, int)
+
+/* get/set frame buffer window origin */
+#define FBIO_GETWINORG _IOR('F', 107, u_int)
+#define FBIO_SETWINORG _IOW('F', 108, u_int)
+
+/* get/set display start address */
+#define FBIO_GETDISPSTART _IOR('F', 109, video_display_start_t)
+#define FBIO_SETDISPSTART _IOW('F', 110, video_display_start_t)
+
+/* get/set scan line width */
+#define FBIO_GETLINEWIDTH _IOR('F', 111, u_int)
+#define FBIO_SETLINEWIDTH _IOW('F', 112, u_int)
+
+/* color palette control */
+#define FBIO_GETPALETTE _IOW('F', 113, video_color_palette_t)
+#define FBIO_SETPALETTE _IOW('F', 114, video_color_palette_t)
+
+#endif /* !_SYS_FBIO_H_ */
diff --git a/sys/sys/kbio.h b/sys/sys/kbio.h
new file mode 100644
index 0000000..c8e9947
--- /dev/null
+++ b/sys/sys/kbio.h
@@ -0,0 +1,228 @@
+/*-
+ * $Id: $
+ */
+
+#ifndef _SYS_KBIO_H_
+#define _SYS_KBIO_H_
+
+#ifndef KERNEL
+#include <sys/types.h>
+#endif
+#include <sys/ioccom.h>
+
+/* get/set keyboard I/O mode */
+#define K_RAW 0 /* keyboard returns scancodes */
+#define K_XLATE 1 /* keyboard returns ascii */
+#define K_CODE 2 /* keyboard returns keycodes */
+#define KDGKBMODE _IOR('K', 6, int)
+#define KDSKBMODE _IO('K', 7 /*, int */)
+
+/* make tone */
+#define KDMKTONE _IO('K', 8 /*, int */)
+
+/* see console.h for the definitions of the following ioctls */
+#if notdef
+#define KDGETMODE _IOR('K', 9, int)
+#define KDSETMODE _IO('K', 10 /*, int */)
+#define KDSBORDER _IO('K', 13 /*, int */)
+#endif
+
+/* get/set keyboard lock state */
+#define CLKED 1 /* Caps locked */
+#define NLKED 2 /* Num locked */
+#define SLKED 4 /* Scroll locked */
+#define ALKED 8 /* AltGr locked */
+#define LOCK_MASK (CLKED | NLKED | SLKED | ALKED)
+#define KDGKBSTATE _IOR('K', 19, int)
+#define KDSKBSTATE _IO('K', 20 /*, int */)
+
+/* enable/disable I/O access */
+#define KDENABIO _IO('K', 60)
+#define KDDISABIO _IO('K', 61)
+
+/* make sound */
+#define KIOCSOUND _IO('K', 63 /*, int */)
+
+/* get keyboard model */
+#define KB_OTHER 0 /* keyboard not known */
+#define KB_84 1 /* 'old' 84 key AT-keyboard */
+#define KB_101 2 /* MF-101 or MF-102 keyboard */
+#define KDGKBTYPE _IOR('K', 64, int)
+
+/* get/set keyboard LED state */
+#define LED_CAP 1 /* Caps lock LED */
+#define LED_NUM 2 /* Num lock LED */
+#define LED_SCR 4 /* Scroll lock LED */
+#define LED_MASK (LED_CAP | LED_NUM | LED_SCR)
+#define KDGETLED _IOR('K', 65, int)
+#define KDSETLED _IO('K', 66 /*, int */)
+
+/* set keyboard repeat rate (obsolete, use KDSETREPEAT below) */
+#define KDSETRAD _IO('K', 67 /*, int */)
+
+/* see console.h for the definition of the following ioctl */
+#if notdef
+#define KDRASTER _IOW('K', 100, scr_size_t)
+#endif
+
+/* get keyboard information */
+struct keyboard_info {
+ int kb_index; /* kbdio index# */
+ char kb_name[16]; /* driver name */
+ int kb_unit; /* unit# */
+ int kb_type; /* KB_84, KB_101, KB_OTHER,... */
+ int kb_config; /* device configuration flags */
+ int kb_flags; /* internal flags */
+};
+typedef struct keyboard_info keyboard_info_t;
+#define KDGKBINFO _IOR('K', 101, keyboard_info_t)
+
+/* set keyboard repeat rate (new interface) */
+struct keyboard_repeat {
+ int kb_repeat[2];
+};
+typedef struct keyboard_repeat keyboard_repeat_t;
+#define KDSETREPEAT _IOW('K', 102, keyboard_repeat_t)
+
+/* get/set key map/accent map/function key strings */
+
+#define NUM_KEYS 256 /* number of keys in table */
+#define NUM_STATES 8 /* states per key */
+#define ALTGR_OFFSET 128 /* offset for altlock keys */
+
+#define NUM_DEADKEYS 15 /* number of accent keys */
+#define NUM_ACCENTCHARS 52 /* max number of accent chars */
+
+#define NUM_FKEYS 96 /* max number of function keys */
+#define MAXFK 16 /* max length of a function key str */
+
+#ifndef _KEYMAP_DECLARED
+#define _KEYMAP_DECLARED
+
+struct keyent_t {
+ u_char map[NUM_STATES];
+ u_char spcl;
+ u_char flgs;
+#define FLAG_LOCK_O 0
+#define FLAG_LOCK_C 1
+#define FLAG_LOCK_N 2
+};
+
+struct keymap {
+ u_short n_keys;
+ struct keyent_t key[NUM_KEYS];
+};
+typedef struct keymap keymap_t;
+
+#endif /* !_KEYMAP_DECLARED */
+
+/* defines for "special" keys (spcl bit set in keymap) */
+#define NOP 0x00 /* nothing (dead key) */
+#define LSH 0x02 /* left shift key */
+#define RSH 0x03 /* right shift key */
+#define CLK 0x04 /* caps lock key */
+#define NLK 0x05 /* num lock key */
+#define SLK 0x06 /* scroll lock key */
+#define LALT 0x07 /* left alt key */
+#define BTAB 0x08 /* backwards tab */
+#define LCTR 0x09 /* left control key */
+#define NEXT 0x0a /* switch to next screen */
+#define F_SCR 0x0b /* switch to first screen */
+#define L_SCR 0x1a /* switch to last screen */
+#define F_FN 0x1b /* first function key */
+#define L_FN 0x7a /* last function key */
+/* 0x7b-0x7f reserved do not use ! */
+#define RCTR 0x80 /* right control key */
+#define RALT 0x81 /* right alt (altgr) key */
+#define ALK 0x82 /* alt lock key */
+#define ASH 0x83 /* alt shift key */
+#define META 0x84 /* meta key */
+#define RBT 0x85 /* boot machine */
+#define DBG 0x86 /* call debugger */
+#define SUSP 0x87 /* suspend power (APM) */
+#define SPSC 0x88 /* toggle splash/text screen */
+
+#define F_ACC DGRA /* first accent key */
+#define DGRA 0x89 /* grave */
+#define DACU 0x8a /* acute */
+#define DCIR 0x8b /* circumflex */
+#define DTIL 0x8c /* tilde */
+#define DMAC 0x8d /* macron */
+#define DBRE 0x8e /* breve */
+#define DDOT 0x8f /* dot */
+#define DUML 0x90 /* umlaut/diaresis */
+#define DDIA 0x90 /* diaresis */
+#define DSLA 0x91 /* slash */
+#define DRIN 0x92 /* ring */
+#define DCED 0x93 /* cedilla */
+#define DAPO 0x94 /* apostrophe */
+#define DDAC 0x95 /* double acute */
+#define DOGO 0x96 /* ogonek */
+#define DCAR 0x97 /* caron */
+#define L_ACC DCAR /* last accent key */
+
+#define STBY 0x98 /* Go into standby mode (apm) */
+#define PREV 0x99 /* switch to previous screen */
+
+#define F(x) ((x)+F_FN-1)
+#define S(x) ((x)+F_SCR-1)
+#define ACC(x) ((x)+F_ACC)
+
+struct acc_t {
+ u_char accchar;
+ u_char map[NUM_ACCENTCHARS][2];
+};
+
+struct accentmap {
+ u_short n_accs;
+ struct acc_t acc[NUM_DEADKEYS];
+};
+typedef struct accentmap accentmap_t;
+
+struct keyarg {
+ u_short keynum;
+ struct keyent_t key;
+};
+typedef struct keyarg keyarg_t;
+
+struct fkeytab {
+ u_char str[MAXFK];
+ u_char len;
+};
+typedef struct fkeytab fkeytab_t;
+
+struct fkeyarg {
+ u_short keynum;
+ char keydef[MAXFK];
+ char flen;
+};
+typedef struct fkeyarg fkeyarg_t;
+
+#define GETFKEY _IOWR('k', 0, fkeyarg_t)
+#define SETFKEY _IOWR('k', 1, fkeyarg_t)
+#if notdef /* see console.h */
+#define GIO_SCRNMAP _IOR('k', 2, scrmap_t)
+#define PIO_SCRNMAP _IOW('k', 3, scrmap_t)
+#endif
+#define GIO_KEYMAP _IOR('k', 6, keymap_t)
+#define PIO_KEYMAP _IOW('k', 7, keymap_t)
+#define GIO_DEADKEYMAP _IOR('k', 8, accentmap_t)
+#define PIO_DEADKEYMAP _IOW('k', 9, accentmap_t)
+#define GIO_KEYMAPENT _IOWR('k', 10, keyarg_t)
+#define PIO_KEYMAPENT _IOW('k', 11, keyarg_t)
+
+/* flags set to the return value in the KD_XLATE mode */
+
+#define NOKEY 0x100 /* no key pressed marker */
+#define FKEY 0x200 /* function key marker */
+#define MKEY 0x400 /* meta key marker (prepend ESC)*/
+#define BKEY 0x800 /* backtab (ESC [ Z) */
+
+#define SPCLKEY 0x8000 /* special key */
+#define RELKEY 0x4000 /* key released */
+#define ERRKEY 0x2000 /* error */
+
+#define KEYCHAR(c) ((c) & 0x00ff)
+#define KEYFLAGS(c) ((c) & ~0x00ff)
+
+#endif /* !_SYS_KBIO_H_ */
OpenPOWER on IntegriCloud