From 4f4eb0cfe54e001639240b3b63551c42280cdcc0 Mon Sep 17 00:00:00 2001 From: yokota Date: Tue, 22 Jun 1999 14:14:06 +0000 Subject: The second phase of syscons reorganization. - Split syscons source code into manageable chunks and reorganize some of complicated functions. - Many static variables are moved to the softc structure. - Added a new key function, PREV. When this key is pressed, the vty immediately before the current vty will become foreground. Analogue to PREV, which is usually assigned to the PrntScrn key. PR: kern/10113 Submitted by: Christian Weisgerber - Modified the kernel console input function sccngetc() so that it handles function keys properly. - Reorganized the screen update routine. - VT switching code is reorganized. It now should be slightly more robust than before. - Added the DEVICE_RESUME function so that syscons no longer hooks the APM resume event directly. - New kernel configuration options: SC_NO_CUTPASTE, SC_NO_FONT_LOADING, SC_NO_HISTORY and SC_NO_SYSMOUSE. Various parts of syscons can be omitted so that the kernel size is reduced. SC_PIXEL_MODE Made the VESA 800x600 mode an option, rather than a standard part of syscons. SC_DISABLE_DDBKEY Disables the `debug' key combination. SC_ALT_MOUSE_IMAGE Inverse the character cell at the mouse cursor position in the text console, rather than drawing an arrow on the screen. Submitted by: Nick Hibma (n_hibma@FreeBSD.ORG) SC_DFLT_FONT makeoptions "SC_DFLT_FONT=_font_name_" Include the named font as the default font of syscons. 16-line, 14-line and 8-line font data will be compiled in. This option replaces the existing STD8X16FONT option, which loads 16-line font data only. - The VGA driver is split into /sys/dev/fb/vga.c and /sys/isa/vga_isa.c. - The video driver provides a set of ioctl commands to manipulate the frame buffer. - New kernel configuration option: VGA_WIDTH90 Enables 90 column modes: 90x25, 90x30, 90x43, 90x50, 90x60. These modes are mot always supported by the video card. PR: i386/7510 Submitted by: kbyanc@freedomnet.com and alexv@sui.gda.itesm.mx. - The header file machine/console.h is reorganized; its contents is now split into sys/fbio.h, sys/kbio.h (a new file) and sys/consio.h (another new file). machine/console.h is still maintained for compatibility reasons. - Kernel console selection/installation routines are fixed and slightly rebumped so that it should now be possible to switch between the interanl kernel console (sc or vt) and a remote kernel console (sio) again, as it was in 2.x, 3.0 and 3.1. - Screen savers and splash screen decoders Because of the header file reorganization described above, screen savers and splash screen decoders are slightly modified. After this update, /sys/modules/syscons/saver.h is no longer necessary and is removed. --- sys/alpha/alpha/cons.c | 38 +- sys/alpha/conf/files.alpha | 7 +- sys/alpha/conf/options.alpha | 20 +- sys/alpha/include/cons.h | 12 +- sys/alpha/include/console.h | 638 +---- sys/conf/NOTES | 31 +- sys/conf/files.alpha | 7 +- sys/conf/files.i386 | 15 +- sys/conf/options.alpha | 20 +- sys/conf/options.i386 | 21 +- sys/dev/fb/fb.c | 473 +++- sys/dev/fb/fbreg.h | 65 +- sys/dev/fb/splash.c | 15 +- sys/dev/fb/splash_bmp.c | 5 +- sys/dev/fb/splash_pcx.c | 5 +- sys/dev/fb/splashreg.h | 5 +- sys/dev/fb/vga.c | 3041 +++++++++++++++++++++ sys/dev/fb/vgareg.h | 34 +- sys/dev/sio/sio.c | 15 +- sys/dev/syscons/blank/blank_saver.c | 71 +- sys/dev/syscons/daemon/daemon_saver.c | 103 +- sys/dev/syscons/fade/fade_saver.c | 69 +- sys/dev/syscons/fire/fire_saver.c | 9 +- sys/dev/syscons/green/green_saver.c | 82 +- sys/dev/syscons/logo/logo_saver.c | 10 +- sys/dev/syscons/rain/rain_saver.c | 8 +- sys/dev/syscons/scgfbrndr.c | 829 ++++++ sys/dev/syscons/schistory.c | 222 ++ sys/dev/syscons/scmouse.c | 1083 ++++++++ sys/dev/syscons/scvesactl.c | 9 +- sys/dev/syscons/scvgarndr.c | 829 ++++++ sys/dev/syscons/scvidctl.c | 474 +++- sys/dev/syscons/scvtb.c | 283 ++ sys/dev/syscons/snake/snake_saver.c | 56 +- sys/dev/syscons/star/star_saver.c | 49 +- sys/dev/syscons/syscons.c | 4249 +++++++++++++---------------- sys/dev/syscons/syscons.h | 411 ++- sys/dev/syscons/warp/warp_saver.c | 9 +- sys/i386/conf/LINT | 31 +- sys/i386/conf/NOTES | 31 +- sys/i386/conf/files.i386 | 15 +- sys/i386/conf/options.i386 | 21 +- sys/i386/i386/cons.c | 17 +- sys/i386/i386/cons.h | 13 +- sys/i386/include/console.h | 637 +---- sys/i386/isa/pcvt/pcvt_drv.c | 9 +- sys/i386/isa/vesa.c | 668 ++++- sys/isa/sio.c | 15 +- sys/isa/syscons_isa.c | 170 +- sys/isa/vga_isa.c | 2129 +-------------- sys/kern/tty_cons.c | 17 +- sys/modules/splash/bmp/splash_bmp.c | 5 +- sys/modules/splash/pcx/splash_pcx.c | 5 +- sys/modules/syscons/blank/blank_saver.c | 71 +- sys/modules/syscons/daemon/daemon_saver.c | 103 +- sys/modules/syscons/fade/fade_saver.c | 69 +- sys/modules/syscons/fire/fire_saver.c | 9 +- sys/modules/syscons/green/green_saver.c | 82 +- sys/modules/syscons/logo/logo_saver.c | 10 +- sys/modules/syscons/rain/rain_saver.c | 8 +- sys/modules/syscons/saver.h | 39 - sys/modules/syscons/snake/snake_saver.c | 56 +- sys/modules/syscons/star/star_saver.c | 49 +- sys/modules/syscons/warp/warp_saver.c | 9 +- sys/sys/cons.h | 13 +- sys/sys/consio.h | 385 +++ sys/sys/fbio.h | 289 +- sys/sys/kbio.h | 228 ++ 68 files changed, 11803 insertions(+), 6722 deletions(-) create mode 100644 sys/dev/fb/vga.c create mode 100644 sys/dev/syscons/scgfbrndr.c create mode 100644 sys/dev/syscons/schistory.c create mode 100644 sys/dev/syscons/scmouse.c create mode 100644 sys/dev/syscons/scvgarndr.c create mode 100644 sys/dev/syscons/scvtb.c delete mode 100644 sys/modules/syscons/saver.h create mode 100644 sys/sys/consio.h create mode 100644 sys/sys/kbio.h (limited to 'sys') 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 #include -/* 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 -#endif -#include - -#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 +#include +#include #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 #include #include +#include #include #include +#include +#include -#include +#include +#include #include @@ -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 #include #include - -#include +#include #include #include @@ -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 #include #include #include - -#include +#include #include #include 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 #include #include #include - -#include +#include #include #include 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 + * 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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include + +#include + +#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 +#include + +#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(¶ms); + /* 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(¶ms); + /* 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(¶ms); + /* 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(¶ms); + /* 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(¶ms); + /* 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, ¶ms); + 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, ¶ms); + 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 #include #include #include +#include +#include -#include - -#include - -#include +#include +#include +#include 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 @@ -34,21 +34,20 @@ #include #include #include +#include +#include -#include #include -#include - -#define CONSOLE_VECT(x, y) \ - (window + (y)*cur_console->xsize + (x)) +#include +#include +#include #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 #include #include #include +#include +#include -#include - -#include +#include +#include +#include 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 #include #include +#include +#include -#include #include -#include +#include +#include +#include #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 #include #include #include +#include +#include -#include - -#include - -#include +#include +#include +#include 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 @@ -33,8 +33,12 @@ #include #include #include +#include +#include -#include +#include +#include +#include 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 @@ -33,10 +33,14 @@ #include #include #include +#include +#include #include -#include +#include +#include +#include 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 + * 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 +#include +#include + +#include +#include + +#include +#include +#include + +#include + +#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 + * 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 +#include +#include +#include +#include + +#include + +#include + +#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 + * 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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#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 #include -#include #include #include @@ -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 + * 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 +#include +#include + +#include +#include + +#include +#include +#include + +#include + +#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 #include -#ifdef __i386__ -#include -#endif +#include +#include + #include #include #include /* 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 + * 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 +#include +#include +#include + +#include +#include + +#include +#include + +#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 @@ -34,16 +34,18 @@ #include #include #include +#include +#include -#include #include -#include +#include +#include +#include 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 #include #include #include +#include +#include -#include #include -#include +#include +#include +#include #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; iscr, 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 @@ -54,308 +51,158 @@ #include #endif -#include #include #include #include -#include -#include #include -#include #include #ifdef __i386__ -#include #include +#include #include #endif -#include -#include -#include - #include #include -#include #include #include -#ifndef __i386__ -#include -#else -#include -#include -#include -#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; + +static void none_saver(sc_softc_t *sc, int blank) { } +static void (*current_saver)(sc_softc_t *, int) = none_saver; - u_char font_8[256*8]; - u_char font_14[256*14]; -#ifdef STD8X16FONT -extern +#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)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,483 +769,66 @@ 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; + sc->flags |= SC_QUIET_BELL; else - sc_flags &= ~QUIET_BELL; + sc->flags &= ~SC_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; - } - else - return EINVAL; - - case CONS_MOUSECTL: /* control mouse arrow */ - case OLD_CONS_MOUSECTL: + case CONS_GETINFO: /* get current (virtual) console info */ { - /* 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; - } + vid_info_t *ptr = (vid_info_t*)data; + if (ptr->size == sizeof(struct vid_info)) { + ptr->m_num = sc->cur_scp->index; + ptr->mv_col = scp->xpos; + ptr->mv_row = scp->ypos; + ptr->mv_csz = scp->xsize; + ptr->mv_rsz = scp->ysize; + ptr->mv_norm.fore = (scp->term.std_color & 0x0f00)>>8; + ptr->mv_norm.back = (scp->term.std_color & 0xf000)>>12; + ptr->mv_rev.fore = (scp->term.rev_color & 0x0f00)>>8; + ptr->mv_rev.back = (scp->term.rev_color & 0xf000)>>12; + ptr->mv_grfc.fore = 0; /* not supported */ + ptr->mv_grfc.back = 0; /* not supported */ + ptr->mv_ovscan = scp->border; + if (scp == sc->cur_scp) + save_kbd_state(scp); + ptr->mk_keylock = scp->status & LOCK_MASK; + return 0; } + 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; - 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->mv_col = scp->xpos; - ptr->mv_row = scp->ypos; - ptr->mv_csz = scp->xsize; - ptr->mv_rsz = scp->ysize; - ptr->mv_norm.fore = (scp->term.std_color & 0x0f00)>>8; - ptr->mv_norm.back = (scp->term.std_color & 0xf000)>>12; - ptr->mv_rev.fore = (scp->term.rev_color & 0x0f00)>>8; - ptr->mv_rev.back = (scp->term.rev_color & 0xf000)>>12; - ptr->mv_grfc.fore = 0; /* not supported */ - ptr->mv_grfc.back = 0; /* not supported */ - ptr->mv_ovscan = scp->border; - if (scp == cur_console) - save_kbd_state(scp); - ptr->mk_keylock = scp->status & LOCK_MASK; - return 0; - } - return EINVAL; - } - - case CONS_GETVERS: /* get version number */ - *(int*)data = 0x200; /* version 2.0 */ - return 0; + case CONS_GETVERS: /* get version number */ + *(int*)data = 0x200; /* version 2.0 */ + return 0; case CONS_IDLE: /* see if the screen has been idle */ /* @@ -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; iscr_map, sizeof(sc->scr_map)); + for (i=0; iscr_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(); + + /* 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; + } - if (next_scr >= MAXCONS || switch_in_progress || - (cur_console->smode.mode == VT_AUTO && ISGRAPHSC(cur_console))) { - do_bell(scp, BELL_PITCH, BELL_DURATION); + /* + * 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,228 +3036,465 @@ 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) { - video_adapter_t *adp; - int col; - int row; - u_int i; - - if (init_done != COLD) - return; - init_done = WARM; - - get_bios_values(); - - /* 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); - - /* 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; iadp->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); - } - /* - * FONT KLUDGE - * Always use the font page #0. XXX - */ - (*vidsw[cur_console->ad]->show_font)(cur_console->adp, 0); - } - save_palette(cur_console->adp, palette); - -#if NSPLASH > 0 - /* we are ready to put up the splash image! */ - splash_init(cur_console->adp, scsplash_callback); -#endif + /* 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 -scshutdown(int howto, void *arg) +remove_cursor_image(scr_stat *scp) { - sc_touch_scrn_saver(); - if (!cold && cur_console->smode.mode == VT_AUTO - && console[0]->smode.mode == VT_AUTO) - switch_scr(cur_console, 0); - shutdown_in_progress = TRUE; + /* 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; } -int -sc_clean_up(scr_stat *scp) +static void +update_cursor_image(scr_stat *scp) { - int error; + int blink; - sc_touch_scrn_saver(); - if ((error = wait_scrn_saver_stop())) - return error; - scp->status &= ~MOUSE_VISIBLE; - remove_cutmarking(scp); - return 0; + 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_alloc_scr_buffer(scr_stat *scp, int wait, int clear) +sc_set_cursor_image(scr_stat *scp) { - 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); - - if (clear) { - /* clear the screen and move the text cursor to the top-left position */ - sc_clear_screen(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 { - /* retain the current cursor position, but adjust pointers */ - move_crsr(scp, scp->xpos, scp->ypos); - scp->cursor_oldpos = scp->cursor_pos; + scp->cursor_base = 0; + scp->cursor_height = scp->font_size; } - /* move the mouse cursor at the center of the screen */ - sc_move_mouse(scp, scp->xpixel / 2, scp->ypixel / 2); + /* 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; } -void -sc_alloc_cut_buffer(scr_stat *scp, int wait) +static void +move_crsr(scr_stat *scp, int x, int y) { - 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'; - } + 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; } -void -sc_alloc_history_buffer(scr_stat *scp, int lines, int extra, int wait) +static void +scinit(int unit, int flags) { - u_short *usp; - - if (lines < scp->ysize) - lines = scp->ysize; + /* + * 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 - usp = scp->history; - scp->history = NULL; - if (usp != NULL) { - free(usp, M_DEVBUF); - if (extra > 0) - extra_history_size += extra; + sc_softc_t *sc; + scr_stat *scp; + video_adapter_t *adp; + int col; + int row; + int i; + + /* 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; + + /* + * 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 */ + (*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 */ + 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); + } + + /* 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 */ - 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; +#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; + } +#endif /* NSPLASH */ + } + + /* 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 + /* 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 && 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; +} + +int +sc_clean_up(scr_stat *scp) +{ + int error; + + sc_touch_scrn_saver(); +#if NSPLASH > 0 + if ((error = wait_scrn_saver_stop(scp->sc))) + return error; +#endif /* NSPLASH */ + scp->status &= ~MOUSE_VISIBLE; + sc_remove_cutmarking(scp); + return 0; +} + +void +sc_alloc_scr_buffer(scr_stat *scp, int wait, int discard) +{ + sc_vtb_t new; + sc_vtb_t old; + int s; + + 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); + splx(s); + sc_vtb_destroy(&old); + } + +#ifndef SC_NO_SYSMOUSE + /* move the mouse cursor at the center of the screen */ + 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; iysize; 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; iysize; 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; iysize; i++) - if (history_up_line(cur_console)) { + sc_remove_cutmarking(scp); + for (i=0; iysize; 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; iysize; i++) - if (history_down_line(cur_console)) { + sc_remove_cutmarking(scp); + for (i=0; iysize; 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; iysize; 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(cur_console, i); + 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(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) -{ - 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; istatus & 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) +sc_paste(scr_stat *scp, u_char *p, int count) { - 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; imouse_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); + 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); } - for (i=0; imouse_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); - } -} - -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 +#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 @@ -33,11 +33,14 @@ #include #include #include +#include +#include -#include #include -#include +#include +#include +#include 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 -#endif -#include - -#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 +#include +#include #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 #include #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 #include #include +#include + #include +#include +#include #include -#include #include #include #include @@ -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 #include +#include #include + #ifdef __i386__ -#include -#endif + +#include +#include +#include + +#include +#include + +#include + +#define BIOS_CLKED (1 << 6) +#define BIOS_NLKED (1 << 5) +#define BIOS_SLKED (1 << 4) +#define BIOS_ALKED 0 + +#endif /* __i386__ */ #include #include #include -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 - * 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 #include #include +#include #include -#include +#include + +#include +#include + +#include #include #include -#include #include #include @@ -55,21 +57,10 @@ #include #include -#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 -#include - -#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, ¶ms); - 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, ¶ms); - 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 #include #include #include - -#include +#include #include #include 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 #include #include #include - -#include +#include #include #include 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 #include #include #include +#include +#include -#include - -#include - -#include +#include +#include +#include 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 @@ -34,21 +34,20 @@ #include #include #include +#include +#include -#include #include -#include - -#define CONSOLE_VECT(x, y) \ - (window + (y)*cur_console->xsize + (x)) +#include +#include +#include #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 #include #include #include +#include +#include -#include - -#include +#include +#include +#include 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 #include #include +#include +#include -#include #include -#include +#include +#include +#include #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 #include #include #include +#include +#include -#include - -#include - -#include +#include +#include +#include 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 @@ -33,8 +33,12 @@ #include #include #include +#include +#include -#include +#include +#include +#include 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 @@ -33,10 +33,14 @@ #include #include #include +#include +#include #include -#include +#include +#include +#include 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 -#include - -#include -#include - -#include - -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 @@ -34,16 +34,18 @@ #include #include #include +#include +#include -#include #include -#include +#include +#include +#include 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 #include #include #include +#include +#include -#include #include -#include +#include +#include +#include #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; iscr, 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 @@ -33,11 +33,14 @@ #include #include #include +#include +#include -#include #include -#include +#include +#include +#include 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 +#endif +#include + +/* + * 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 +#endif +#include + /* * 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 +#endif +#include + +/* 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_ */ -- cgit v1.1