diff options
Diffstat (limited to 'sys')
68 files changed, 11762 insertions, 6681 deletions
diff --git a/sys/alpha/alpha/cons.c b/sys/alpha/alpha/cons.c index 161fecf..7194a33 100644 --- a/sys/alpha/alpha/cons.c +++ b/sys/alpha/alpha/cons.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * from: @(#)cons.c 7.2 (Berkeley) 5/9/91 - * $Id: cons.c,v 1.9 1999/05/31 11:23:35 phk Exp $ + * $Id: cons.c,v 1.10 1999/06/01 20:26:04 dt Exp $ */ #include "opt_devfs.h" @@ -57,25 +57,6 @@ #include <machine/cpu.h> #include <machine/cons.h> -/* XXX this should be config(8)ed. */ -#if 0 -#include "sc.h" -#include "vt.h" -#include "sio.h" -#endif -static struct consdev constab[] = { -#if NSC > 0 - { sccnprobe, sccninit, sccngetc, sccncheckc, sccnputc }, -#endif -#if NVT > 0 - { pccnprobe, pccninit, pccngetc, pccncheckc, pccnputc }, -#endif -#if NSIO > 0 - { siocnprobe, siocninit, siocngetc, siocncheckc, siocnputc }, -#endif - { 0 }, -}; - static d_open_t cnopen; static d_close_t cnclose; static d_read_t cnread; @@ -129,16 +110,22 @@ static struct tty *cn_tp; /* physical console tty struct */ static void *cn_devfs_token; /* represents the devfs entry */ #endif /* DEVFS */ +CONS_DRIVER(cons, NULL, NULL, NULL, NULL, NULL, NULL); + void cninit() { struct consdev *best_cp, *cp; + struct consdev **list; /* * Find the first console with the highest priority. */ best_cp = NULL; - for (cp = constab; cp->cn_probe; cp++) { + list = (struct consdev **)cons_set.ls_items; + while ((cp = *list++) != NULL) { + if (cp->cn_probe == NULL) + continue; (*cp->cn_probe)(cp); if (cp->cn_pri > CN_DEAD && (best_cp == NULL || cp->cn_pri > best_cp->cn_pri)) @@ -161,6 +148,8 @@ cninit() * If no console, give up. */ if (best_cp == NULL) { + if (cn_tab != NULL && cn_tab->cn_term != NULL) + (*cn_tab->cn_term)(cn_tab); cn_tab = best_cp; return; } @@ -168,10 +157,13 @@ cninit() /* * Initialize console, then attach to it. This ordering allows * debugging using the previous console, if any. - * XXX if there was a previous console, then its driver should - * be informed when we forget about it. */ (*best_cp->cn_init)(best_cp); + if (cn_tab != NULL && cn_tab != best_cp) { + /* Turn off the previous console. */ + if (cn_tab->cn_term != NULL) + (*cn_tab->cn_term)(cn_tab); + } cn_tab = best_cp; } diff --git a/sys/alpha/conf/files.alpha b/sys/alpha/conf/files.alpha index 112d8f8..fb69c9a 100644 --- a/sys/alpha/conf/files.alpha +++ b/sys/alpha/conf/files.alpha @@ -1,7 +1,7 @@ # This file tells config what files go into building a kernel, # files marked standard are always included. # -# $Id: files.alpha,v 1.20 1999/06/05 13:29:57 dfr Exp $ +# $Id: files.alpha,v 1.21 1999/06/19 13:12:51 dfr Exp $ # # The long compile-with and dependency lines are required because of # limitations in config: backslash-newline doesn't work in strings, and @@ -152,6 +152,7 @@ libkern/alpha/ntohs.S standard isa/sio.c optional sio device-driver dev/fb/fb.c optional fb device-driver dev/fb/fb.c optional vga device-driver +dev/fb/vga.c optional vga device-driver isa/vga_isa.c optional vga device-driver dev/fb/splash.c optional splash dev/kbd/atkbd.c optional atkbd device-driver @@ -162,7 +163,11 @@ dev/kbd/kbd.c optional atkbd device-driver dev/kbd/kbd.c optional kbd device-driver dev/kbd/kbd.c optional ukbd device-driver dev/syscons/syscons.c optional sc device-driver +dev/syscons/schistory.c optional sc device-driver +dev/syscons/scmouse.c optional sc device-driver +dev/syscons/scvgarndr.c optional sc device-driver dev/syscons/scvidctl.c optional sc device-driver +dev/syscons/scvtb.c optional sc device-driver isa/syscons_isa.c optional sc device-driver isa/psm.c optional psm device-driver isa/fd.c optional fd device-driver diff --git a/sys/alpha/conf/options.alpha b/sys/alpha/conf/options.alpha index 9c8e8e1..d78c220 100644 --- a/sys/alpha/conf/options.alpha +++ b/sys/alpha/conf/options.alpha @@ -1,4 +1,4 @@ -# $Id: options.alpha,v 1.10 1999/03/10 10:36:50 yokota Exp $ +# $Id: options.alpha,v 1.11 1999/05/27 22:03:31 gallatin Exp $ EV5 opt_global.h EV4 opt_global.h @@ -21,25 +21,35 @@ CMD640 opt_wd.h SHOW_BUSYBUFS PANIC_REBOOT_WAIT_TIME opt_panic.h -SC_SPLASH_SCREEN opt_syscons.h MAXCONS opt_syscons.h -SLOW_VGA opt_syscons.h -STD8X16FONT opt_syscons.h -SC_HISTORY_SIZE opt_syscons.h +SC_ALT_MOUSE_IMAGE opt_syscons.h +SC_DEBUG_LEVEL opt_syscons.h +SC_DFLT_FONT opt_syscons.h +SC_DISABLE_DDB opt_syscons.h SC_DISABLE_REBOOT opt_syscons.h +SC_HISTORY_SIZE opt_syscons.h SC_MOUSE_CHAR opt_syscons.h +SC_NO_CUTPASTE opt_syscons.h +SC_NO_FONT_LOADING opt_syscons.h +SC_NO_HISTORY opt_syscons.h +SC_NO_SYSMOUSE opt_syscons.h +SC_PIXEL_MODE opt_syscons.h +SC_RENDER_DEBUG opt_syscons.h +SC_VIDEO_DEBUG opt_syscons.h VGA_ALT_SEQACCESS opt_vga.h VGA_DEBUG opt_vga.h VGA_NO_FONT_LOADING opt_vga.h VGA_NO_MODE_CHANGE opt_vga.h VGA_SLOW_IOACCESS opt_vga.h +VGA_WIDTH90 opt_vga.h PSM_HOOKAPM opt_psm.h PSM_RESETAFTERSUSPEND opt_psm.h PSM_DEBUG opt_psm.h # Fb options +FB_DEBUG opt_fb.h FB_INSTALL_CDEV opt_fb.h # Atkbd options diff --git a/sys/alpha/include/cons.h b/sys/alpha/include/cons.h index 057a2fa..fdc0da0 100644 --- a/sys/alpha/include/cons.h +++ b/sys/alpha/include/cons.h @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * from: @(#)cons.h 7.2 (Berkeley) 5/9/91 - * $Id: cons.h,v 1.1 1998/06/10 10:54:42 dfr Exp $ + * $Id: cons.h,v 1.2 1999/01/23 16:53:27 dfr Exp $ */ #ifndef _MACHINE_CONS_H_ @@ -45,6 +45,7 @@ struct consdev; typedef void cn_probe_t __P((struct consdev *)); typedef void cn_init_t __P((struct consdev *)); +typedef void cn_term_t __P((struct consdev *)); typedef int cn_getc_t __P((dev_t)); typedef int cn_checkc_t __P((dev_t)); typedef void cn_putc_t __P((dev_t, int)); @@ -66,6 +67,8 @@ struct consdev { /* probe hardware and fill in consdev info */ cn_init_t *cn_init; /* turn on as console */ + cn_term_t *cn_term; + /* turn off as console */ cn_getc_t *cn_getc; /* kernel getchar interface */ cn_checkc_t *cn_checkc; @@ -84,8 +87,15 @@ struct consdev { #define CN_REMOTE 3 /* serial interface with remote bit set */ #ifdef KERNEL +extern struct linker_set cons_set; extern int cons_unavail; +#define CONS_DRIVER(name, probe, init, term, getc, checkc, putc) \ + static struct consdev name##_consdev = { \ + probe, init, term, getc, checkc, putc \ + }; \ + DATA_SET(cons_set, name##_consdev) + /* Other kernel entry points. */ int cncheckc __P((void)); int cngetc __P((void)); diff --git a/sys/alpha/include/console.h b/sys/alpha/include/console.h index 9521dfa..79a6b57 100644 --- a/sys/alpha/include/console.h +++ b/sys/alpha/include/console.h @@ -1,636 +1,8 @@ -/*- - * Copyright (c) 1991-1996 Søren Schmidt - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $Id: console.h,v 1.43 1999/02/05 11:51:56 yokota Exp $ - * from: i386/include console.h,v 1.43 - */ +#ifndef _MACHINE_CONSOLE_H_ +#define _MACHINE_CONSOLE_H_ -#ifndef _MACHINE_CONSOLE_H_ -#define _MACHINE_CONSOLE_H_ - -#ifndef KERNEL -#include <sys/types.h> -#endif -#include <sys/ioccom.h> - -#define KDGKBMODE _IOR('K', 6, int) -#define KDSKBMODE _IO('K', 7 /*, int */) -#define KDMKTONE _IO('K', 8 /*, int */) -#define KDGETMODE _IOR('K', 9, int) -#define KDSETMODE _IO('K', 10 /*, int */) -#define KDSBORDER _IO('K', 13 /*, int */) -#define KDGKBSTATE _IOR('K', 19, int) -#define KDSKBSTATE _IO('K', 20 /*, int */) -#define KDENABIO _IO('K', 60) -#define KDDISABIO _IO('K', 61) -#define KIOCSOUND _IO('K', 63 /*, int */) -#define KDGKBTYPE _IOR('K', 64, int) -#define KDGETLED _IOR('K', 65, int) -#define KDSETLED _IO('K', 66 /*, int */) -#define KDSETRAD _IO('K', 67 /*, int */) /* obsolete */ -#define KDRASTER _IOW('K', 100, scr_size_t) -#define KDGKBINFO _IOR('K', 101, keyboard_info_t) -#define KDSETREPEAT _IOW('K', 102, keyboard_delay_t) - -#define GETFKEY _IOWR('k', 0, fkeyarg_t) -#define SETFKEY _IOWR('k', 1, fkeyarg_t) -#define GIO_SCRNMAP _IOR('k', 2, scrmap_t) -#define PIO_SCRNMAP _IOW('k', 3, scrmap_t) -#define GIO_KEYMAP _IOR('k', 6, keymap_t) -#define PIO_KEYMAP _IOW('k', 7, keymap_t) -#define GIO_DEADKEYMAP _IOR('k', 8, accentmap_t) -#define PIO_DEADKEYMAP _IOW('k', 9, accentmap_t) -#define GIO_KEYMAPENT _IOWR('k', 10, keyarg_t) -#define PIO_KEYMAPENT _IOW('k', 11, keyarg_t) - -#define GIO_ATTR _IOR('a', 0, int) -#define GIO_COLOR _IOR('c', 0, int) -#define CONS_CURRENT _IOR('c', 1, int) -#define CONS_GET _IOR('c', 2, int) -#define CONS_IO _IO('c', 3) -#define CONS_BLANKTIME _IOW('c', 4, int) -#define CONS_SSAVER _IOW('c', 5, ssaver_t) -#define CONS_GSAVER _IOWR('c', 6, ssaver_t) -#define CONS_CURSORTYPE _IOW('c', 7, int) -#define CONS_BELLTYPE _IOW('c', 8, int) -#define CONS_HISTORY _IOW('c', 9, int) -#define CONS_MOUSECTL _IOWR('c', 10, mouse_info_t) -#define CONS_IDLE _IOR('c', 11, int) -#define CONS_SAVERMODE _IOW('c', 12, int) -#define CONS_SAVERSTART _IOW('c', 13, int) -#define PIO_FONT8x8 _IOW('c', 64, fnt8_t) -#define GIO_FONT8x8 _IOR('c', 65, fnt8_t) -#define PIO_FONT8x14 _IOW('c', 66, fnt14_t) -#define GIO_FONT8x14 _IOR('c', 67, fnt14_t) -#define PIO_FONT8x16 _IOW('c', 68, fnt16_t) -#define GIO_FONT8x16 _IOR('c', 69, fnt16_t) -#define CONS_GETINFO _IOWR('c', 73, vid_info_t) -#define CONS_GETVERS _IOR('c', 74, int) -#define CONS_CURRENTADP _IOR('c', 100, int) -#define CONS_ADPINFO _IOWR('c', 101, video_adapter_info_t) -#define CONS_MODEINFO _IOWR('c', 102, video_info_t) -#define CONS_FINDMODE _IOWR('c', 103, video_info_t) -#define CONS_SETWINORG _IO('c', 104 /* u_int */) - -#define CONS_SETKBD _IO('c', 110 /* int */) -#define CONS_RELKBD _IO('c', 111) - -/* CONS_SAVERMODE */ -#define CONS_LKM_SAVER 0 -#define CONS_USR_SAVER 1 - -#ifdef PC98 -#define ADJUST_CLOCK _IO('t',100) /* for 98note resume */ -#endif - -#define VT_OPENQRY _IOR('v', 1, int) -#define VT_SETMODE _IOW('v', 2, vtmode_t) -#define VT_GETMODE _IOR('v', 3, vtmode_t) -#define VT_RELDISP _IO('v', 4 /*, int */) -#define VT_ACTIVATE _IO('v', 5 /*, int */) -#define VT_WAITACTIVE _IO('v', 6 /*, int */) -#define VT_GETACTIVE _IOR('v', 7, int) - -#define VT_FALSE 0 -#define VT_TRUE 1 -#define VT_ACKACQ 2 - -#define VT_AUTO 0 /* switching is automatic */ -#define VT_PROCESS 1 /* switching controlled by prog */ -#define VT_KERNEL 255 /* switching controlled in kernel */ - -#ifndef _VT_MODE_DECLARED -#define _VT_MODE_DECLARED -struct vt_mode { - char mode; - char waitv; /* not implemented yet SOS */ - short relsig; - short acqsig; - short frsig; /* not implemented yet SOS */ -}; - -typedef struct vt_mode vtmode_t; -#endif /* !_VT_MODE_DECLARED */ - -struct mouse_data { - int x; - int y; - int z; - int buttons; -}; - -struct mouse_mode { - int mode; - int signal; -}; - -struct mouse_event { - int id; /* one based */ - int value; -}; - -#define MOUSE_SHOW 0x01 -#define MOUSE_HIDE 0x02 -#define MOUSE_MOVEABS 0x03 -#define MOUSE_MOVEREL 0x04 -#define MOUSE_GETINFO 0x05 -#define MOUSE_MODE 0x06 -#define MOUSE_ACTION 0x07 -#define MOUSE_MOTION_EVENT 0x08 -#define MOUSE_BUTTON_EVENT 0x09 - -struct mouse_info { - int operation; - union { - struct mouse_data data; - struct mouse_mode mode; - struct mouse_event event; - }u; -}; - -#define KD_MONO 1 /* monochrome adapter */ -#define KD_HERCULES 2 /* hercules adapter */ -#define KD_CGA 3 /* color graphics adapter */ -#define KD_EGA 4 /* enhanced graphics adapter */ -#define KD_VGA 5 /* video graphics adapter */ -#define KD_PC98 6 /* PC-98 display */ - -#define KD_TEXT 0 /* set text mode restore fonts */ -#define KD_TEXT0 0 /* ditto */ -#define KD_TEXT1 2 /* set text mode !restore fonts */ -#define KD_GRAPHICS 1 /* set graphics mode */ -#define KD_PIXEL 3 /* set pixel mode */ - -#define K_RAW 0 /* keyboard returns scancodes */ -#define K_XLATE 1 /* keyboard returns ascii */ -#define K_CODE 2 /* keyboard returns keycodes */ - -#define KB_84 1 /* 'old' 84 key AT-keyboard */ -#define KB_101 2 /* MF-101 or MF-102 keyboard */ -#define KB_OTHER 3 /* keyboard not known */ - -#define CLKED 1 /* Caps locked */ -#define NLKED 2 /* Num locked */ -#define SLKED 4 /* Scroll locked */ -#define ALKED 8 /* AltGr locked */ -#define LOCK_MASK (CLKED | NLKED | SLKED | ALKED) -#define LED_CAP 1 /* Caps lock LED */ -#define LED_NUM 2 /* Num lock LED */ -#define LED_SCR 4 /* Scroll lock LED */ -#define LED_MASK (LED_CAP | LED_NUM | LED_SCR) - -/* possible flag values */ -#define FLAG_LOCK_O 0 -#define FLAG_LOCK_C 1 -#define FLAG_LOCK_N 2 - -#define NUM_KEYS 256 /* number of keys in table */ -#define NUM_STATES 8 /* states per key */ -#define ALTGR_OFFSET 128 /* offset for altlock keys */ - -#ifndef _KEYMAP_DECLARED -#define _KEYMAP_DECLARED -struct keyent_t { - u_char map[NUM_STATES]; - u_char spcl; - u_char flgs; -}; - -struct keymap { - u_short n_keys; - struct keyent_t key[NUM_KEYS]; -}; - -typedef struct keymap keymap_t; - -struct keyarg { - u_short keynum; - struct keyent_t key; -}; - -typedef struct keyarg keyarg_t; -#endif /* !_KEYMAP_DECLARED */ - -#define NUM_DEADKEYS 15 /* number of accent keys */ -#define NUM_ACCENTCHARS 52 /* max number of accent chars */ - -struct acc_t { - u_char accchar; - u_char map[NUM_ACCENTCHARS][2]; -}; - -struct accentmap { - u_short n_accs; - struct acc_t acc[NUM_DEADKEYS]; -}; - -#define MAXFK 16 -#define NUM_FKEYS 96 - -struct fkeytab { - u_char str[MAXFK]; - u_char len; -}; - -struct fkeyarg { - u_short keynum; - char keydef[MAXFK]; - char flen; -}; - -struct colors { - char fore; - char back; -}; - -struct vid_info { - short size; - short m_num; - u_short mv_row, mv_col; - u_short mv_rsz, mv_csz; - struct colors mv_norm, - mv_rev, - mv_grfc; - u_char mv_ovscan; - u_char mk_keylock; -}; - -#define MAXSSAVER 16 - -struct ssaver { - char name[MAXSSAVER]; - int num; - long time; -}; - -/* video mode information block */ -struct video_info { - int vi_mode; - int vi_flags; -#define V_INFO_COLOR (1<<0) -#define V_INFO_GRAPHICS (1<<1) -#define V_INFO_LINEAR (1<<2) -#define V_INFO_VESA (1<<3) - int vi_width; - int vi_height; - int vi_cwidth; - int vi_cheight; - int vi_depth; - int vi_planes; - u_int vi_window; /* physical address */ - size_t vi_window_size; - size_t vi_window_gran; - u_int vi_buffer; /* physical address */ - size_t vi_buffer_size; - /* XXX pixel format, memory model,... */ -}; - -/* adapter infromation block */ -struct video_adapter { - int va_index; - int va_type; - char *va_name; - int va_unit; - int va_minor; - int va_flags; -#define V_ADP_COLOR (1<<0) -#define V_ADP_MODECHANGE (1<<1) -#define V_ADP_STATESAVE (1<<2) -#define V_ADP_STATELOAD (1<<3) -#define V_ADP_FONT (1<<4) -#define V_ADP_PALETTE (1<<5) -#define V_ADP_BORDER (1<<6) -#define V_ADP_VESA (1<<7) -#define V_ADP_PROBED (1<<16) -#define V_ADP_INITIALIZED (1<<17) -#define V_ADP_REGISTERED (1<<18) - int va_io_base; - int va_io_size; - int va_crtc_addr; - int va_mem_base; - int va_mem_size; - u_int va_window; /* virtual address */ - size_t va_window_size; - size_t va_window_gran; - u_int va_buffer; /* virtual address */ - size_t va_buffer_size; - int va_initial_mode; - int va_initial_bios_mode; - int va_mode; - struct video_info va_info; - int va_line_width; - void *va_token; -}; - -struct video_adapter_info { - int va_index; - int va_type; - char va_name[16]; - int va_unit; - int va_flags; - int va_io_base; - int va_io_size; - int va_crtc_addr; - int va_mem_base; - int va_mem_size; - u_int va_window; /* virtual address */ - size_t va_window_size; - size_t va_window_gran; - u_int va_buffer; /* virtual address */ - size_t va_buffer_size; - int va_initial_mode; - int va_initial_bios_mode; - int va_mode; - int va_line_width; -}; - -#define V_ADP_PRIMARY 0 -#define V_ADP_SECONDARY 1 - -struct keyboard_info { - int kb_index; /* kbdio index# */ - char kb_name[16]; /* driver name */ - int kb_unit; /* unit# */ - int kb_type; /* KB_84, KB_101, KB_OTHER,... */ - int kb_config; /* device configuration flags */ - int kb_flags; /* internal flags */ -}; - -typedef struct accentmap accentmap_t; -typedef struct fkeytab fkeytab_t; -typedef struct fkeyarg fkeyarg_t; -typedef struct vid_info vid_info_t; -typedef struct mouse_info mouse_info_t; -typedef struct {char scrmap[256];} scrmap_t; -typedef struct {char fnt8x8[8*256];} fnt8_t; -typedef struct {char fnt8x14[14*256];} fnt14_t; -typedef struct {char fnt8x16[16*256];} fnt16_t; -typedef struct ssaver ssaver_t; -typedef struct video_adapter video_adapter_t; -typedef struct video_adapter_info video_adapter_info_t; -typedef struct video_info video_info_t; -typedef struct keyboard_info keyboard_info_t; -typedef struct {int scr_size[3];} scr_size_t; -typedef struct {int kbd_delay[2];} keyboard_delay_t; - -/* defines for "special" keys (spcl bit set in keymap) */ -#define NOP 0x00 /* nothing (dead key) */ -#define LSH 0x02 /* left shift key */ -#define RSH 0x03 /* right shift key */ -#define CLK 0x04 /* caps lock key */ -#define NLK 0x05 /* num lock key */ -#define SLK 0x06 /* scroll lock key */ -#define LALT 0x07 /* left alt key */ -#define BTAB 0x08 /* backwards tab */ -#define LCTR 0x09 /* left control key */ -#define NEXT 0x0a /* switch to next screen */ -#define F_SCR 0x0b /* switch to first screen */ -#define L_SCR 0x1a /* switch to last screen */ -#define F_FN 0x1b /* first function key */ -#define L_FN 0x7a /* last function key */ -/* 0x7b-0x7f reserved do not use ! */ -#define RCTR 0x80 /* right control key */ -#define RALT 0x81 /* right alt (altgr) key */ -#define ALK 0x82 /* alt lock key */ -#define ASH 0x83 /* alt shift key */ -#define META 0x84 /* meta key */ -#define RBT 0x85 /* boot machine */ -#define DBG 0x86 /* call debugger */ -#define SUSP 0x87 /* suspend power (APM) */ -#define SPSC 0x88 /* toggle splash/text screen */ - -#define F_ACC DGRA /* first accent key */ -#define DGRA 0x89 /* grave */ -#define DACU 0x8a /* acute */ -#define DCIR 0x8b /* circumflex */ -#define DTIL 0x8c /* tilde */ -#define DMAC 0x8d /* macron */ -#define DBRE 0x8e /* breve */ -#define DDOT 0x8f /* dot */ -#define DUML 0x90 /* umlaut/diaresis */ -#define DDIA 0x90 /* diaresis */ -#define DSLA 0x91 /* slash */ -#define DRIN 0x92 /* ring */ -#define DCED 0x93 /* cedilla */ -#define DAPO 0x94 /* apostrophe */ -#define DDAC 0x95 /* double acute */ -#define DOGO 0x96 /* ogonek */ -#define DCAR 0x97 /* caron */ -#define L_ACC DCAR /* last accent key */ - -#define STBY 0x98 /* Go into standby mode (apm) */ - -#define F(x) ((x)+F_FN-1) -#define S(x) ((x)+F_SCR-1) -#define ACC(x) ((x)+F_ACC) -#define NOKEY 0x100 /* no key pressed marker */ -#define FKEY 0x200 /* function key marker */ -#define MKEY 0x400 /* meta key marker (prepend ESC)*/ -#define BKEY 0x800 /* backtab (ESC [ Z) */ - -#define SPCLKEY 0x8000 /* special key */ -#define RELKEY 0x4000 /* key released */ -#define ERRKEY 0x2000 /* error */ - -#define KEYCHAR(c) ((c) & 0x00ff) -#define KEYFLAGS(c) ((c) & ~0x00ff) - -/* video mode definitions */ -#define M_B40x25 0 /* black & white 40 columns */ -#define M_C40x25 1 /* color 40 columns */ -#define M_B80x25 2 /* black & white 80 columns */ -#define M_C80x25 3 /* color 80 columns */ -#define M_BG320 4 /* black & white graphics 320x200 */ -#define M_CG320 5 /* color graphics 320x200 */ -#define M_BG640 6 /* black & white graphics 640x200 hi-res */ -#define M_EGAMONO80x25 7 /* ega-mono 80x25 */ -#define M_CG320_D 13 /* ega mode D */ -#define M_CG640_E 14 /* ega mode E */ -#define M_EGAMONOAPA 15 /* ega mode F */ -#define M_CG640x350 16 /* ega mode 10 */ -#define M_ENHMONOAPA2 17 /* ega mode F with extended memory */ -#define M_ENH_CG640 18 /* ega mode 10* */ -#define M_ENH_B40x25 19 /* ega enhanced black & white 40 columns */ -#define M_ENH_C40x25 20 /* ega enhanced color 40 columns */ -#define M_ENH_B80x25 21 /* ega enhanced black & white 80 columns */ -#define M_ENH_C80x25 22 /* ega enhanced color 80 columns */ -#define M_VGA_C40x25 23 /* vga 8x16 font on color */ -#define M_VGA_C80x25 24 /* vga 8x16 font on color */ -#define M_VGA_M80x25 25 /* vga 8x16 font on mono */ - -#define M_VGA11 26 /* vga 640x480 2 colors */ -#define M_BG640x480 26 -#define M_VGA12 27 /* vga 640x480 16 colors */ -#define M_CG640x480 27 -#define M_VGA13 28 /* vga 640x200 256 colors */ -#define M_VGA_CG320 28 - -#define M_VGA_C80x50 30 /* vga 8x8 font on color */ -#define M_VGA_M80x50 31 /* vga 8x8 font on color */ -#define M_VGA_C80x30 32 /* vga 8x16 font on color */ -#define M_VGA_M80x30 33 /* vga 8x16 font on color */ -#define M_VGA_C80x60 34 /* vga 8x8 font on color */ -#define M_VGA_M80x60 35 /* vga 8x8 font on color */ -#define M_VGA_CG640 36 /* vga 640x400 256 color */ -#define M_VGA_MODEX 37 /* vga 320x240 256 color */ - -#define M_ENH_B80x43 0x70 /* ega black & white 80x43 */ -#define M_ENH_C80x43 0x71 /* ega color 80x43 */ - -#define M_PC98_80x25 98 /* PC98 80x25 */ -#define M_PC98_80x30 99 /* PC98 80x30 */ - -#define M_HGC_P0 0xe0 /* hercules graphics - page 0 @ B0000 */ -#define M_HGC_P1 0xe1 /* hercules graphics - page 1 @ B8000 */ -#define M_MCA_MODE 0xff /* monochrome adapter mode */ - -#define M_TEXT_80x25 200 /* generic text modes */ -#define M_TEXT_80x30 201 -#define M_TEXT_80x43 202 -#define M_TEXT_80x50 203 -#define M_TEXT_80x60 204 -#define M_TEXT_132x25 205 -#define M_TEXT_132x30 206 -#define M_TEXT_132x43 207 -#define M_TEXT_132x50 208 -#define M_TEXT_132x60 209 - -#define SW_PC98_80x25 _IO('S', M_PC98_80x25) -#define SW_PC98_80x30 _IO('S', M_PC98_80x30) -#define SW_B40x25 _IO('S', M_B40x25) -#define SW_C40x25 _IO('S', M_C40x25) -#define SW_B80x25 _IO('S', M_B80x25) -#define SW_C80x25 _IO('S', M_C80x25) -#define SW_BG320 _IO('S', M_BG320) -#define SW_CG320 _IO('S', M_CG320) -#define SW_BG640 _IO('S', M_BG640) -#define SW_EGAMONO80x25 _IO('S', M_EGAMONO80x25) -#define SW_CG320_D _IO('S', M_CG320_D) -#define SW_CG640_E _IO('S', M_CG640_E) -#define SW_EGAMONOAPA _IO('S', M_EGAMONOAPA) -#define SW_CG640x350 _IO('S', M_CG640x350) -#define SW_ENH_MONOAPA2 _IO('S', M_ENHMONOAPA2) -#define SW_ENH_CG640 _IO('S', M_ENH_CG640) -#define SW_ENH_B40x25 _IO('S', M_ENH_B40x25) -#define SW_ENH_C40x25 _IO('S', M_ENH_C40x25) -#define SW_ENH_B80x25 _IO('S', M_ENH_B80x25) -#define SW_ENH_C80x25 _IO('S', M_ENH_C80x25) -#define SW_ENH_B80x43 _IO('S', M_ENH_B80x43) -#define SW_ENH_C80x43 _IO('S', M_ENH_C80x43) -#define SW_MCAMODE _IO('S', M_MCA_MODE) -#define SW_VGA_C40x25 _IO('S', M_VGA_C40x25) -#define SW_VGA_C80x25 _IO('S', M_VGA_C80x25) -#define SW_VGA_C80x30 _IO('S', M_VGA_C80x30) -#define SW_VGA_C80x50 _IO('S', M_VGA_C80x50) -#define SW_VGA_C80x60 _IO('S', M_VGA_C80x60) -#define SW_VGA_M80x25 _IO('S', M_VGA_M80x25) -#define SW_VGA_M80x30 _IO('S', M_VGA_M80x30) -#define SW_VGA_M80x50 _IO('S', M_VGA_M80x50) -#define SW_VGA_M80x60 _IO('S', M_VGA_M80x60) -#define SW_VGA11 _IO('S', M_VGA11) -#define SW_BG640x480 _IO('S', M_VGA11) -#define SW_VGA12 _IO('S', M_VGA12) -#define SW_CG640x480 _IO('S', M_VGA12) -#define SW_VGA13 _IO('S', M_VGA13) -#define SW_VGA_CG320 _IO('S', M_VGA13) -#define SW_VGA_CG640 _IO('S', M_VGA_CG640) -#define SW_VGA_MODEX _IO('S', M_VGA_MODEX) - -#define SW_TEXT_80x25 _IO('S', M_TEXT_80x25) -#define SW_TEXT_80x30 _IO('S', M_TEXT_80x30) -#define SW_TEXT_80x43 _IO('S', M_TEXT_80x43) -#define SW_TEXT_80x50 _IO('S', M_TEXT_80x50) -#define SW_TEXT_80x60 _IO('S', M_TEXT_80x60) -#define SW_TEXT_132x25 _IO('S', M_TEXT_132x25) -#define SW_TEXT_132x30 _IO('S', M_TEXT_132x30) -#define SW_TEXT_132x43 _IO('S', M_TEXT_132x43) -#define SW_TEXT_132x50 _IO('S', M_TEXT_132x50) -#define SW_TEXT_132x60 _IO('S', M_TEXT_132x60) - -#define M_VESA_BASE 0x100 /* VESA mode number base */ - -#define M_VESA_CG640x400 0x100 /* 640x400, 256 color */ -#define M_VESA_CG640x480 0x101 /* 640x480, 256 color */ -#define M_VESA_800x600 0x102 /* 800x600, 16 color */ -#define M_VESA_CG800x600 0x103 /* 800x600, 256 color */ -#define M_VESA_1024x768 0x104 /* 1024x768, 16 color */ -#define M_VESA_CG1024x768 0x105 /* 1024x768, 256 color */ -#define M_VESA_1280x1024 0x106 /* 1280x1024, 16 color */ -#define M_VESA_CG1280x1024 0x107 /* 1280x1024, 256 color */ -#define M_VESA_C80x60 0x108 /* 8x8 font */ -#define M_VESA_C132x25 0x109 /* 8x16 font */ -#define M_VESA_C132x43 0x10a /* 8x14 font */ -#define M_VESA_C132x50 0x10b /* 8x8 font */ -#define M_VESA_C132x60 0x10c /* 8x8 font */ -#define M_VESA_32K_320 0x10d /* 320x200, 5:5:5 */ -#define M_VESA_64K_320 0x10e /* 320x200, 5:6:5 */ -#define M_VESA_FULL_320 0x10f /* 320x200, 8:8:8 */ -#define M_VESA_32K_640 0x110 /* 640x480, 5:5:5 */ -#define M_VESA_64K_640 0x111 /* 640x480, 5:6:5 */ -#define M_VESA_FULL_640 0x112 /* 640x480, 8:8:8 */ -#define M_VESA_32K_800 0x113 /* 800x600, 5:5:5 */ -#define M_VESA_64K_800 0x114 /* 800x600, 5:6:5 */ -#define M_VESA_FULL_800 0x115 /* 800x600, 8:8:8 */ -#define M_VESA_32K_1024 0x116 /* 1024x768, 5:5:5 */ -#define M_VESA_64K_1024 0x117 /* 1024x768, 5:6:5 */ -#define M_VESA_FULL_1024 0x118 /* 1024x768, 8:8:8 */ -#define M_VESA_32K_1280 0x119 /* 1280x1024, 5:5:5 */ -#define M_VESA_64K_1280 0x11a /* 1280x1024, 5:6:5 */ -#define M_VESA_FULL_1280 0x11b /* 1280x1024, 8:8:8 */ -#define M_VESA_MODE_MAX 0x1ff - -#define SW_VESA_CG640x400 _IO('V', M_VESA_CG640x400 - M_VESA_BASE) -#define SW_VESA_CG640x480 _IO('V', M_VESA_CG640x480 - M_VESA_BASE) -#define SW_VESA_800x600 _IO('V', M_VESA_800x600 - M_VESA_BASE) -#define SW_VESA_CG800x600 _IO('V', M_VESA_CG800x600 - M_VESA_BASE) -#define SW_VESA_1024x768 _IO('V', M_VESA_1024x768 - M_VESA_BASE) -#define SW_VESA_CG1024x768 _IO('V', M_VESA_CG1024x768 - M_VESA_BASE) -#define SW_VESA_1280x1024 _IO('V', M_VESA_1280x1024 - M_VESA_BASE) -#define SW_VESA_CG1280x1024 _IO('V', M_VESA_CG1280x1024 - M_VESA_BASE) -#define SW_VESA_C80x60 _IO('V', M_VESA_C80x60 - M_VESA_BASE) -#define SW_VESA_C132x25 _IO('V', M_VESA_C132x25 - M_VESA_BASE) -#define SW_VESA_C132x43 _IO('V', M_VESA_C132x43 - M_VESA_BASE) -#define SW_VESA_C132x50 _IO('V', M_VESA_C132x50 - M_VESA_BASE) -#define SW_VESA_C132x60 _IO('V', M_VESA_C132x60 - M_VESA_BASE) -#define SW_VESA_32K_320 _IO('V', M_VESA_32K_320 - M_VESA_BASE) -#define SW_VESA_64K_320 _IO('V', M_VESA_64K_320 - M_VESA_BASE) -#define SW_VESA_FULL_320 _IO('V', M_VESA_FULL_320 - M_VESA_BASE) -#define SW_VESA_32K_640 _IO('V', M_VESA_32K_640 - M_VESA_BASE) -#define SW_VESA_64K_640 _IO('V', M_VESA_64K_640 - M_VESA_BASE) -#define SW_VESA_FULL_640 _IO('V', M_VESA_FULL_640 - M_VESA_BASE) -#define SW_VESA_32K_800 _IO('V', M_VESA_32K_800 - M_VESA_BASE) -#define SW_VESA_64K_800 _IO('V', M_VESA_64K_800 - M_VESA_BASE) -#define SW_VESA_FULL_800 _IO('V', M_VESA_FULL_800 - M_VESA_BASE) -#define SW_VESA_32K_1024 _IO('V', M_VESA_32K_1024 - M_VESA_BASE) -#define SW_VESA_64K_1024 _IO('V', M_VESA_64K_1024 - M_VESA_BASE) -#define SW_VESA_FULL_1024 _IO('V', M_VESA_FULL_1024 - M_VESA_BASE) -#define SW_VESA_32K_1280 _IO('V', M_VESA_32K_1280 - M_VESA_BASE) -#define SW_VESA_64K_1280 _IO('V', M_VESA_64K_1280 - M_VESA_BASE) -#define SW_VESA_FULL_1280 _IO('V', M_VESA_FULL_1280 - M_VESA_BASE) +#include <sys/fbio.h> +#include <sys/kbio.h> +#include <sys/consio.h> #endif /* !_MACHINE_CONSOLE_H_ */ - diff --git a/sys/conf/NOTES b/sys/conf/NOTES index 5563146..cc51183 100644 --- a/sys/conf/NOTES +++ b/sys/conf/NOTES @@ -2,7 +2,7 @@ # LINT -- config file for checking all the sources, tries to pull in # as much of the source tree as it can. # -# $Id: LINT,v 1.606 1999/06/15 13:14:40 des Exp $ +# $Id: LINT,v 1.607 1999/06/19 20:20:52 rnordier Exp $ # # NB: You probably don't want to try running a kernel built from this # file. Instead, you should start from GENERIC, and add options from @@ -912,6 +912,9 @@ options VGA_NO_MODE_CHANGE # don't change video modes # Older video cards may require this option for proper operation. options VGA_SLOW_IOACCESS # do byte-wide i/o's to TS and GDC regs +# The following option probably won't work with the LCD displays. +options VGA_WIDTH90 # support 90 column modes + # To include support for VESA video modes options VESA @@ -939,18 +942,20 @@ options PCVT_VT220KEYB # The syscons console driver (sco color console compatible). device sc0 at isa? options MAXCONS=16 # number of virtual consoles -options STD8X16FONT # Compile font in -makeoptions STD8X16FONT=cp850 -options SC_HISTORY_SIZE=200 # number of history buffer lines +options SC_ALT_MOUSE_IMAGE # simplified mouse cursor in text mode +options SC_DFLT_FONT # compile font in +makeoptions SC_DFLT_FONT="cp850" +options SC_DISABLE_DDBKEY # disable `debug' key options SC_DISABLE_REBOOT # disable reboot key sequence +options SC_HISTORY_SIZE=200 # number of history buffer lines +options SC_MOUSE_CHAR=0x3 # char code for text mode mouse cursor +options SC_PIXEL_MODE # add support for the raster text mode -# -# `flags' for sc0: -# 0x01 Use a 'visual' bell -# 0x02 Use a 'blink' cursor -# 0x04 Use a 'underline' cursor -# 0x06 Use a 'blinking underline' (destructive) cursor -# 0x40 Make the bell quiet if it is rung in the background vty. +# You can selectively disable features in syscons. +options SC_NO_CUTPASTE +options SC_NO_FONT_LOADING +options SC_NO_HISTORY +options SC_NO_SYSMOUSE # # The Numeric Processing eXtension driver. This should be configured if @@ -2155,6 +2160,10 @@ options ULPT_DEBUG options UMASS_DEBUG options UMS_DEBUG +# options for ukbd: +options UKBD_DFLT_KEYMAP # specify the built-in keymap +makeoptions UKBD_DFLT_KEYMAP="it.iso" + # # Embedded system options: # diff --git a/sys/conf/files.alpha b/sys/conf/files.alpha index 112d8f8..fb69c9a 100644 --- a/sys/conf/files.alpha +++ b/sys/conf/files.alpha @@ -1,7 +1,7 @@ # This file tells config what files go into building a kernel, # files marked standard are always included. # -# $Id: files.alpha,v 1.20 1999/06/05 13:29:57 dfr Exp $ +# $Id: files.alpha,v 1.21 1999/06/19 13:12:51 dfr Exp $ # # The long compile-with and dependency lines are required because of # limitations in config: backslash-newline doesn't work in strings, and @@ -152,6 +152,7 @@ libkern/alpha/ntohs.S standard isa/sio.c optional sio device-driver dev/fb/fb.c optional fb device-driver dev/fb/fb.c optional vga device-driver +dev/fb/vga.c optional vga device-driver isa/vga_isa.c optional vga device-driver dev/fb/splash.c optional splash dev/kbd/atkbd.c optional atkbd device-driver @@ -162,7 +163,11 @@ dev/kbd/kbd.c optional atkbd device-driver dev/kbd/kbd.c optional kbd device-driver dev/kbd/kbd.c optional ukbd device-driver dev/syscons/syscons.c optional sc device-driver +dev/syscons/schistory.c optional sc device-driver +dev/syscons/scmouse.c optional sc device-driver +dev/syscons/scvgarndr.c optional sc device-driver dev/syscons/scvidctl.c optional sc device-driver +dev/syscons/scvtb.c optional sc device-driver isa/syscons_isa.c optional sc device-driver isa/psm.c optional psm device-driver isa/fd.c optional fd device-driver diff --git a/sys/conf/files.i386 b/sys/conf/files.i386 index 44c115c..ae19e96 100644 --- a/sys/conf/files.i386 +++ b/sys/conf/files.i386 @@ -1,7 +1,7 @@ # This file tells config what files go into building a kernel, # files marked standard are always included. # -# $Id: files.i386,v 1.246 1999/06/01 18:18:38 jlemon Exp $ +# $Id: files.i386,v 1.247 1999/06/18 19:55:50 green Exp $ # # The long compile-with and dependency lines are required because of # limitations in config: backslash-newline doesn't work in strings, and @@ -19,10 +19,10 @@ linux_assym.h optional compat_linux \ no-obj no-implicit-rule before-depend \ clean "linux_assym.h" # -font8x16.o optional std8x16font \ - compile-with "uudecode < /usr/share/syscons/fonts/${STD8X16FONT}-8x16.fnt && file2c 'unsigned char font_16[16*256] = {' '};' < ${STD8X16FONT}-8x16 > font8x16.c && ${CC} -c ${CFLAGS} font8x16.c" \ - no-implicit-rule before-depend \ - clean "${STD8X16FONT}-8x16 font8x16.c" +font.h optional sc_dflt_font \ + compile-with "uudecode < /usr/share/syscons/fonts/${SC_DFLT_FONT}-8x16.fnt && file2c 'static u_char dflt_font_16[16*256] = {' '};' < ${SC_DFLT_FONT}-8x16 > font.h && uudecode < /usr/share/syscons/fonts/${SC_DFLT_FONT}-8x14.fnt && file2c 'static u_char dflt_font_14[14*256] = {' '};' < ${SC_DFLT_FONT}-8x14 >> font.h && uudecode < /usr/share/syscons/fonts/${SC_DFLT_FONT}-8x8.fnt && file2c 'static u_char dflt_font_8[8*256] = {' '};' < ${SC_DFLT_FONT}-8x8 >> font.h" \ + no-obj no-implicit-rule before-depend \ + clean "font.h" # atkbdmap.h optional atkbd_dflt_keymap \ compile-with "kbdcontrol -L ${ATKBD_DFLT_KEYMAP} | sed -e 's/^static keymap_t.* = /static keymap_t key_map = /' -e 's/^static accentmap_t.* = /static accentmap_t accent_map = /' > atkbdmap.h" \ @@ -44,14 +44,19 @@ dev/ata/atapi-tape.c optional atapist device-driver dev/fb/fb.c optional fb device-driver dev/fb/fb.c optional vga device-driver dev/fb/splash.c optional splash +dev/fb/vga.c optional vga device-driver dev/kbd/atkbd.c optional atkbd device-driver dev/kbd/atkbdc.c optional atkbdc device-driver dev/kbd/kbd.c optional atkbd device-driver dev/kbd/kbd.c optional kbd device-driver dev/kbd/kbd.c optional ukbd device-driver dev/syscons/syscons.c optional sc device-driver +dev/syscons/schistory.c optional sc device-driver +dev/syscons/scmouse.c optional sc device-driver dev/syscons/scvidctl.c optional sc device-driver dev/syscons/scvesactl.c optional sc device-driver +dev/syscons/scvgarndr.c optional sc device-driver +dev/syscons/scvtb.c optional sc device-driver i386/apm/apm.c optional apm device-driver i386/apm/apm_setup.s optional apm i386/eisa/dpt_eisa.c optional eisa dpt device-driver diff --git a/sys/conf/options.alpha b/sys/conf/options.alpha index 9c8e8e1..d78c220 100644 --- a/sys/conf/options.alpha +++ b/sys/conf/options.alpha @@ -1,4 +1,4 @@ -# $Id: options.alpha,v 1.10 1999/03/10 10:36:50 yokota Exp $ +# $Id: options.alpha,v 1.11 1999/05/27 22:03:31 gallatin Exp $ EV5 opt_global.h EV4 opt_global.h @@ -21,25 +21,35 @@ CMD640 opt_wd.h SHOW_BUSYBUFS PANIC_REBOOT_WAIT_TIME opt_panic.h -SC_SPLASH_SCREEN opt_syscons.h MAXCONS opt_syscons.h -SLOW_VGA opt_syscons.h -STD8X16FONT opt_syscons.h -SC_HISTORY_SIZE opt_syscons.h +SC_ALT_MOUSE_IMAGE opt_syscons.h +SC_DEBUG_LEVEL opt_syscons.h +SC_DFLT_FONT opt_syscons.h +SC_DISABLE_DDB opt_syscons.h SC_DISABLE_REBOOT opt_syscons.h +SC_HISTORY_SIZE opt_syscons.h SC_MOUSE_CHAR opt_syscons.h +SC_NO_CUTPASTE opt_syscons.h +SC_NO_FONT_LOADING opt_syscons.h +SC_NO_HISTORY opt_syscons.h +SC_NO_SYSMOUSE opt_syscons.h +SC_PIXEL_MODE opt_syscons.h +SC_RENDER_DEBUG opt_syscons.h +SC_VIDEO_DEBUG opt_syscons.h VGA_ALT_SEQACCESS opt_vga.h VGA_DEBUG opt_vga.h VGA_NO_FONT_LOADING opt_vga.h VGA_NO_MODE_CHANGE opt_vga.h VGA_SLOW_IOACCESS opt_vga.h +VGA_WIDTH90 opt_vga.h PSM_HOOKAPM opt_psm.h PSM_RESETAFTERSUSPEND opt_psm.h PSM_DEBUG opt_psm.h # Fb options +FB_DEBUG opt_fb.h FB_INSTALL_CDEV opt_fb.h # Atkbd options diff --git a/sys/conf/options.i386 b/sys/conf/options.i386 index c3aa0d9..d7cc7b4 100644 --- a/sys/conf/options.i386 +++ b/sys/conf/options.i386 @@ -1,4 +1,4 @@ -# $Id: options.i386,v 1.116 1999/06/06 22:45:04 steve Exp $ +# $Id: options.i386,v 1.117 1999/06/15 13:14:43 des Exp $ DISABLE_PSE IDE_DELAY @@ -65,17 +65,30 @@ I586_CPU opt_global.h I686_CPU opt_global.h MAXCONS opt_syscons.h -STD8X16FONT opt_syscons.h -SC_HISTORY_SIZE opt_syscons.h +SC_ALT_MOUSE_IMAGE opt_syscons.h +SC_DEBUG_LEVEL opt_syscons.h +SC_DFLT_FONT opt_syscons.h +SC_DISABLE_DDBKEY opt_syscons.h SC_DISABLE_REBOOT opt_syscons.h +SC_HISTORY_SIZE opt_syscons.h SC_MOUSE_CHAR opt_syscons.h - +SC_NO_CUTPASTE opt_syscons.h +SC_NO_FONT_LOADING opt_syscons.h +SC_NO_HISTORY opt_syscons.h +SC_NO_SYSMOUSE opt_syscons.h +SC_PIXEL_MODE opt_syscons.h +SC_RENDER_DEBUG opt_syscons.h +SC_VIDEO_DEBUG opt_syscons.h + +FB_DEBUG opt_fb.h FB_INSTALL_CDEV opt_fb.h VGA_ALT_SEQACCESS opt_vga.h +VGA_DEBUG opt_vga.h VGA_NO_FONT_LOADING opt_vga.h VGA_NO_MODE_CHANGE opt_vga.h VGA_SLOW_IOACCESS opt_vga.h +VGA_WIDTH90 opt_vga.h VESA opt_vesa.h VESA_DEBUG opt_vesa.h diff --git a/sys/dev/fb/fb.c b/sys/dev/fb/fb.c index a1d5f11..e10b75b 100644 --- a/sys/dev/fb/fb.c +++ b/sys/dev/fb/fb.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: fb.c,v 1.4 1999/05/30 16:51:23 phk Exp $ + * $Id: fb.c,v 1.5 1999/05/31 11:24:38 phk Exp $ */ #include "fb.h" @@ -34,10 +34,14 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/conf.h> +#include <sys/bus.h> #include <sys/kernel.h> #include <sys/malloc.h> +#include <sys/uio.h> +#include <sys/fbio.h> -#include <machine/console.h> +#include <vm/vm.h> +#include <vm/pmap.h> #include <dev/fb/fbreg.h> @@ -49,6 +53,7 @@ * when necessary. */ +static int vid_malloc; static int adapters = 1; static video_adapter_t *adp_ini; static video_adapter_t **adapter = &adp_ini; @@ -56,48 +61,69 @@ static video_switch_t *vidsw_ini; video_switch_t **vidsw = &vidsw_ini; #ifdef FB_INSTALL_CDEV - -#define ARRAY_DELTA 4 - static struct cdevsw *vidcdevsw_ini; static struct cdevsw **vidcdevsw = &vidcdevsw_ini; +#endif -static void +#define ARRAY_DELTA 4 + +static int vid_realloc_array(void) { video_adapter_t **new_adp; video_switch_t **new_vidsw; +#ifdef FB_INSTALL_CDEV struct cdevsw **new_cdevsw; +#endif int newsize; int s; + if (!vid_malloc) + return ENOMEM; + s = spltty(); newsize = ((adapters + ARRAY_DELTA)/ARRAY_DELTA)*ARRAY_DELTA; new_adp = malloc(sizeof(*new_adp)*newsize, M_DEVBUF, M_WAITOK); new_vidsw = malloc(sizeof(*new_vidsw)*newsize, M_DEVBUF, M_WAITOK); +#ifdef FB_INSTALL_CDEV new_cdevsw = malloc(sizeof(*new_cdevsw)*newsize, M_DEVBUF, M_WAITOK); +#endif bzero(new_adp, sizeof(*new_adp)*newsize); bzero(new_vidsw, sizeof(*new_vidsw)*newsize); - bzero(new_cdevsw, sizeof(*new_cdevsw)*newsize); bcopy(adapter, new_adp, sizeof(*adapter)*adapters); bcopy(vidsw, new_vidsw, sizeof(*vidsw)*adapters); +#ifdef FB_INSTALL_CDEV + bzero(new_cdevsw, sizeof(*new_cdevsw)*newsize); bcopy(vidcdevsw, new_cdevsw, sizeof(*vidcdevsw)*adapters); +#endif if (adapters > 1) { free(adapter, M_DEVBUF); free(vidsw, M_DEVBUF); +#ifdef FB_INSTALL_CDEV free(vidcdevsw, M_DEVBUF); +#endif } adapter = new_adp; vidsw = new_vidsw; +#ifdef FB_INSTALL_CDEV vidcdevsw = new_cdevsw; +#endif adapters = newsize; splx(s); if (bootverbose) printf("fb: new array size %d\n", adapters); + + return 0; } -#endif /* FB_INSTALL_CDEV */ +static void +vid_malloc_init(void *arg) +{ + vid_malloc = TRUE; +} + +SYSINIT(vid_mem, SI_SUB_KMEM, SI_ORDER_ANY, vid_malloc_init, NULL); /* * Low-level frame buffer driver functions @@ -120,20 +146,22 @@ vid_init_struct(video_adapter_t *adp, char *name, int type, int unit) int vid_register(video_adapter_t *adp) { - video_driver_t **list; - video_driver_t *p; + const video_driver_t **list; + const video_driver_t *p; int index; for (index = 0; index < adapters; ++index) { if (adapter[index] == NULL) break; } - if (index >= adapters) - return -1; + if (index >= adapters) { + if (vid_realloc_array()) + return -1; + } adp->va_index = index; adp->va_token = NULL; - list = (video_driver_t **)videodriver_set.ls_items; + list = (const video_driver_t **)videodriver_set.ls_items; while ((p = *list++) != NULL) { if (strcmp(p->name, adp->va_name) == 0) { adapter[index] = adp; @@ -162,10 +190,10 @@ vid_unregister(video_adapter_t *adp) video_switch_t *vid_get_switch(char *name) { - video_driver_t **list; - video_driver_t *p; + const video_driver_t **list; + const video_driver_t *p; - list = (video_driver_t **)videodriver_set.ls_items; + list = (const video_driver_t **)videodriver_set.ls_items; while ((p = *list++) != NULL) { if (strcmp(p->name, name) == 0) return p->vidsw; @@ -251,10 +279,10 @@ video_adapter_t int vid_configure(int flags) { - video_driver_t **list; - video_driver_t *p; + const video_driver_t **list; + const video_driver_t *p; - list = (video_driver_t **)videodriver_set.ls_items; + list = (const video_driver_t **)videodriver_set.ls_items; while ((p = *list++) != NULL) { if (p->configure != NULL) (*p->configure)(flags); @@ -269,27 +297,73 @@ vid_configure(int flags) * appropriate subdrivers. */ -#define DRIVER_NAME "fb" +#define FB_DRIVER_NAME "fb" #ifdef FB_INSTALL_CDEV +#if experimental + +static devclass_t fb_devclass; + +static int fbprobe(device_t dev); +static int fbattach(device_t dev); + +static device_method_t fb_methods[] = { + DEVMETHOD(device_probe, fbprobe), + DEVMETHOD(device_attach, fbattach), + + DEVMETHOD(bus_print_child, bus_generic_print_child), + { 0, 0 } +}; + +static driver_t fb_driver = { + FB_DRIVER_NAME, + fb_methods, + 0, +}; + +static int +fbprobe(device_t dev) +{ + int unit; + + unit = device_get_unit(dev); + if (unit >= adapters) + return ENXIO; + if (adapter[unit] == NULL) + return ENXIO; + + device_set_desc(dev, "generic frame buffer"); + return 0; +} + +static int +fbattach(device_t dev) +{ + printf("fbattach: about to attach children\n"); + bus_generic_attach(dev); + return 0; +} + +#endif /* experimental */ + #define FB_UNIT(dev) minor(dev) #define FB_MKMINOR(unit) (u) -#if notyet - static d_open_t fbopen; static d_close_t fbclose; +static d_read_t fbread; +static d_write_t fbwrite; static d_ioctl_t fbioctl; static d_mmap_t fbmmap; -#define CDEV_MAJOR 141 /* XXX */ +#define CDEV_MAJOR 123 /* XXX */ static struct cdevsw fb_cdevsw = { /* open */ fbopen, /* close */ fbclose, - /* read */ noread, - /* write */ nowrite, + /* read */ fbread, + /* write */ fbwrite, /* ioctl */ fbioctl, /* stop */ nostop, /* reset */ noreset, @@ -297,7 +371,7 @@ static struct cdevsw fb_cdevsw = { /* poll */ nopoll, /* mmap */ fbmmap, /* strategy */ nostrategy, - /* name */ DRIVER_NAME, + /* name */ FB_DRIVER_NAME, /* parms */ noparms, /* maj */ CDEV_MAJOR, /* dump */ nodump, @@ -320,10 +394,8 @@ vfbattach(void *arg) PSEUDO_SET(vfbattach, fb); -#endif /* notyet */ - int -fb_attach(dev_t dev, video_adapter *adp, struct cdevsw *cdevsw) +fb_attach(dev_t dev, video_adapter_t *adp, struct cdevsw *cdevsw) { int s; @@ -339,15 +411,12 @@ fb_attach(dev_t dev, video_adapter *adp, struct cdevsw *cdevsw) /* XXX: DEVFS? */ - if (adp->va_index + 1 >= adapters) - vid_realloc_array(); - printf("fb%d at %s%d\n", adp->va_index, adp->va_name, adp->va_unit); return 0; } int -fb_detach(dev_t dev, video_adapter *adp, struct cdevsw *cdevsw) +fb_detach(dev_t dev, video_adapter_t *adp, struct cdevsw *cdevsw) { int s; @@ -364,6 +433,165 @@ fb_detach(dev_t dev, video_adapter *adp, struct cdevsw *cdevsw) return 0; } +static int +fbopen(dev_t dev, int flag, int mode, struct proc *p) +{ + int unit; + + unit = FB_UNIT(dev); + if (unit >= adapters) + return ENXIO; + if (vidcdevsw[unit] == NULL) + return ENXIO; + return (*vidcdevsw[unit]->d_open)(makedev(0, adapter[unit]->va_minor), + flag, mode, p); +} + +static int +fbclose(dev_t dev, int flag, int mode, struct proc *p) +{ + int unit; + + unit = FB_UNIT(dev); + if (vidcdevsw[unit] == NULL) + return ENXIO; + return (*vidcdevsw[unit]->d_close)(makedev(0, adapter[unit]->va_minor), + flag, mode, p); +} + +static int +fbread(dev_t dev, struct uio *uio, int flag) +{ + int unit; + + unit = FB_UNIT(dev); + if (vidcdevsw[unit] == NULL) + return ENXIO; + return (*vidcdevsw[unit]->d_read)(makedev(0, adapter[unit]->va_minor), + uio, flag); +} + +static int +fbwrite(dev_t dev, struct uio *uio, int flag) +{ + int unit; + + unit = FB_UNIT(dev); + if (vidcdevsw[unit] == NULL) + return ENXIO; + return (*vidcdevsw[unit]->d_write)(makedev(0, adapter[unit]->va_minor), + uio, flag); +} + +static int +fbioctl(dev_t dev, u_long cmd, caddr_t arg, int flag, struct proc *p) +{ + int unit; + + unit = FB_UNIT(dev); + if (vidcdevsw[unit] == NULL) + return ENXIO; + return (*vidcdevsw[unit]->d_ioctl)(makedev(0, adapter[unit]->va_minor), + cmd, arg, flag, p); +} + +static int +fbmmap(dev_t dev, vm_offset_t offset, int nprot) +{ + int unit; + + unit = FB_UNIT(dev); + if (vidcdevsw[unit] == NULL) + return ENXIO; + return (*vidcdevsw[unit]->d_mmap)(makedev(0, adapter[unit]->va_minor), + offset, nprot); +} + +#if experimental +DEV_DRIVER_MODULE(fb, ???, fb_driver, fb_devclass, + CDEV_MAJOR, NOMAJ, fb_cdevsw, 0, 0); +#endif + +/* + * Generic frame buffer cdev driver functions + * Frame buffer subdrivers may call these functions to implement common + * driver functions. + */ + +int genfbopen(genfb_softc_t *sc, video_adapter_t *adp, int flag, int mode, + struct proc *p) +{ + int s; + + s = spltty(); + if (!(sc->gfb_flags & FB_OPEN)) + sc->gfb_flags |= FB_OPEN; + splx(s); + return 0; +} + +int genfbclose(genfb_softc_t *sc, video_adapter_t *adp, int flag, int mode, + struct proc *p) +{ + int s; + + s = spltty(); + sc->gfb_flags &= ~FB_OPEN; + splx(s); + return 0; +} + +int genfbread(genfb_softc_t *sc, video_adapter_t *adp, struct uio *uio, + int flag) +{ + int size; + int offset; + int error; + int len; + + error = 0; + size = adp->va_buffer_size/adp->va_info.vi_planes; + while (uio->uio_resid > 0) { + if (uio->uio_offset >= size) + break; + offset = uio->uio_offset%adp->va_window_size; + len = imin(uio->uio_resid, size - uio->uio_offset); + len = imin(len, adp->va_window_size - offset); + if (len <= 0) + break; + (*vidsw[adp->va_index]->set_win_org)(adp, uio->uio_offset); + error = uiomove((caddr_t)(adp->va_window + offset), len, uio); + if (error) + break; + } + return error; +} + +int genfbwrite(genfb_softc_t *sc, video_adapter_t *adp, struct uio *uio, + int flag) +{ + return ENODEV; +} + +int genfbioctl(genfb_softc_t *sc, video_adapter_t *adp, u_long cmd, + caddr_t arg, int flag, struct proc *p) +{ + int error; + + if (adp == NULL) /* XXX */ + return ENXIO; + error = (*vidsw[adp->va_index]->ioctl)(adp, cmd, arg); + if (error == ENOIOCTL) + error = ENODEV; + return error; +} + +int genfbmmap(genfb_softc_t *sc, video_adapter_t *adp, vm_offset_t offset, + int prot) +{ + return (*vidsw[adp->va_index]->mmap)(adp, offset, prot); +} + #endif /* FB_INSTALL_CDEV */ static char @@ -379,6 +607,7 @@ static char { KD_EGA, "EGA" }, { KD_VGA, "VGA" }, { KD_PC98, "PC-98x1" }, + { KD_TGA, "TGA" }, { -1, "Unknown" }, }; int i; @@ -389,6 +618,12 @@ static char return names[i].name; } +/* + * Generic low-level frame buffer functions + * The low-level functions in the frame buffer subdriver may use these + * functions. + */ + void fb_dump_adp_info(char *driver, video_adapter_t *adp, int level) { @@ -396,19 +631,19 @@ fb_dump_adp_info(char *driver, video_adapter_t *adp, int level) return; printf("%s%d: %s%d, %s, type:%s (%d), flags:0x%x\n", - DRIVER_NAME, adp->va_index, driver, adp->va_unit, adp->va_name, + FB_DRIVER_NAME, adp->va_index, driver, adp->va_unit, adp->va_name, adapter_name(adp->va_type), adp->va_type, adp->va_flags); printf("%s%d: port:0x%x-0x%x, crtc:0x%x, mem:0x%x 0x%x\n", - DRIVER_NAME, adp->va_index, + FB_DRIVER_NAME, adp->va_index, adp->va_io_base, adp->va_io_base + adp->va_io_size - 1, adp->va_crtc_addr, adp->va_mem_base, adp->va_mem_size); printf("%s%d: init mode:%d, bios mode:%d, current mode:%d\n", - DRIVER_NAME, adp->va_index, + FB_DRIVER_NAME, adp->va_index, adp->va_initial_mode, adp->va_initial_bios_mode, adp->va_mode); - printf("%s%d: window:0x%x size:%dk gran:%dk, buf:0x%x size:%dk\n", - DRIVER_NAME, adp->va_index, - adp->va_window, (int)adp->va_window_size/1024, - (int)adp->va_window_gran/1024, adp->va_buffer, + printf("%s%d: window:%p size:%dk gran:%dk, buf:%p size:%dk\n", + FB_DRIVER_NAME, adp->va_index, + (void *)adp->va_window, (int)adp->va_window_size/1024, + (int)adp->va_window_gran/1024, (void *)adp->va_buffer, (int)adp->va_buffer_size/1024); } @@ -432,3 +667,161 @@ fb_dump_mode_info(char *driver, video_adapter_t *adp, video_info_t *info, info->vi_cwidth, info->vi_cheight); printf("win:0x%x\n", info->vi_window); } + +int +fb_type(int adp_type) +{ + static struct { + int fb_type; + int va_type; + } types[] = { + { FBTYPE_MDA, KD_MONO }, + { FBTYPE_HERCULES, KD_HERCULES }, + { FBTYPE_CGA, KD_CGA }, + { FBTYPE_EGA, KD_EGA }, + { FBTYPE_VGA, KD_VGA }, + { FBTYPE_PC98, KD_PC98 }, + { FBTYPE_TGA, KD_TGA }, + }; + int i; + + for (i = 0; i < sizeof(types)/sizeof(types[0]); ++i) { + if (types[i].va_type == adp_type) + return types[i].fb_type; + } + return -1; +} + +int +fb_commonioctl(video_adapter_t *adp, u_long cmd, caddr_t arg) +{ + int error; + int s; + + /* assert(adp != NULL) */ + + error = 0; + s = spltty(); + + switch (cmd) { + + case FBIO_ADAPTER: /* get video adapter index */ + *(int *)arg = adp->va_index; + break; + + case FBIO_ADPTYPE: /* get video adapter type */ + *(int *)arg = adp->va_type; + break; + + case FBIO_ADPINFO: /* get video adapter info */ + ((video_adapter_info_t *)arg)->va_index = adp->va_index; + ((video_adapter_info_t *)arg)->va_type = adp->va_type; + bcopy(adp->va_name, ((video_adapter_info_t *)arg)->va_name, + imin(strlen(adp->va_name) + 1, + sizeof(((video_adapter_info_t *)arg)->va_name))); + ((video_adapter_info_t *)arg)->va_unit = adp->va_unit; + ((video_adapter_info_t *)arg)->va_flags = adp->va_flags; + ((video_adapter_info_t *)arg)->va_io_base = adp->va_io_base; + ((video_adapter_info_t *)arg)->va_io_size = adp->va_io_size; + ((video_adapter_info_t *)arg)->va_crtc_addr = adp->va_crtc_addr; + ((video_adapter_info_t *)arg)->va_mem_base = adp->va_mem_base; + ((video_adapter_info_t *)arg)->va_mem_size = adp->va_mem_size; + ((video_adapter_info_t *)arg)->va_window + = vtophys(adp->va_window); + ((video_adapter_info_t *)arg)->va_window_size + = adp->va_window_size; + ((video_adapter_info_t *)arg)->va_window_gran + = adp->va_window_gran; + ((video_adapter_info_t *)arg)->va_window_orig + = adp->va_window_orig; + ((video_adapter_info_t *)arg)->va_unused0 + = (adp->va_buffer) ? vtophys(adp->va_buffer) : 0; + ((video_adapter_info_t *)arg)->va_buffer_size + = adp->va_buffer_size; + ((video_adapter_info_t *)arg)->va_mode = adp->va_mode; + ((video_adapter_info_t *)arg)->va_initial_mode + = adp->va_initial_mode; + ((video_adapter_info_t *)arg)->va_initial_bios_mode + = adp->va_initial_bios_mode; + ((video_adapter_info_t *)arg)->va_line_width + = adp->va_line_width; + ((video_adapter_info_t *)arg)->va_disp_start.x + = adp->va_disp_start.x; + ((video_adapter_info_t *)arg)->va_disp_start.y + = adp->va_disp_start.y; + break; + + case FBIO_MODEINFO: /* get mode information */ + error = (*vidsw[adp->va_index]->get_info)(adp, + ((video_info_t *)arg)->vi_mode, + (video_info_t *)arg); + if (error) + error = ENODEV; + break; + + case FBIO_FINDMODE: /* find a matching video mode */ + error = (*vidsw[adp->va_index]->query_mode)(adp, + (video_info_t *)arg); + if (error < 0) { + error = EINVAL; + } else { + error = (*vidsw[adp->va_index]->get_info)(adp, + error, (video_info_t *)arg); + if (error) + error = ENODEV; /* shouldn't happen */ + } + break; + + case FBIO_GETMODE: /* get video mode */ + *(int *)arg = adp->va_mode; + break; + + case FBIO_SETMODE: /* set video mode */ + error = (*vidsw[adp->va_index]->set_mode)(adp, *(int *)arg); + if (error) + error = ENODEV; /* EINVAL? */ + break; + + case FBIO_GETWINORG: /* get frame buffer window origin */ + *(u_int *)arg = adp->va_window_orig; + break; + + case FBIO_GETDISPSTART: /* get display start address */ + ((video_display_start_t *)arg)->x = adp->va_disp_start.x; + ((video_display_start_t *)arg)->y = adp->va_disp_start.y; + break; + + case FBIO_GETLINEWIDTH: /* get scan line width in bytes */ + *(u_int *)arg = adp->va_line_width; + break; + + case FBIO_GETPALETTE: /* get color palette */ + case FBIO_SETPALETTE: /* set color palette */ + /* XXX */ + + case FBIOPUTCMAP: + case FBIOGETCMAP: + /* XXX */ + + case FBIO_SETWINORG: /* set frame buffer window origin */ + case FBIO_SETDISPSTART: /* set display start address */ + case FBIO_SETLINEWIDTH: /* set scan line width in pixel */ + + case FBIOGTYPE: + case FBIOGATTR: + case FBIOSVIDEO: + case FBIOGVIDEO: + case FBIOSCURSOR: + case FBIOGCURSOR: + case FBIOSCURPOS: + case FBIOGCURPOS: + case FBIOGCURMAX: + + default: + error = ENODEV; + break; + } + + splx(s); + return error; +} diff --git a/sys/dev/fb/fbreg.h b/sys/dev/fb/fbreg.h index 561ac57..ff13bd8 100644 --- a/sys/dev/fb/fbreg.h +++ b/sys/dev/fb/fbreg.h @@ -23,7 +23,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: fbreg.h,v 1.2 1999/01/19 11:31:11 yokota Exp $ + * $Id: fbreg.h,v 1.3 1999/04/12 13:34:56 des Exp $ */ #ifndef _DEV_FB_FBREG_H_ @@ -35,15 +35,22 @@ /* some macros */ #ifdef __i386__ -#define bcopy_toio(s, d, c) generic_bcopy((void *)(s), (void *)(d), c) -#define bcopy_fromio(s, d, c) generic_bcopy((void *)(s), (void *)(d), c) -#define bzero_io(d, c) generic_bzero((void *)(d), c) +#define bcopy_io(s, d, c) generic_bcopy((void *)(s), (void *)(d), (c)) +#define bcopy_toio(s, d, c) generic_bcopy((void *)(s), (void *)(d), (c)) +#define bcopy_fromio(s, d, c) generic_bcopy((void *)(s), (void *)(d), (c)) +#define bzero_io(d, c) generic_bzero((void *)(d), (c)) +#define fill_io(p, d, c) fill((p), (void *)(d), (c)) +#define fillw_io(p, d, c) fillw((p), (void *)(d), (c)) void generic_bcopy(const void *s, void *d, size_t c); void generic_bzero(void *d, size_t c); #else /* !__i386__ */ -#define bcopy_toio(s, d, c) memcpy_toio(d, s, c) -#define bcopy_fromio(s, d, c) memcpy_fromio(d, s, c) -#define bzero_io(d, c) memset_io(d, 0, c) +#define bcopy_io(s, d, c) memcpy_io((d), (s), (c)) +#define bcopy_toio(s, d, c) memcpy_toio((d), (void *)(s), (c)) +#define bcopy_fromio(s, d, c) memcpy_fromio((void *)(d), (s), (c)) +#define bzero_io(d, c) memset_io((d), 0, (c)) +#define fill_io(p, d, c) memset_io((d), (p), (c)) +#define fillw(p, d, c) memsetw((d), (p), (c)) +#define fillw_io(p, d, c) memsetw_io((d), (p), (c)) #endif /* !__i386__ */ /* video function table */ @@ -68,12 +75,16 @@ typedef int vi_set_hw_cursor_t(video_adapter_t *adp, int col, int row); typedef int vi_set_hw_cursor_shape_t(video_adapter_t *adp, int base, int height, int celsize, int blink); typedef int vi_blank_display_t(video_adapter_t *adp, int mode); -#define V_DISPLAY_POWER_ON 0 -#define V_DISPLAY_SUSPEND 1 -#define V_DISPLAY_SUSPEND1 1 -#define V_DISPLAY_SUSPEND2 2 -#define V_DISPLAY_POWER_OFF 3 -typedef int vi_mmap_t(video_adapter_t *adp, vm_offset_t offset); +#define V_DISPLAY_ON 0 +#define V_DISPLAY_BLANK 1 +#define V_DISPLAY_STAND_BY 2 +#define V_DISPLAY_SUSPEND 3 +typedef int vi_mmap_t(video_adapter_t *adp, vm_offset_t offset, int prot); +typedef int vi_ioctl_t(video_adapter_t *adp, u_long cmd, caddr_t data); +typedef int vi_clear_t(video_adapter_t *adp); +typedef int vi_fill_rect_t(video_adapter_t *adp, int val, int x, int y, + int cx, int cy); +typedef int vi_bitblt_t(video_adapter_t *adp,...); typedef int vi_diag_t(video_adapter_t *adp, int level); typedef struct video_switch { @@ -96,6 +107,12 @@ typedef struct video_switch { vi_set_hw_cursor_shape_t *set_hw_cursor_shape; vi_blank_display_t *blank_display; vi_mmap_t *mmap; + vi_ioctl_t *ioctl; + vi_clear_t *clear; + vi_fill_rect_t *fill_rect; + vi_bitblt_t *bitblt; + int (*reserved1)(void); + int (*reserved2)(void); vi_diag_t *diag; } video_switch_t; @@ -158,6 +175,26 @@ int fb_attach(dev_t dev, video_adapter_t *adp, int fb_detach(dev_t dev, video_adapter_t *adp, struct cdevsw *cdevsw); +/* generic frame buffer cdev driver functions */ + +typedef struct genfb_softc { + int gfb_flags; /* flag/status bits */ +#define FB_OPEN (1 << 0) +} genfb_softc_t; + +int genfbopen(genfb_softc_t *sc, video_adapter_t *adp, + int flag, int mode, struct proc *p); +int genfbclose(genfb_softc_t *sc, video_adapter_t *adp, + int flag, int mode, struct proc *p); +int genfbread(genfb_softc_t *sc, video_adapter_t *adp, + struct uio *uio, int flag); +int genfbwrite(genfb_softc_t *sc, video_adapter_t *adp, + struct uio *uio, int flag); +int genfbioctl(genfb_softc_t *sc, video_adapter_t *adp, + u_long cmd, caddr_t arg, int flag, struct proc *p); +int genfbmmap(genfb_softc_t *sc, video_adapter_t *adp, + vm_offset_t offset, int prot); + #endif /* FB_INSTALL_CDEV */ /* generic low-level driver functions */ @@ -165,6 +202,8 @@ int fb_detach(dev_t dev, video_adapter_t *adp, void fb_dump_adp_info(char *driver, video_adapter_t *adp, int level); void fb_dump_mode_info(char *driver, video_adapter_t *adp, video_info_t *info, int level); +int fb_type(int adp_type); +int fb_commonioctl(video_adapter_t *adp, u_long cmd, caddr_t arg); #endif /* KERNEL */ diff --git a/sys/dev/fb/splash.c b/sys/dev/fb/splash.c index e8f9cf2..40f1d01 100644 --- a/sys/dev/fb/splash.c +++ b/sys/dev/fb/splash.c @@ -35,8 +35,7 @@ #include <sys/kernel.h> #include <sys/malloc.h> #include <sys/linker.h> - -#include <machine/console.h> +#include <sys/fbio.h> #include <dev/fb/fbreg.h> #include <dev/fb/splashreg.h> @@ -51,7 +50,8 @@ static splash_decoder_t **decoder_set; #define DECODER_ARRAY_DELTA 4 /* console driver callback */ -static int (*splash_callback)(int); +static int (*splash_callback)(int, void *); +static void *splash_arg; static int splash_find_data(splash_decoder_t *decoder) @@ -98,7 +98,7 @@ splash_new(splash_decoder_t *decoder) { splash_decoder = decoder; if (splash_callback != NULL) - (*splash_callback)(SPLASH_INIT); + (*splash_callback)(SPLASH_INIT, splash_arg); } int @@ -159,12 +159,13 @@ splash_unregister(splash_decoder_t *decoder) } int -splash_init(video_adapter_t *adp, int (*callback)(int)) +splash_init(video_adapter_t *adp, int (*callback)(int, void *), void *arg) { int i; splash_adp = adp; splash_callback = callback; + splash_arg = arg; splash_decoder = NULL; for (i = 0; i < decoders; ++i) { @@ -187,9 +188,11 @@ splash_term(video_adapter_t *adp) { int error = 0; + if (splash_adp != adp) + return EINVAL; if (splash_decoder != NULL) { if (splash_callback != NULL) - error = (*splash_callback)(SPLASH_TERM); + error = (*splash_callback)(SPLASH_TERM, splash_arg); if (error == 0) error = (*splash_decoder->term)(adp); if (error == 0) diff --git a/sys/dev/fb/splash_bmp.c b/sys/dev/fb/splash_bmp.c index 44ac914..6de5a28 100644 --- a/sys/dev/fb/splash_bmp.c +++ b/sys/dev/fb/splash_bmp.c @@ -24,15 +24,14 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: splash_bmp.c,v 1.7 1999/03/29 15:13:53 yokota Exp $ + * $Id: splash_bmp.c,v 1.8 1999/06/16 14:04:45 yokota Exp $ */ #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> #include <sys/linker.h> - -#include <machine/console.h> +#include <sys/fbio.h> #include <dev/fb/fbreg.h> #include <dev/fb/splashreg.h> diff --git a/sys/dev/fb/splash_pcx.c b/sys/dev/fb/splash_pcx.c index 3066bb3..5423295 100644 --- a/sys/dev/fb/splash_pcx.c +++ b/sys/dev/fb/splash_pcx.c @@ -27,15 +27,14 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id$ + * $Id: splash_pcx.c,v 1.1 1999/04/12 13:39:11 des Exp $ */ #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> #include <sys/linker.h> - -#include <machine/console.h> +#include <sys/fbio.h> #include <dev/fb/fbreg.h> #include <dev/fb/splashreg.h> diff --git a/sys/dev/fb/splashreg.h b/sys/dev/fb/splashreg.h index fb78534..a34a3b9 100644 --- a/sys/dev/fb/splashreg.h +++ b/sys/dev/fb/splashreg.h @@ -23,7 +23,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: splashreg.h,v 1.1 1999/01/09 02:44:49 yokota Exp $ + * $Id: splashreg.h,v 1.2 1999/01/11 03:06:28 yokota Exp $ */ #ifndef _DEV_FB_SPLASHREG_H_ @@ -91,7 +91,8 @@ int splash_register(splash_decoder_t *decoder); int splash_unregister(splash_decoder_t *decoder); /* entry points for the console driver */ -int splash_init(video_adapter_t *adp, int (*callback)(int)); +int splash_init(video_adapter_t *adp, int (*callback)(int, void *), + void *arg); int splash_term(video_adapter_t *adp); int splash(video_adapter_t *adp, int on); diff --git a/sys/dev/fb/vga.c b/sys/dev/fb/vga.c new file mode 100644 index 0000000..91f99e9 --- /dev/null +++ b/sys/dev/fb/vga.c @@ -0,0 +1,3041 @@ +/*- + * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp> + * Copyright (c) 1992-1998 Søren Schmidt + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer as + * the first lines of this file unmodified. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Id: $ + */ + +#include "vga.h" +#include "opt_vga.h" +#include "opt_fb.h" +#include "opt_syscons.h" /* should be removed in the future, XXX */ + +#if NVGA > 0 + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/conf.h> +#include <sys/proc.h> +#include <sys/fcntl.h> +#include <sys/malloc.h> +#include <sys/fbio.h> + +#include <vm/vm.h> +#include <vm/vm_param.h> +#include <vm/pmap.h> + +#include <machine/md_var.h> +#include <machine/pc/bios.h> + +#include <dev/fb/fbreg.h> +#include <dev/fb/vgareg.h> + +#include <isa/isareg.h> + +#ifndef VGA_DEBUG +#define VGA_DEBUG 0 +#endif + +int +vga_probe_unit(int unit, video_adapter_t *buf, int flags) +{ + video_adapter_t *adp; + video_switch_t *sw; + int error; + + sw = vid_get_switch(VGA_DRIVER_NAME); + if (sw == NULL) + return 0; + error = (*sw->probe)(unit, &adp, NULL, flags); + if (error) + return error; + bcopy(adp, buf, sizeof(*buf)); + return 0; +} + +int +vga_attach_unit(int unit, vga_softc_t *sc, int flags) +{ + video_switch_t *sw; + int error; + + sw = vid_get_switch(VGA_DRIVER_NAME); + if (sw == NULL) + return ENXIO; + + error = (*sw->probe)(unit, &sc->adp, NULL, flags); + if (error) + return error; + return (*sw->init)(unit, sc->adp, flags); +} + +/* cdev driver functions */ + +#ifdef FB_INSTALL_CDEV + +int +vga_open(dev_t dev, vga_softc_t *sc, int flag, int mode, struct proc *p) +{ + if (sc == NULL) + return ENXIO; + if (mode & (O_CREAT | O_APPEND | O_TRUNC)) + return ENODEV; + + return genfbopen(&sc->gensc, sc->adp, flag, mode, p); +} + +int +vga_close(dev_t dev, vga_softc_t *sc, int flag, int mode, struct proc *p) +{ + return genfbclose(&sc->gensc, sc->adp, flag, mode, p); +} + +int +vga_read(dev_t dev, vga_softc_t *sc, struct uio *uio, int flag) +{ + return genfbread(&sc->gensc, sc->adp, uio, flag); +} + +int +vga_write(dev_t dev, vga_softc_t *sc, struct uio *uio, int flag) +{ + return genfbread(&sc->gensc, sc->adp, uio, flag); +} + +int +vga_ioctl(dev_t dev, vga_softc_t *sc, u_long cmd, caddr_t arg, int flag, + struct proc *p) +{ + return genfbioctl(&sc->gensc, sc->adp, cmd, arg, flag, p); +} + +int +vga_mmap(dev_t dev, vga_softc_t *sc, vm_offset_t offset, int prot) +{ + return genfbmmap(&sc->gensc, sc->adp, offset, prot); +} + +#endif /* FB_INSTALL_CDEV */ + +/* LOW-LEVEL */ + +#include <machine/clock.h> +#include <machine/pc/vesa.h> + +#define probe_done(adp) ((adp)->va_flags & V_ADP_PROBED) +#define init_done(adp) ((adp)->va_flags & V_ADP_INITIALIZED) +#define config_done(adp) ((adp)->va_flags & V_ADP_REGISTERED) + +/* for compatibility with old kernel options */ +#ifdef SC_ALT_SEQACCESS +#undef SC_ALT_SEQACCESS +#undef VGA_ALT_SEQACCESS +#define VGA_ALT_SEQACCESS 1 +#endif + +#ifdef SLOW_VGA +#undef SLOW_VGA +#undef VGA_SLOW_IOACCESS +#define VGA_SLOW_IOACCESS 1 +#endif + +/* architecture dependent option */ +#ifdef __alpha__ +#define VGA_NO_BIOS 1 +#endif + +/* this should really be in `rtc.h' */ +#define RTC_EQUIPMENT 0x14 + +/* various sizes */ +#define V_MODE_MAP_SIZE (M_VGA_CG320 + 1) +#define V_MODE_PARAM_SIZE 64 + +/* video adapter state buffer */ +struct adp_state { + int sig; +#define V_STATE_SIG 0x736f6962 + u_char regs[V_MODE_PARAM_SIZE]; +}; +typedef struct adp_state adp_state_t; + +/* video adapter information */ +#define DCC_MONO 0 +#define DCC_CGA40 1 +#define DCC_CGA80 2 +#define DCC_EGAMONO 3 +#define DCC_EGA40 4 +#define DCC_EGA80 5 + +/* + * NOTE: `va_window' should have a virtual address, but is initialized + * with a physical address in the following table, as verify_adapter() + * will perform address conversion at run-time. + */ +static video_adapter_t adapter_init_value[] = { + /* DCC_MONO */ + { 0, KD_MONO, "mda", 0, 0, 0, IO_MDA, IO_MDASIZE, MONO_CRTC, + MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE, + 0, 0, 0, 0, 7, 0, }, + /* DCC_CGA40 */ + { 0, KD_CGA, "cga", 0, 0, V_ADP_COLOR, IO_CGA, IO_CGASIZE, COLOR_CRTC, + CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, + 0, 0, 0, 0, 3, 0, }, + /* DCC_CGA80 */ + { 0, KD_CGA, "cga", 0, 0, V_ADP_COLOR, IO_CGA, IO_CGASIZE, COLOR_CRTC, + CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, + 0, 0, 0, 0, 3, 0, }, + /* DCC_EGAMONO */ + { 0, KD_EGA, "ega", 0, 0, 0, IO_MDA, 48, MONO_CRTC, + EGA_BUF_BASE, EGA_BUF_SIZE, MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE, + 0, 0, 0, 0, 7, 0, }, + /* DCC_EGA40 */ + { 0, KD_EGA, "ega", 0, 0, V_ADP_COLOR, IO_MDA, 48, COLOR_CRTC, + EGA_BUF_BASE, EGA_BUF_SIZE, CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, + 0, 0, 0, 0, 3, 0, }, + /* DCC_EGA80 */ + { 0, KD_EGA, "ega", 0, 0, V_ADP_COLOR, IO_MDA, 48, COLOR_CRTC, + EGA_BUF_BASE, EGA_BUF_SIZE, CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, + 0, 0, 0, 0, 3, 0, }, +}; + +static video_adapter_t biosadapter[2]; +static int biosadapters = 0; + +/* video driver declarations */ +static int vga_configure(int flags); + int (*vga_sub_configure)(int flags); +static int vga_nop(void); +static int vga_error(void); +static vi_probe_t vga_probe; +static vi_init_t vga_init; +static vi_get_info_t vga_get_info; +static vi_query_mode_t vga_query_mode; +static vi_set_mode_t vga_set_mode; +static vi_save_font_t vga_save_font; +static vi_load_font_t vga_load_font; +static vi_show_font_t vga_show_font; +static vi_save_palette_t vga_save_palette; +static vi_load_palette_t vga_load_palette; +static vi_set_border_t vga_set_border; +static vi_save_state_t vga_save_state; +static vi_load_state_t vga_load_state; +static vi_set_win_org_t vga_set_origin; +static vi_read_hw_cursor_t vga_read_hw_cursor; +static vi_set_hw_cursor_t vga_set_hw_cursor; +static vi_set_hw_cursor_shape_t vga_set_hw_cursor_shape; +static vi_blank_display_t vga_blank_display; +static vi_mmap_t vga_mmap_buf; +static vi_ioctl_t vga_dev_ioctl; +#ifndef VGA_NO_MODE_CHANGE +static vi_clear_t vga_clear; +static vi_fill_rect_t vga_fill_rect; +static vi_bitblt_t vga_bitblt; +#else /* VGA_NO_MODE_CHANGE */ +#define vga_clear (vi_clear_t *)vga_error +#define vga_fill_rect (vi_fill_rect_t *)vga_error +#define vga_bitblt (vi_bitblt_t *)vga_error +#endif +static vi_diag_t vga_diag; + +static video_switch_t vgavidsw = { + vga_probe, + vga_init, + vga_get_info, + vga_query_mode, + vga_set_mode, + vga_save_font, + vga_load_font, + vga_show_font, + vga_save_palette, + vga_load_palette, + vga_set_border, + vga_save_state, + vga_load_state, + vga_set_origin, + vga_read_hw_cursor, + vga_set_hw_cursor, + vga_set_hw_cursor_shape, + vga_blank_display, + vga_mmap_buf, + vga_dev_ioctl, + vga_clear, + vga_fill_rect, + vga_bitblt, + vga_error, + vga_error, + vga_diag, +}; + +VIDEO_DRIVER(mda, vgavidsw, NULL); +VIDEO_DRIVER(cga, vgavidsw, NULL); +VIDEO_DRIVER(ega, vgavidsw, NULL); +VIDEO_DRIVER(vga, vgavidsw, vga_configure); + +/* VGA BIOS standard video modes */ +#define EOT (-1) +#define NA (-2) + +static video_info_t bios_vmode[] = { + /* CGA */ + { M_B40x25, V_INFO_COLOR, 40, 25, 8, 8, 2, 1, + CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, + { M_C40x25, V_INFO_COLOR, 40, 25, 8, 8, 4, 1, + CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, + { M_B80x25, V_INFO_COLOR, 80, 25, 8, 8, 2, 1, + CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, + { M_C80x25, V_INFO_COLOR, 80, 25, 8, 8, 4, 1, + CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, + /* EGA */ + { M_ENH_B40x25, V_INFO_COLOR, 40, 25, 8, 14, 2, 1, + CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, + { M_ENH_C40x25, V_INFO_COLOR, 40, 25, 8, 14, 4, 1, + CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, + { M_ENH_B80x25, V_INFO_COLOR, 80, 25, 8, 14, 2, 1, + CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, + { M_ENH_C80x25, V_INFO_COLOR, 80, 25, 8, 14, 4, 1, + CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, + /* VGA */ + { M_VGA_C40x25, V_INFO_COLOR, 40, 25, 8, 16, 4, 1, + CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, + { M_VGA_M80x25, 0, 80, 25, 8, 16, 2, 1, + MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, + { M_VGA_C80x25, V_INFO_COLOR, 80, 25, 8, 16, 4, 1, + CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, + /* MDA */ + { M_EGAMONO80x25, 0, 80, 25, 8, 14, 2, 1, + MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, + /* EGA */ + { M_ENH_B80x43, 0, 80, 43, 8, 8, 2, 1, + CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, + { M_ENH_C80x43, V_INFO_COLOR, 80, 43, 8, 8, 4, 1, + CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, + /* VGA */ + { M_VGA_M80x30, 0, 80, 30, 8, 16, 2, 1, + MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, + { M_VGA_C80x30, V_INFO_COLOR, 80, 30, 8, 16, 4, 1, + CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, + { M_VGA_M80x50, 0, 80, 50, 8, 8, 2, 1, + MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, + { M_VGA_C80x50, V_INFO_COLOR, 80, 50, 8, 8, 4, 1, + CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, + { M_VGA_M80x60, 0, 80, 60, 8, 8, 2, 1, + MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, + { M_VGA_C80x60, V_INFO_COLOR, 80, 60, 8, 8, 4, 1, + CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, + +#ifndef VGA_NO_MODE_CHANGE + +#ifdef VGA_WIDTH90 + { M_VGA_M90x25, 0, 90, 25, 8, 16, 2, 1, + MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, + { M_VGA_C90x25, V_INFO_COLOR, 90, 25, 8, 16, 4, 1, + CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, + { M_VGA_M90x30, 0, 90, 30, 8, 16, 2, 1, + MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, + { M_VGA_C90x30, V_INFO_COLOR, 90, 30, 8, 16, 4, 1, + CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, + { M_VGA_M90x43, 0, 90, 43, 8, 8, 2, 1, + CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, + { M_VGA_C90x43, V_INFO_COLOR, 90, 43, 8, 8, 4, 1, + CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, + { M_VGA_M90x50, 0, 90, 50, 8, 8, 2, 1, + MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, + { M_VGA_C90x50, V_INFO_COLOR, 90, 50, 8, 8, 4, 1, + CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, + { M_VGA_M90x60, 0, 90, 60, 8, 8, 2, 1, + MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, + { M_VGA_C90x60, V_INFO_COLOR, 90, 60, 8, 8, 4, 1, + CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, +#endif /* VGA_WIDTH90 */ + + /* CGA */ + { M_BG320, V_INFO_COLOR | V_INFO_GRAPHICS, 320, 200, 8, 8, 2, 1, + CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_CGA }, + { M_CG320, V_INFO_COLOR | V_INFO_GRAPHICS, 320, 200, 8, 8, 2, 1, + CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_CGA }, + { M_BG640, V_INFO_COLOR | V_INFO_GRAPHICS, 640, 200, 8, 8, 1, 1, + CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_CGA }, + /* EGA */ + { M_CG320_D, V_INFO_COLOR | V_INFO_GRAPHICS, 320, 200, 8, 8, 4, 4, + GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0, + V_INFO_MM_PLANAR }, + { M_CG640_E, V_INFO_COLOR | V_INFO_GRAPHICS, 640, 200, 8, 8, 4, 4, + GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0 , + V_INFO_MM_PLANAR }, + { M_EGAMONOAPA, V_INFO_GRAPHICS, 640, 350, 8, 14, 4, 4, + GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, 64*1024, 0, 0 , + V_INFO_MM_PLANAR }, + { M_ENHMONOAPA2,V_INFO_GRAPHICS, 640, 350, 8, 14, 4, 4, + GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0 , + V_INFO_MM_PLANAR }, + { M_CG640x350, V_INFO_COLOR | V_INFO_GRAPHICS, 640, 350, 8, 14, 2, 2, + GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0 , + V_INFO_MM_PLANAR }, + { M_ENH_CG640, V_INFO_COLOR | V_INFO_GRAPHICS, 640, 350, 8, 14, 4, 4, + GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0 , + V_INFO_MM_PLANAR }, + /* VGA */ + { M_BG640x480, V_INFO_COLOR | V_INFO_GRAPHICS, 640, 480, 8, 16, 4, 4, + GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0 , + V_INFO_MM_PLANAR }, + { M_CG640x480, V_INFO_COLOR | V_INFO_GRAPHICS, 640, 480, 8, 16, 4, 4, + GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0 , + V_INFO_MM_PLANAR }, + { M_VGA_CG320, V_INFO_COLOR | V_INFO_GRAPHICS, 320, 200, 8, 8, 8, 1, + GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0, + V_INFO_MM_PACKED, 1 }, + { M_VGA_MODEX, V_INFO_COLOR | V_INFO_GRAPHICS, 320, 240, 8, 8, 8, 1, + GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0, + V_INFO_MM_PACKED, 1 }, +#endif /* VGA_NO_MODE_CHANGE */ + + { EOT }, +}; + +static int vga_init_done = FALSE; +#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE) +static u_char *video_mode_ptr = NULL; /* EGA/VGA */ +static u_char *video_mode_ptr2 = NULL; /* CGA/MDA */ +#endif +static u_char *mode_map[V_MODE_MAP_SIZE]; +static adp_state_t adpstate; +static adp_state_t adpstate2; +static int rows_offset = 1; + +/* local macros and functions */ +#define BIOS_SADDRTOLADDR(p) ((((p) & 0xffff0000) >> 12) + ((p) & 0x0000ffff)) + +#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE) +static void map_mode_table(u_char *map[], u_char *table, int max); +#endif +static void clear_mode_map(video_adapter_t *adp, u_char *map[], int max, + int color); +#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE) +static int map_mode_num(int mode); +#endif +static int map_gen_mode_num(int type, int color, int mode); +static int map_bios_mode_num(int type, int color, int bios_mode); +static u_char *get_mode_param(int mode); +#ifndef VGA_NO_BIOS +static void fill_adapter_param(int code, video_adapter_t *adp); +#endif +static int verify_adapter(video_adapter_t *adp); +static void update_adapter_info(video_adapter_t *adp, video_info_t *info); +#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE) +#define COMP_IDENTICAL 0 +#define COMP_SIMILAR 1 +#define COMP_DIFFERENT 2 +static int comp_adpregs(u_char *buf1, u_char *buf2); +#endif +static int probe_adapters(void); +static int set_line_length(video_adapter_t *adp, int pixel); +static int set_display_start(video_adapter_t *adp, int x, int y); +static void filll_io(int val, vm_offset_t d, size_t size); + +#ifndef VGA_NO_MODE_CHANGE +#ifdef VGA_WIDTH90 +static void set_width90(adp_state_t *params); +#endif +#endif /* !VGA_NO_MODE_CHANGE */ + +#ifndef VGA_NO_FONT_LOADING +#define PARAM_BUFSIZE 6 +static void set_font_mode(video_adapter_t *adp, u_char *buf); +static void set_normal_mode(video_adapter_t *adp, u_char *buf); +#endif + +#ifndef VGA_NO_MODE_CHANGE +static void planar_fill(video_adapter_t *adp, int val); +static void packed_fill(video_adapter_t *adp, int val); +static void direct_fill(video_adapter_t *adp, int val); +#ifdef notyet +static void planar_fill_rect(video_adapter_t *adp, int val, int x, int y, + int cx, int cy); +static void packed_fill_rect(video_adapter_t *adp, int val, int x, int y, + int cx, int cy); +static void direct_fill_rect16(video_adapter_t *adp, int val, int x, int y, + int cx, int cy); +static void direct_fill_rect24(video_adapter_t *adp, int val, int x, int y, + int cx, int cy); +static void direct_fill_rect32(video_adapter_t *adp, int val, int x, int y, + int cx, int cy); +#endif /* notyet */ +#endif /* !VGA_NO_MODE_CHANGE */ + +static void dump_buffer(u_char *buf, size_t len); + +#define ISMAPPED(pa, width) \ + (((pa) <= (u_long)0x1000 - (width)) \ + || ((pa) >= ISA_HOLE_START && (pa) <= 0x100000 - (width))) + +#define prologue(adp, flag, err) \ + if (!vga_init_done || !((adp)->va_flags & (flag))) \ + return (err) + +/* a backdoor for the console driver */ +static int +vga_configure(int flags) +{ + int i; + + probe_adapters(); + for (i = 0; i < biosadapters; ++i) { + if (!probe_done(&biosadapter[i])) + continue; + biosadapter[i].va_flags |= V_ADP_INITIALIZED; + if (!config_done(&biosadapter[i])) { + if (vid_register(&biosadapter[i]) < 0) + continue; + biosadapter[i].va_flags |= V_ADP_REGISTERED; + } + } + if (vga_sub_configure != NULL) + (*vga_sub_configure)(flags); + + return biosadapters; +} + +/* local subroutines */ + +#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE) +/* construct the mode parameter map */ +static void +map_mode_table(u_char *map[], u_char *table, int max) +{ + int i; + + for(i = 0; i < max; ++i) + map[i] = table + i*V_MODE_PARAM_SIZE; + for(; i < V_MODE_MAP_SIZE; ++i) + map[i] = NULL; +} +#endif /* !VGA_NO_BIOS && !VGA_NO_MODE_CHANGE */ + +static void +clear_mode_map(video_adapter_t *adp, u_char *map[], int max, int color) +{ + video_info_t info; + int i; + + /* + * NOTE: we don't touch `bios_vmode[]' because it is shared + * by all adapters. + */ + for(i = 0; i < max; ++i) { + if (vga_get_info(adp, i, &info)) + continue; + if ((info.vi_flags & V_INFO_COLOR) != color) + map[i] = NULL; + } +} + +#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE) +/* map the non-standard video mode to a known mode number */ +static int +map_mode_num(int mode) +{ + static struct { + int from; + int to; + } mode_map[] = { + { M_ENH_B80x43, M_ENH_B80x25 }, + { M_ENH_C80x43, M_ENH_C80x25 }, + { M_VGA_M80x30, M_VGA_M80x25 }, + { M_VGA_C80x30, M_VGA_C80x25 }, + { M_VGA_M80x50, M_VGA_M80x25 }, + { M_VGA_C80x50, M_VGA_C80x25 }, + { M_VGA_M80x60, M_VGA_M80x25 }, + { M_VGA_C80x60, M_VGA_C80x25 }, +#ifdef VGA_WIDTH90 + { M_VGA_M90x25, M_VGA_M80x25 }, + { M_VGA_C90x25, M_VGA_C80x25 }, + { M_VGA_M90x30, M_VGA_M80x25 }, + { M_VGA_C90x30, M_VGA_C80x25 }, + { M_VGA_M90x43, M_ENH_B80x25 }, + { M_VGA_C90x43, M_ENH_C80x25 }, + { M_VGA_M90x50, M_VGA_M80x25 }, + { M_VGA_C90x50, M_VGA_C80x25 }, + { M_VGA_M90x60, M_VGA_M80x25 }, + { M_VGA_C90x60, M_VGA_C80x25 }, +#endif + { M_VGA_MODEX, M_VGA_CG320 }, + }; + int i; + + for (i = 0; i < sizeof(mode_map)/sizeof(mode_map[0]); ++i) { + if (mode_map[i].from == mode) + return mode_map[i].to; + } + return mode; +} +#endif /* !VGA_NO_BIOS && !VGA_NO_MODE_CHANGE */ + +/* map a generic video mode to a known mode number */ +static int +map_gen_mode_num(int type, int color, int mode) +{ + static struct { + int from; + int to_color; + int to_mono; + } mode_map[] = { + { M_TEXT_80x30, M_VGA_C80x30, M_VGA_M80x30, }, + { M_TEXT_80x43, M_ENH_C80x43, M_ENH_B80x43, }, + { M_TEXT_80x50, M_VGA_C80x50, M_VGA_M80x50, }, + { M_TEXT_80x60, M_VGA_C80x60, M_VGA_M80x60, }, + }; + int i; + + if (mode == M_TEXT_80x25) { + switch (type) { + + case KD_VGA: + if (color) + return M_VGA_C80x25; + else + return M_VGA_M80x25; + break; + + case KD_EGA: + if (color) + return M_ENH_C80x25; + else + return M_EGAMONO80x25; + break; + + case KD_CGA: + return M_C80x25; + + case KD_MONO: + case KD_HERCULES: + return M_EGAMONO80x25; /* XXX: this name is confusing */ + + default: + return -1; + } + } + + for (i = 0; i < sizeof(mode_map)/sizeof(mode_map[0]); ++i) { + if (mode_map[i].from == mode) + return ((color) ? mode_map[i].to_color : mode_map[i].to_mono); + } + return mode; +} + +/* turn the BIOS video number into our video mode number */ +static int +map_bios_mode_num(int type, int color, int bios_mode) +{ + static int cga_modes[7] = { + M_B40x25, M_C40x25, /* 0, 1 */ + M_B80x25, M_C80x25, /* 2, 3 */ + M_BG320, M_CG320, + M_BG640, + }; + static int ega_modes[17] = { + M_ENH_B40x25, M_ENH_C40x25, /* 0, 1 */ + M_ENH_B80x25, M_ENH_C80x25, /* 2, 3 */ + M_BG320, M_CG320, + M_BG640, + M_EGAMONO80x25, /* 7 */ + 8, 9, 10, 11, 12, + M_CG320_D, + M_CG640_E, + M_ENHMONOAPA2, /* XXX: video momery > 64K */ + M_ENH_CG640, /* XXX: video momery > 64K */ + }; + static int vga_modes[20] = { + M_VGA_C40x25, M_VGA_C40x25, /* 0, 1 */ + M_VGA_C80x25, M_VGA_C80x25, /* 2, 3 */ + M_BG320, M_CG320, + M_BG640, + M_VGA_M80x25, /* 7 */ + 8, 9, 10, 11, 12, + M_CG320_D, + M_CG640_E, + M_ENHMONOAPA2, + M_ENH_CG640, + M_BG640x480, M_CG640x480, + M_VGA_CG320, + }; + + switch (type) { + + case KD_VGA: + if (bios_mode < sizeof(vga_modes)/sizeof(vga_modes[0])) + return vga_modes[bios_mode]; + else if (color) + return M_VGA_C80x25; + else + return M_VGA_M80x25; + break; + + case KD_EGA: + if (bios_mode < sizeof(ega_modes)/sizeof(ega_modes[0])) + return ega_modes[bios_mode]; + else if (color) + return M_ENH_C80x25; + else + return M_EGAMONO80x25; + break; + + case KD_CGA: + if (bios_mode < sizeof(cga_modes)/sizeof(cga_modes[0])) + return cga_modes[bios_mode]; + else + return M_C80x25; + break; + + case KD_MONO: + case KD_HERCULES: + return M_EGAMONO80x25; /* XXX: this name is confusing */ + + default: + break; + } + return -1; +} + +/* look up a parameter table entry */ +static u_char +*get_mode_param(int mode) +{ +#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE) + if (mode >= V_MODE_MAP_SIZE) + mode = map_mode_num(mode); +#endif + if ((mode >= 0) && (mode < V_MODE_MAP_SIZE)) + return mode_map[mode]; + else + return NULL; +} + +#ifndef VGA_NO_BIOS +static void +fill_adapter_param(int code, video_adapter_t *adp) +{ + static struct { + int primary; + int secondary; + } dcc[] = { + { DCC_MONO, DCC_EGA40 /* CGA monitor */ }, + { DCC_MONO, DCC_EGA80 /* CGA monitor */ }, + { DCC_MONO, DCC_EGA80 /* CGA emulation */ }, + { DCC_MONO, DCC_EGA80 }, + { DCC_CGA40, DCC_EGAMONO }, + { DCC_CGA80, DCC_EGAMONO }, + { DCC_EGA40 /* CGA monitor */, DCC_MONO}, + { DCC_EGA80 /* CGA monitor */, DCC_MONO}, + { DCC_EGA80 /* CGA emulation */,DCC_MONO }, + { DCC_EGA80, DCC_MONO }, + { DCC_EGAMONO, DCC_CGA40 }, + { DCC_EGAMONO, DCC_CGA40 }, + }; + + if ((code < 0) || (code >= sizeof(dcc)/sizeof(dcc[0]))) { + adp[V_ADP_PRIMARY] = adapter_init_value[DCC_MONO]; + adp[V_ADP_SECONDARY] = adapter_init_value[DCC_CGA80]; + } else { + adp[V_ADP_PRIMARY] = adapter_init_value[dcc[code].primary]; + adp[V_ADP_SECONDARY] = adapter_init_value[dcc[code].secondary]; + } +} +#endif /* VGA_NO_BIOS */ + +static int +verify_adapter(video_adapter_t *adp) +{ + vm_offset_t buf; + u_int16_t v; +#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE) + u_int32_t p; +#endif + + buf = BIOS_PADDRTOVADDR(adp->va_window); + v = readw(buf); + writew(buf, 0xA55A); + if (readw(buf) != 0xA55A) + return ENXIO; + writew(buf, v); + + switch (adp->va_type) { + + case KD_EGA: + outb(adp->va_crtc_addr, 7); + if (inb(adp->va_crtc_addr) == 7) { + adp->va_type = KD_VGA; + adp->va_name = "vga"; + adp->va_flags |= V_ADP_STATESAVE | V_ADP_PALETTE; + } + adp->va_flags |= V_ADP_STATELOAD | V_ADP_BORDER; + /* the color adapter may be in the 40x25 mode... XXX */ + +#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE) + /* get the BIOS video mode pointer */ + p = *(u_int32_t *)BIOS_PADDRTOVADDR(0x4a8); + p = BIOS_SADDRTOLADDR(p); + if (ISMAPPED(p, sizeof(u_int32_t))) { + p = *(u_int32_t *)BIOS_PADDRTOVADDR(p); + p = BIOS_SADDRTOLADDR(p); + if (ISMAPPED(p, V_MODE_PARAM_SIZE)) + video_mode_ptr = (u_char *)BIOS_PADDRTOVADDR(p); + } +#endif + break; + + case KD_CGA: + adp->va_flags |= V_ADP_COLOR | V_ADP_BORDER; + /* may be in the 40x25 mode... XXX */ +#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE) + /* get the BIOS video mode pointer */ + p = *(u_int32_t *)BIOS_PADDRTOVADDR(0x1d*4); + p = BIOS_SADDRTOLADDR(p); + video_mode_ptr2 = (u_char *)BIOS_PADDRTOVADDR(p); +#endif + break; + + case KD_MONO: +#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE) + /* get the BIOS video mode pointer */ + p = *(u_int32_t *)BIOS_PADDRTOVADDR(0x1d*4); + p = BIOS_SADDRTOLADDR(p); + video_mode_ptr2 = (u_char *)BIOS_PADDRTOVADDR(p); +#endif + break; + } + + return 0; +} + +static void +update_adapter_info(video_adapter_t *adp, video_info_t *info) +{ + adp->va_flags &= ~V_ADP_COLOR; + adp->va_flags |= + (info->vi_flags & V_INFO_COLOR) ? V_ADP_COLOR : 0; + adp->va_crtc_addr = + (adp->va_flags & V_ADP_COLOR) ? COLOR_CRTC : MONO_CRTC; + adp->va_window = BIOS_PADDRTOVADDR(info->vi_window); + adp->va_window_size = info->vi_window_size; + adp->va_window_gran = info->vi_window_gran; + adp->va_window_orig = 0; + /* XXX */ + adp->va_buffer = info->vi_buffer; + adp->va_buffer_size = info->vi_buffer_size; + if (info->vi_flags & V_INFO_GRAPHICS) { + switch (info->vi_depth/info->vi_planes) { + case 1: + adp->va_line_width = info->vi_width/8; + break; + case 2: + adp->va_line_width = info->vi_width/4; + break; + case 4: + adp->va_line_width = info->vi_width/2; + break; + case 8: + default: /* shouldn't happen */ + adp->va_line_width = info->vi_width; + break; + } + } else { + adp->va_line_width = info->vi_width; + } + adp->va_disp_start.x = 0; + adp->va_disp_start.y = 0; + bcopy(info, &adp->va_info, sizeof(adp->va_info)); +} + +#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE) +/* compare two parameter table entries */ +static int +comp_adpregs(u_char *buf1, u_char *buf2) +{ + static struct { + u_char mask; + } params[V_MODE_PARAM_SIZE] = { + {0xff}, {0x00}, {0xff}, /* COLS}, ROWS}, POINTS */ + {0x00}, {0x00}, /* page length */ + {0xfe}, {0xff}, {0xff}, {0xff}, /* sequencer registers */ + {0xf3}, /* misc register */ + {0xff}, {0xff}, {0xff}, {0x7f}, {0xff}, /* CRTC */ + {0xff}, {0xff}, {0xff}, {0x7f}, {0xff}, + {0x00}, {0x00}, {0x00}, {0x00}, {0x00}, + {0x00}, {0xff}, {0x7f}, {0xff}, {0xff}, + {0x7f}, {0xff}, {0xff}, {0xef}, {0xff}, + {0xff}, {0xff}, {0xff}, {0xff}, {0xff}, /* attribute controller regs */ + {0xff}, {0xff}, {0xff}, {0xff}, {0xff}, + {0xff}, {0xff}, {0xff}, {0xff}, {0xff}, + {0xff}, {0xff}, {0xff}, {0xff}, {0xf0}, + {0xff}, {0xff}, {0xff}, {0xff}, {0xff}, /* GDC register */ + {0xff}, {0xff}, {0xff}, {0xff}, + }; + int identical = TRUE; + int i; + + if ((buf1 == NULL) || (buf2 == NULL)) + return COMP_DIFFERENT; + + for (i = 0; i < sizeof(params)/sizeof(params[0]); ++i) { + if (params[i].mask == 0) /* don't care */ + continue; + if ((buf1[i] & params[i].mask) != (buf2[i] & params[i].mask)) + return COMP_DIFFERENT; + if (buf1[i] != buf2[i]) + identical = FALSE; + } + return (identical) ? COMP_IDENTICAL : COMP_SIMILAR; +} +#endif /* !VGA_NO_BIOS && !VGA_NO_MODE_CHANGE */ + +/* probe video adapters and return the number of detected adapters */ +static int +probe_adapters(void) +{ + video_adapter_t *adp; + video_info_t info; +#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE) + u_char *mp; +#endif + int i; + + /* do this test only once */ + if (vga_init_done) + return biosadapters; + vga_init_done = TRUE; + + /* + * Locate display adapters. + * The AT architecture supports upto two adapters. `syscons' allows + * the following combinations of adapters: + * 1) MDA + CGA + * 2) MDA + EGA/VGA color + * 3) CGA + EGA/VGA mono + * Note that `syscons' doesn't bother with MCGA as it is only + * avaiable for low end PS/2 models which has 80286 or earlier CPUs, + * thus, they are not running FreeBSD! + * When there are two adapaters in the system, one becomes `primary' + * and the other `secondary'. The EGA adapter has a set of DIP + * switches on board for this information and the EGA BIOS copies + * it in the BIOS data area BIOSDATA_VIDEOSWITCH (40:88). + * The VGA BIOS has more sophisticated mechanism and has this + * information in BIOSDATA_DCCINDEX (40:8a), but it also maintains + * compatibility with the EGA BIOS by updating BIOSDATA_VIDEOSWITCH. + */ + + /* + * Check rtc and BIOS data area. + * XXX: we don't use BIOSDATA_EQUIPMENT, since it is not a dead + * copy of RTC_EQUIPMENT. Bits 4 and 5 of ETC_EQUIPMENT are + * zeros for EGA and VGA. However, the EGA/VGA BIOS sets + * these bits in BIOSDATA_EQUIPMENT according to the monitor + * type detected. + */ +#ifndef VGA_NO_BIOS + switch ((rtcin(RTC_EQUIPMENT) >> 4) & 3) { /* bit 4 and 5 */ + case 0: + /* EGA/VGA */ + fill_adapter_param(readb(BIOS_PADDRTOVADDR(0x488)) & 0x0f, + biosadapter); + break; + case 1: + /* CGA 40x25 */ + /* FIXME: switch to the 80x25 mode? XXX */ + biosadapter[V_ADP_PRIMARY] = adapter_init_value[DCC_CGA40]; + biosadapter[V_ADP_SECONDARY] = adapter_init_value[DCC_MONO]; + break; + case 2: + /* CGA 80x25 */ + biosadapter[V_ADP_PRIMARY] = adapter_init_value[DCC_CGA80]; + biosadapter[V_ADP_SECONDARY] = adapter_init_value[DCC_MONO]; + break; + case 3: + /* MDA */ + biosadapter[V_ADP_PRIMARY] = adapter_init_value[DCC_MONO]; + biosadapter[V_ADP_SECONDARY] = adapter_init_value[DCC_CGA80]; + break; + } +#else + /* assume EGA/VGA? XXX */ + biosadapter[V_ADP_PRIMARY] = adapter_init_value[DCC_EGA80]; + biosadapter[V_ADP_SECONDARY] = adapter_init_value[DCC_MONO]; +#endif /* VGA_NO_BIOS */ + + biosadapters = 0; + if (verify_adapter(&biosadapter[V_ADP_SECONDARY]) == 0) { + ++biosadapters; + biosadapter[V_ADP_SECONDARY].va_flags |= V_ADP_PROBED; + biosadapter[V_ADP_SECONDARY].va_mode = + biosadapter[V_ADP_SECONDARY].va_initial_mode = + map_bios_mode_num(biosadapter[V_ADP_SECONDARY].va_type, + biosadapter[V_ADP_SECONDARY].va_flags + & V_ADP_COLOR, + biosadapter[V_ADP_SECONDARY].va_initial_bios_mode); + } else { + biosadapter[V_ADP_SECONDARY].va_type = -1; + } + if (verify_adapter(&biosadapter[V_ADP_PRIMARY]) == 0) { + ++biosadapters; + biosadapter[V_ADP_PRIMARY].va_flags |= V_ADP_PROBED; +#ifndef VGA_NO_BIOS + biosadapter[V_ADP_PRIMARY].va_initial_bios_mode = + readb(BIOS_PADDRTOVADDR(0x449)); +#else + biosadapter[V_ADP_PRIMARY].va_initial_bios_mode = 3; /* XXX */ +#endif + biosadapter[V_ADP_PRIMARY].va_mode = + biosadapter[V_ADP_PRIMARY].va_initial_mode = + map_bios_mode_num(biosadapter[V_ADP_PRIMARY].va_type, + biosadapter[V_ADP_PRIMARY].va_flags & V_ADP_COLOR, + biosadapter[V_ADP_PRIMARY].va_initial_bios_mode); + } else { + biosadapter[V_ADP_PRIMARY] = biosadapter[V_ADP_SECONDARY]; + biosadapter[V_ADP_SECONDARY].va_type = -1; + } + if (biosadapters == 0) + return biosadapters; + biosadapter[V_ADP_PRIMARY].va_unit = V_ADP_PRIMARY; + biosadapter[V_ADP_SECONDARY].va_unit = V_ADP_SECONDARY; + +#if 0 /* we don't need these... */ + fb_init_struct(&biosadapter[V_ADP_PRIMARY], ...); + fb_init_struct(&biosadapter[V_ADP_SECONDARY], ...); +#endif + +#if notyet + /* + * We cannot have two video adapter of the same type; there must be + * only one of color or mono adapter, or one each of them. + */ + if (biosadapters > 1) { + if (!((biosadapter[0].va_flags ^ biosadapter[1].va_flags) + & V_ADP_COLOR)) + /* we have two mono or color adapters!! */ + return (biosadapters = 0); + } +#endif + + /* + * Ensure a zero start address. This is mainly to recover after + * switching from pcvt using userconfig(). The registers are w/o + * for old hardware so it's too hard to relocate the active screen + * memory. + * This must be done before vga_save_state() for VGA. + */ + outb(biosadapter[V_ADP_PRIMARY].va_crtc_addr, 12); + outb(biosadapter[V_ADP_PRIMARY].va_crtc_addr + 1, 0); + outb(biosadapter[V_ADP_PRIMARY].va_crtc_addr, 13); + outb(biosadapter[V_ADP_PRIMARY].va_crtc_addr + 1, 0); + + /* the video mode parameter table in EGA/VGA BIOS */ + /* NOTE: there can be only one EGA/VGA, wheather color or mono, + * recognized by the video BIOS. + */ + if ((biosadapter[V_ADP_PRIMARY].va_type == KD_EGA) || + (biosadapter[V_ADP_PRIMARY].va_type == KD_VGA)) { + adp = &biosadapter[V_ADP_PRIMARY]; + } else if ((biosadapter[V_ADP_SECONDARY].va_type == KD_EGA) || + (biosadapter[V_ADP_SECONDARY].va_type == KD_VGA)) { + adp = &biosadapter[V_ADP_SECONDARY]; + } else { + adp = NULL; + } + bzero(mode_map, sizeof(mode_map)); + if (adp != NULL) { + if (adp->va_type == KD_VGA) { + vga_save_state(adp, &adpstate, sizeof(adpstate)); +#if defined(VGA_NO_BIOS) || defined(VGA_NO_MODE_CHANGE) + mode_map[adp->va_initial_mode] = adpstate.regs; + rows_offset = 1; +#else /* VGA_NO_BIOS || VGA_NO_MODE_CHANGE */ + if (video_mode_ptr == NULL) { + mode_map[adp->va_initial_mode] = adpstate.regs; + rows_offset = 1; + } else { + /* discard the table if we are not familiar with it... */ + map_mode_table(mode_map, video_mode_ptr, M_VGA_CG320 + 1); + mp = get_mode_param(adp->va_initial_mode); + if (mp != NULL) + bcopy(mp, adpstate2.regs, sizeof(adpstate2.regs)); + switch (comp_adpregs(adpstate.regs, mp)) { + case COMP_IDENTICAL: + /* + * OK, this parameter table looks reasonably familiar + * to us... + */ + /* + * This is a kludge for Toshiba DynaBook SS433 + * whose BIOS video mode table entry has the actual # + * of rows at the offset 1; BIOSes from other + * manufacturers store the # of rows - 1 there. XXX + */ + rows_offset = adpstate.regs[1] + 1 - mp[1]; + break; + + case COMP_SIMILAR: + /* + * Not exactly the same, but similar enough to be + * trusted. However, use the saved register values + * for the initial mode and other modes which are + * based on the initial mode. + */ + mode_map[adp->va_initial_mode] = adpstate.regs; + rows_offset = adpstate.regs[1] + 1 - mp[1]; + adpstate.regs[1] -= rows_offset - 1; + break; + + case COMP_DIFFERENT: + default: + /* + * Don't use the paramter table in BIOS. It doesn't + * look familiar to us. Video mode switching is allowed + * only if the new mode is the same as or based on + * the initial mode. + */ + video_mode_ptr = NULL; + bzero(mode_map, sizeof(mode_map)); + mode_map[adp->va_initial_mode] = adpstate.regs; + rows_offset = 1; + break; + } + } +#endif /* VGA_NO_BIOS || VGA_NO_MODE_CHANGE */ + +#ifndef VGA_NO_MODE_CHANGE + adp->va_flags |= V_ADP_MODECHANGE; +#endif +#ifndef VGA_NO_FONT_LOADING + adp->va_flags |= V_ADP_FONT; +#endif + } else if (adp->va_type == KD_EGA) { +#if defined(VGA_NO_BIOS) || defined(VGA_NO_MODE_CHANGE) + rows_offset = 1; +#else /* VGA_NO_BIOS || VGA_NO_MODE_CHANGE */ + if (video_mode_ptr == NULL) { + rows_offset = 1; + } else { + map_mode_table(mode_map, video_mode_ptr, M_ENH_C80x25 + 1); + /* XXX how can one validate the EGA table... */ + mp = get_mode_param(adp->va_initial_mode); + if (mp != NULL) { + adp->va_flags |= V_ADP_MODECHANGE; +#ifndef VGA_NO_FONT_LOADING + adp->va_flags |= V_ADP_FONT; +#endif + rows_offset = 1; + } else { + /* + * This is serious. We will not be able to switch video + * modes at all... + */ + video_mode_ptr = NULL; + bzero(mode_map, sizeof(mode_map)); + rows_offset = 1; + } + } +#endif /* VGA_NO_BIOS || VGA_NO_MODE_CHANGE */ + } + } + + /* remove conflicting modes if we have more than one adapter */ + if (biosadapters > 1) { + for (i = 0; i < biosadapters; ++i) { + if (!(biosadapter[i].va_flags & V_ADP_MODECHANGE)) + continue; + clear_mode_map(&biosadapter[i], mode_map, M_VGA_CG320 + 1, + (biosadapter[i].va_flags & V_ADP_COLOR) ? + V_INFO_COLOR : 0); + if ((biosadapter[i].va_type == KD_VGA) + || (biosadapter[i].va_type == KD_EGA)) { + biosadapter[i].va_io_base = + (biosadapter[i].va_flags & V_ADP_COLOR) ? + IO_VGA : IO_MDA; + biosadapter[i].va_io_size = 32; + } + } + } + + /* buffer address */ + vga_get_info(&biosadapter[V_ADP_PRIMARY], + biosadapter[V_ADP_PRIMARY].va_initial_mode, &info); + info.vi_flags &= ~V_INFO_LINEAR; /* XXX */ + update_adapter_info(&biosadapter[V_ADP_PRIMARY], &info); + + if (biosadapters > 1) { + vga_get_info(&biosadapter[V_ADP_SECONDARY], + biosadapter[V_ADP_SECONDARY].va_initial_mode, &info); + info.vi_flags &= ~V_INFO_LINEAR; /* XXX */ + update_adapter_info(&biosadapter[V_ADP_SECONDARY], &info); + } + + /* + * XXX: we should verify the following values for the primary adapter... + * crtc I/O port address: *(u_int16_t *)BIOS_PADDRTOVADDR(0x463); + * color/mono display: (*(u_int8_t *)BIOS_PADDRTOVADDR(0x487) & 0x02) + * ? 0 : V_ADP_COLOR; + * columns: *(u_int8_t *)BIOS_PADDRTOVADDR(0x44a); + * rows: *(u_int8_t *)BIOS_PADDRTOVADDR(0x484); + * font size: *(u_int8_t *)BIOS_PADDRTOVADDR(0x485); + * buffer size: *(u_int16_t *)BIOS_PADDRTOVADDR(0x44c); + */ + + return biosadapters; +} + +/* set the scan line length in pixel */ +static int +set_line_length(video_adapter_t *adp, int pixel) +{ + u_char *mp; + int ppw; /* pixels per word */ + int bpl; /* bytes per line */ + int count; + + if ((adp->va_type != KD_VGA) && (adp->va_type != KD_EGA)) + return ENODEV; + mp = get_mode_param(adp->va_mode); + if (mp == NULL) + return EINVAL; + + switch (adp->va_info.vi_mem_model) { + case V_INFO_MM_PLANAR: + ppw = 16/(adp->va_info.vi_depth/adp->va_info.vi_planes); + count = (pixel + ppw - 1)/ppw/2; + bpl = ((pixel + ppw - 1)/ppw/2)*4; + break; + case V_INFO_MM_PACKED: + count = (pixel + 7)/8; + bpl = ((pixel + 7)/8)*8; + break; + case V_INFO_MM_TEXT: + count = (pixel + 7)/8; /* columns */ + bpl = (pixel + 7)/8; /* columns */ + break; + default: + return ENODEV; + } + + if (mp[10 + 0x17] & 0x40) /* CRTC mode control reg */ + count *= 2; /* byte mode */ + outb(adp->va_crtc_addr, 0x13); + outb(adp->va_crtc_addr + 1, count); + adp->va_line_width = bpl; + + return 0; +} + +static int +set_display_start(video_adapter_t *adp, int x, int y) +{ + int off; /* byte offset (graphics mode)/word offset (text mode) */ + int poff; /* pixel offset */ + int roff; /* row offset */ + int ppb; /* pixels per byte */ + + if ((adp->va_type != KD_VGA) && (adp->va_type != KD_EGA)) + x &= ~7; + if (adp->va_info.vi_flags & V_INFO_GRAPHICS) { + ppb = 8/(adp->va_info.vi_depth/adp->va_info.vi_planes); + off = y*adp->va_line_width + x/ppb; + roff = 0; + poff = x%ppb; + } else { + if ((adp->va_type == KD_VGA) || (adp->va_type == KD_EGA)) { + outb(TSIDX, 1); + if (inb(TSREG) & 1) + ppb = 9; + else + ppb = 8; + } else { + ppb = 8; + } + off = y/adp->va_info.vi_cheight*adp->va_line_width + x/ppb; + roff = y%adp->va_info.vi_cheight; + /* FIXME: is this correct? XXX */ + if (ppb == 8) + poff = x%ppb; + else + poff = (x + 8)%ppb; + } + + /* start address */ + outb(adp->va_crtc_addr, 0xc); /* high */ + outb(adp->va_crtc_addr + 1, off >> 8); + outb(adp->va_crtc_addr, 0xd); /* low */ + outb(adp->va_crtc_addr + 1, off & 0xff); + + /* horizontal pel pan */ + if ((adp->va_type == KD_VGA) || (adp->va_type == KD_EGA)) { + inb(adp->va_crtc_addr + 6); + outb(ATC, 0x13 | 0x20); + outb(ATC, poff); + inb(adp->va_crtc_addr + 6); + outb(ATC, 0x20); + } + + /* preset raw scan */ + outb(adp->va_crtc_addr, 8); + outb(adp->va_crtc_addr + 1, roff); + + adp->va_disp_start.x = x; + adp->va_disp_start.y = y; + return 0; +} + +#ifdef __i386__ /* XXX */ +static void +fill(int val, void *d, size_t size) +{ + u_char *p = d; + + while (size-- > 0) + *p++ = val; +} +#endif /* __i386__ */ + +static void +filll_io(int val, vm_offset_t d, size_t size) +{ + while (size-- > 0) { + writel(d, val); + d += sizeof(u_int32_t); + } +} + +/* entry points */ + +static int +vga_nop(void) +{ + return 0; +} + +static int +vga_error(void) +{ + return ENODEV; +} + +static int +vga_probe(int unit, video_adapter_t **adpp, void *arg, int flags) +{ + probe_adapters(); + if (unit >= biosadapters) + return ENXIO; + + *adpp = &biosadapter[unit]; + + return 0; +} + +static int +vga_init(int unit, video_adapter_t *adp, int flags) +{ + if ((unit >= biosadapters) || (adp == NULL) || !probe_done(adp)) + return ENXIO; + + if (!init_done(adp)) { + /* nothing to do really... */ + adp->va_flags |= V_ADP_INITIALIZED; + } + + if (!config_done(adp)) { + if (vid_register(adp) < 0) + return ENXIO; + adp->va_flags |= V_ADP_REGISTERED; + } + if (vga_sub_configure != NULL) + (*vga_sub_configure)(0); + + return 0; +} + +/* + * get_info(): + * Return the video_info structure of the requested video mode. + * + * all adapters + */ +static int +vga_get_info(video_adapter_t *adp, int mode, video_info_t *info) +{ + int i; + + if (!vga_init_done) + return ENXIO; + + mode = map_gen_mode_num(adp->va_type, adp->va_flags & V_ADP_COLOR, mode); +#ifndef VGA_NO_MODE_CHANGE + if (adp->va_flags & V_ADP_MODECHANGE) { + /* + * If the parameter table entry for this mode is not found, + * the mode is not supported... + */ + if (get_mode_param(mode) == NULL) + return EINVAL; + } else +#endif /* VGA_NO_MODE_CHANGE */ + { + /* + * Even if we don't support video mode switching on this adapter, + * the information on the initial (thus current) video mode + * should be made available. + */ + if (mode != adp->va_initial_mode) + return EINVAL; + } + + for (i = 0; bios_vmode[i].vi_mode != EOT; ++i) { + if (bios_vmode[i].vi_mode == NA) + continue; + if (mode == bios_vmode[i].vi_mode) { + *info = bios_vmode[i]; + /* XXX */ + info->vi_buffer_size = info->vi_window_size*info->vi_planes; + return 0; + } + } + return EINVAL; +} + +/* + * query_mode(): + * Find a video mode matching the requested parameters. + * Fields filled with 0 are considered "don't care" fields and + * match any modes. + * + * all adapters + */ +static int +vga_query_mode(video_adapter_t *adp, video_info_t *info) +{ + video_info_t buf; + int i; + + if (!vga_init_done) + return -1; + + for (i = 0; bios_vmode[i].vi_mode != EOT; ++i) { + if (bios_vmode[i].vi_mode == NA) + continue; + + if ((info->vi_width != 0) + && (info->vi_width != bios_vmode[i].vi_width)) + continue; + if ((info->vi_height != 0) + && (info->vi_height != bios_vmode[i].vi_height)) + continue; + if ((info->vi_cwidth != 0) + && (info->vi_cwidth != bios_vmode[i].vi_cwidth)) + continue; + if ((info->vi_cheight != 0) + && (info->vi_cheight != bios_vmode[i].vi_cheight)) + continue; + if ((info->vi_depth != 0) + && (info->vi_depth != bios_vmode[i].vi_depth)) + continue; + if ((info->vi_planes != 0) + && (info->vi_planes != bios_vmode[i].vi_planes)) + continue; + /* XXX: should check pixel format, memory model */ + if ((info->vi_flags != 0) + && (info->vi_flags != bios_vmode[i].vi_flags)) + continue; + + /* verify if this mode is supported on this adapter */ + if (vga_get_info(adp, bios_vmode[i].vi_mode, &buf)) + continue; + return bios_vmode[i].vi_mode; + } + return -1; +} + +/* + * set_mode(): + * Change the video mode. + * + * EGA/VGA + */ + +#ifndef VGA_NO_MODE_CHANGE +#ifdef VGA_WIDTH90 +static void +set_width90(adp_state_t *params) +{ + /* + * Based on code submitted by Kelly Yancey (kbyanc@freedomnet.com) + * and alexv@sui.gda.itesm.mx. + */ + params->regs[5] |= 1; /* toggle 8 pixel wide fonts */ + params->regs[10+0x0] = 0x6b; + params->regs[10+0x1] = 0x59; + params->regs[10+0x2] = 0x5a; + params->regs[10+0x3] = 0x8e; + params->regs[10+0x4] = 0x5e; + params->regs[10+0x5] = 0x8a; + params->regs[10+0x13] = 45; + params->regs[35+0x13] = 0; +} +#endif /* VGA_WIDTH90 */ +#endif /* !VGA_NO_MODE_CHANGE */ + +static int +vga_set_mode(video_adapter_t *adp, int mode) +{ +#ifndef VGA_NO_MODE_CHANGE + video_info_t info; + adp_state_t params; + + prologue(adp, V_ADP_MODECHANGE, ENODEV); + + mode = map_gen_mode_num(adp->va_type, + adp->va_flags & V_ADP_COLOR, mode); + if (vga_get_info(adp, mode, &info)) + return EINVAL; + +#if VGA_DEBUG > 1 + printf("vga_set_mode(): setting mode %d\n", mode); +#endif + + params.sig = V_STATE_SIG; + bcopy(get_mode_param(mode), params.regs, sizeof(params.regs)); + + switch (mode) { +#ifdef VGA_WIDTH90 + case M_VGA_C90x60: case M_VGA_M90x60: + set_width90(¶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 <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> #include <sys/module.h> +#include <sys/consio.h> +#include <sys/fbio.h> -#include <dev/fb/vgareg.h> - -#include <i386/isa/isa.h> - -#include <saver.h> +#include <dev/fb/fbreg.h> +#include <dev/fb/splashreg.h> +#include <dev/syscons/syscons.h> static int blank_saver(video_adapter_t *adp, int blank) { - u_char val; - if (blank) { - switch (adp->va_type) { - case KD_VGA: - outb(TSIDX, 0x01); val = inb(TSREG); - outb(TSIDX, 0x01); outb(TSREG, val | 0x20); - break; - case KD_EGA: - /* not yet done XXX */ - break; - case KD_CGA: - outb(adp->va_crtc_addr + 4, 0x25); - break; - case KD_MONO: - case KD_HERCULES: - outb(adp->va_crtc_addr + 4, 0x21); - break; - default: - break; - } - } - else { - switch (adp->va_type) { - case KD_VGA: - outb(TSIDX, 0x01); val = inb(TSREG); - outb(TSIDX, 0x01); outb(TSREG, val & 0xDF); - break; - case KD_EGA: - /* not yet done XXX */ - break; - case KD_CGA: - outb(adp->va_crtc_addr + 4, 0x2d); - break; - case KD_MONO: - case KD_HERCULES: - outb(adp->va_crtc_addr + 4, 0x29); - break; - default: - break; - } - } + (*vidsw[adp->va_index]->blank_display)(adp, + (blank) ? V_DISPLAY_BLANK + : V_DISPLAY_ON); return 0; } static int blank_init(video_adapter_t *adp) { - switch (adp->va_type) { - case KD_MONO: - case KD_HERCULES: - case KD_CGA: - case KD_VGA: - break; - case KD_EGA: - /* EGA is yet to be supported */ - default: - return ENODEV; - } - return 0; + if ((*vidsw[adp->va_index]->blank_display)(adp, V_DISPLAY_ON) == 0) + return 0; + return ENODEV; } static int diff --git a/sys/dev/syscons/daemon/daemon_saver.c b/sys/dev/syscons/daemon/daemon_saver.c index 423e6c7..ebedfaa 100644 --- a/sys/dev/syscons/daemon/daemon_saver.c +++ b/sys/dev/syscons/daemon/daemon_saver.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: daemon_saver.c,v 1.14 1999/01/17 14:25:08 yokota Exp $ + * $Id: daemon_saver.c,v 1.15 1999/02/05 12:40:15 des Exp $ */ #include <sys/param.h> @@ -34,21 +34,20 @@ #include <sys/malloc.h> #include <sys/kernel.h> #include <sys/sysctl.h> +#include <sys/consio.h> +#include <sys/fbio.h> -#include <machine/md_var.h> #include <machine/pc/display.h> -#include <saver.h> - -#define CONSOLE_VECT(x, y) \ - (window + (y)*cur_console->xsize + (x)) +#include <dev/fb/fbreg.h> +#include <dev/fb/splashreg.h> +#include <dev/syscons/syscons.h> #define DAEMON_MAX_WIDTH 32 #define DAEMON_MAX_HEIGHT 19 static char *message; static int messagelen; -static u_short *window; static int blanked; /* Who is the author of this ASCII pic? */ @@ -119,20 +118,23 @@ xflip_symbol(char symbol) } static void -clear_daemon(int xpos, int ypos, int dxdir, int xoff, int yoff, +clear_daemon(sc_softc_t *sc, int xpos, int ypos, int dxdir, int xoff, int yoff, int xlen, int ylen) { int y; if (xlen <= 0) return; - for (y = yoff; y < ylen; y++) - fillw(((FG_LIGHTGREY|BG_BLACK) << 8) | scr_map[0x20], - CONSOLE_VECT(xpos + xoff, ypos + y), xlen - xoff); + for (y = yoff; y < ylen; y++) { + sc_vtb_erase(&sc->cur_scp->scr, + (ypos + y)*sc->cur_scp->xsize + xpos + xoff, + xlen - xoff, + sc->scr_map[0x20], (FG_LIGHTGREY | BG_BLACK) << 8); + } } static void -draw_daemon(int xpos, int ypos, int dxdir, int xoff, int yoff, +draw_daemon(sc_softc_t *sc, int xpos, int ypos, int dxdir, int xoff, int yoff, int xlen, int ylen) { int x, y; @@ -148,41 +150,60 @@ draw_daemon(int xpos, int ypos, int dxdir, int xoff, int yoff, continue; for (x = xoff; (x < xlen) && (daemon_pic[y][px] != '\0'); x++, px++) { switch (daemon_attr[y][px]) { +#ifndef PC98 case 'R': attr = (FG_LIGHTRED|BG_BLACK)<<8; break; case 'Y': attr = (FG_YELLOW|BG_BLACK)<<8; break; case 'B': attr = (FG_LIGHTBLUE|BG_BLACK)<<8; break; case 'W': attr = (FG_LIGHTGREY|BG_BLACK)<<8; break; case 'C': attr = (FG_CYAN|BG_BLACK)<<8; break; default: attr = (FG_WHITE|BG_BLACK)<<8; break; +#else /* PC98 */ + case 'R': attr = (FG_RED|BG_BLACK)<<8; break; + case 'Y': attr = (FG_BROWN|BG_BLACK)<<8; break; + case 'B': attr = (FG_BLUE|BG_BLACK)<<8; break; + case 'W': attr = (FG_LIGHTGREY|BG_BLACK)<<8; break; + case 'C': attr = (FG_CYAN|BG_BLACK)<<8; break; + default: attr = (FG_LIGHTGREY|BG_BLACK)<<8; break; +#endif /* PC98 */ } if (dxdir < 0) { /* Moving left */ - *CONSOLE_VECT(xpos + x, ypos + y) = - scr_map[daemon_pic[y][px]]|attr; + sc_vtb_putc(&sc->cur_scp->scr, + (ypos + y)*sc->cur_scp->xsize + + xpos + x, + sc->scr_map[daemon_pic[y][px]], + attr); } else { /* Moving right */ - *CONSOLE_VECT(xpos + DAEMON_MAX_WIDTH - px - 1, ypos + y) = - scr_map[xflip_symbol(daemon_pic[y][px])]|attr; + sc_vtb_putc(&sc->cur_scp->scr, + (ypos + y)*sc->cur_scp->xsize + + xpos + DAEMON_MAX_WIDTH + - px - 1, + sc->scr_map[xflip_symbol(daemon_pic[y][px])], + attr); } } } } static void -clear_string(int xpos, int ypos, int xoff, char *s, int len) +clear_string(sc_softc_t *sc, int xpos, int ypos, int xoff, char *s, int len) { if (len <= 0) return; - fillw(((FG_LIGHTGREY|BG_BLACK) << 8) | scr_map[0x20], - CONSOLE_VECT(xpos + xoff, ypos), len - xoff); + sc_vtb_erase(&sc->cur_scp->scr, + ypos*sc->cur_scp->xsize + xpos + xoff, len - xoff, + sc->scr_map[0x20], (FG_LIGHTGREY | BG_BLACK) << 8); } static void -draw_string(int xpos, int ypos, int xoff, char *s, int len) +draw_string(sc_softc_t *sc, int xpos, int ypos, int xoff, char *s, int len) { int x; - for (x = xoff; x < len; x++) - *CONSOLE_VECT(xpos + x, ypos) = - scr_map[s[x]]|(FG_LIGHTGREEN|BG_BLACK)<<8; + for (x = xoff; x < len; x++) { + sc_vtb_putc(&sc->cur_scp->scr, + ypos*sc->cur_scp->xsize + xpos + x, + sc->scr_map[s[x]], (FG_LIGHTGREEN | BG_BLACK) << 8); + } } static int @@ -195,17 +216,30 @@ daemon_saver(video_adapter_t *adp, int blank) static int moved_daemon = 0; static int xoff, yoff, toff; static int xlen, ylen, tlen; - scr_stat *scp = cur_console; + sc_softc_t *sc; + scr_stat *scp; int min, max; + sc = sc_find_softc(adp, NULL); + if (sc == NULL) + return EAGAIN; + scp = sc->cur_scp; + if (blank) { if (adp->va_info.vi_flags & V_INFO_GRAPHICS) return EAGAIN; if (blanked == 0) { - window = (u_short *)adp->va_window; +#ifdef PC98 + if (epson_machine_id == 0x20) { + outb(0x43f, 0x42); + outb(0x0c17, inb(0xc17) & ~0x08); + outb(0x43f, 0x40); + } +#endif /* PC98 */ /* clear the screen and set the border color */ - fillw(((FG_LIGHTGREY|BG_BLACK) << 8) | scr_map[0x20], - window, scp->xsize * scp->ysize); + sc_vtb_clear(&scp->scr, sc->scr_map[0x20], + (FG_LIGHTGREY | BG_BLACK) << 8); + (*vidsw[adp->va_index]->set_hw_cursor)(adp, -1, -1); set_border(scp, 0); xlen = ylen = tlen = 0; } @@ -213,8 +247,8 @@ daemon_saver(video_adapter_t *adp, int blank) return 0; blanked = 1; - clear_daemon(dxpos, dypos, dxdir, xoff, yoff, xlen, ylen); - clear_string(txpos, typos, toff, (char *)message, tlen); + clear_daemon(sc, dxpos, dypos, dxdir, xoff, yoff, xlen, ylen); + clear_string(sc, txpos, typos, toff, (char *)message, tlen); if (++moved_daemon) { /* @@ -319,9 +353,16 @@ daemon_saver(video_adapter_t *adp, int blank) else if (txpos + tlen > scp->xsize) tlen = scp->xsize - txpos; - draw_daemon(dxpos, dypos, dxdir, xoff, yoff, xlen, ylen); - draw_string(txpos, typos, toff, (char *)message, tlen); + draw_daemon(sc, dxpos, dypos, dxdir, xoff, yoff, xlen, ylen); + draw_string(sc, txpos, typos, toff, (char *)message, tlen); } else { +#ifdef PC98 + if (epson_machine_id == 0x20) { + outb(0x43f, 0x42); + outb(0x0c17, inb(0xc17) | 0x08); + outb(0x43f, 0x40); + } +#endif /* PC98 */ blanked = 0; } return 0; diff --git a/sys/dev/syscons/fade/fade_saver.c b/sys/dev/syscons/fade/fade_saver.c index 70d36c9..4a44c85 100644 --- a/sys/dev/syscons/fade/fade_saver.c +++ b/sys/dev/syscons/fade/fade_saver.c @@ -25,17 +25,19 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: fade_saver.c,v 1.15 1998/11/04 03:49:38 peter Exp $ + * $Id: fade_saver.c,v 1.16 1999/01/11 03:18:46 yokota Exp $ */ #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> #include <sys/module.h> +#include <sys/consio.h> +#include <sys/fbio.h> -#include <i386/isa/isa.h> - -#include <saver.h> +#include <dev/fb/fbreg.h> +#include <dev/fb/splashreg.h> +#include <dev/syscons/syscons.h> static u_char palette[256*3]; static int blanked; @@ -49,11 +51,10 @@ fade_saver(video_adapter_t *adp, int blank) if (blank) { blanked = TRUE; - switch (adp->va_type) { - case KD_VGA: + if (ISPALAVAIL(adp->va_flags)) { if (count <= 0) save_palette(adp, palette); - if (count < 64) { + if (count < 256) { pal[0] = pal[1] = pal[2] = 0; for (i = 3; i < 256*3; i++) { if (palette[i] - count > 60) @@ -64,39 +65,17 @@ fade_saver(video_adapter_t *adp, int blank) load_palette(adp, pal); count++; } - break; - case KD_EGA: - /* not yet done XXX */ - break; - case KD_CGA: - outb(adp->va_crtc_addr + 4, 0x25); - break; - case KD_MONO: - case KD_HERCULES: - outb(adp->va_crtc_addr + 4, 0x21); - break; - default: - break; + } else { + (*vidsw[adp->va_index]->blank_display)(adp, + V_DISPLAY_BLANK); } - } - else { - switch (adp->va_type) { - case KD_VGA: + } else { + if (ISPALAVAIL(adp->va_flags)) { load_palette(adp, palette); count = 0; - break; - case KD_EGA: - /* not yet done XXX */ - break; - case KD_CGA: - outb(adp->va_crtc_addr + 4, 0x2d); - break; - case KD_MONO: - case KD_HERCULES: - outb(adp->va_crtc_addr + 4, 0x29); - break; - default: - break; + } else { + (*vidsw[adp->va_index]->blank_display)(adp, + V_DISPLAY_ON); } blanked = FALSE; } @@ -106,21 +85,9 @@ fade_saver(video_adapter_t *adp, int blank) static int fade_init(video_adapter_t *adp) { - switch (adp->va_type) { - case KD_MONO: - case KD_HERCULES: - case KD_CGA: - /* - * `fade' saver is not fully implemented for MDA and CGA. - * It simply blanks the display instead. - */ - case KD_VGA: - break; - case KD_EGA: - /* EGA is yet to be supported */ - default: + if (!ISPALAVAIL(adp->va_flags) + && (*vidsw[adp->va_index]->blank_display)(adp, V_DISPLAY_ON) != 0) return ENODEV; - } blanked = FALSE; return 0; } diff --git a/sys/dev/syscons/fire/fire_saver.c b/sys/dev/syscons/fire/fire_saver.c index aea36a9..db4b80b 100644 --- a/sys/dev/syscons/fire/fire_saver.c +++ b/sys/dev/syscons/fire/fire_saver.c @@ -23,7 +23,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: fire_saver.c,v 1.2.2.1 1999/05/10 15:20:30 des Exp $ + * $Id: fire_saver.c,v 1.4 1999/05/10 15:25:50 des Exp $ */ /* @@ -38,11 +38,14 @@ #include <sys/kernel.h> #include <sys/module.h> #include <sys/syslog.h> +#include <sys/consio.h> +#include <sys/fbio.h> -#include <machine/md_var.h> #include <machine/random.h> -#include <saver.h> +#include <dev/fb/fbreg.h> +#include <dev/fb/splashreg.h> +#include <dev/syscons/syscons.h> #define X_SIZE 320 #define Y_SIZE 200 diff --git a/sys/dev/syscons/green/green_saver.c b/sys/dev/syscons/green/green_saver.c index 9decd72..103154b 100644 --- a/sys/dev/syscons/green/green_saver.c +++ b/sys/dev/syscons/green/green_saver.c @@ -25,93 +25,35 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: green_saver.c,v 1.14 1998/11/04 03:49:38 peter Exp $ + * $Id: green_saver.c,v 1.15 1999/01/11 03:18:48 yokota Exp $ */ #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> #include <sys/module.h> +#include <sys/consio.h> +#include <sys/fbio.h> -#include <dev/fb/vgareg.h> - -#include <i386/isa/isa.h> - -#include <saver.h> +#include <dev/fb/fbreg.h> +#include <dev/fb/splashreg.h> +#include <dev/syscons/syscons.h> static int green_saver(video_adapter_t *adp, int blank) { - int crtc_addr; - u_char val; - - crtc_addr = adp->va_crtc_addr; - if (blank) { - switch (adp->va_type) { - case KD_VGA: - outb(TSIDX, 0x01); val = inb(TSREG); - outb(TSIDX, 0x01); outb(TSREG, val | 0x20); - outb(crtc_addr, 0x17); val = inb(crtc_addr + 1); - outb(crtc_addr + 1, val & ~0x80); - break; - case KD_EGA: - /* not yet done XXX */ - break; - case KD_CGA: - outb(crtc_addr + 4, 0x25); - break; - case KD_MONO: - case KD_HERCULES: - outb(crtc_addr + 4, 0x21); - break; - default: - break; - } - } - else { - switch (adp->va_type) { - case KD_VGA: - outb(TSIDX, 0x01); val = inb(TSREG); - outb(TSIDX, 0x01); outb(TSREG, val & 0xDF); - outb(crtc_addr, 0x17); val = inb(crtc_addr + 1); - outb(crtc_addr + 1, val | 0x80); - break; - case KD_EGA: - /* not yet done XXX */ - break; - case KD_CGA: - outb(crtc_addr + 4, 0x2d); - break; - case KD_MONO: - case KD_HERCULES: - outb(crtc_addr + 4, 0x29); - break; - default: - break; - } - } + (*vidsw[adp->va_index]->blank_display)(adp, + (blank) ? V_DISPLAY_STAND_BY + : V_DISPLAY_ON); return 0; } static int green_init(video_adapter_t *adp) { - switch (adp->va_type) { - case KD_MONO: - case KD_HERCULES: - case KD_CGA: - /* - * `green' saver is not fully implemented for MDA and CGA. - * It simply blanks the display instead. - */ - case KD_VGA: - break; - case KD_EGA: - /* EGA is yet to be supported */ - default: - return ENODEV; - } - return 0; + if ((*vidsw[adp->va_index]->blank_display)(adp, V_DISPLAY_ON) == 0) + return 0; + return ENODEV; } static int diff --git a/sys/dev/syscons/logo/logo_saver.c b/sys/dev/syscons/logo/logo_saver.c index b6a46ac..24da964 100644 --- a/sys/dev/syscons/logo/logo_saver.c +++ b/sys/dev/syscons/logo/logo_saver.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: logo_saver.c,v 1.5 1999/02/05 12:40:15 des Exp $ + * $Id: logo_saver.c,v 1.6 1999/04/12 13:34:57 des Exp $ */ #include <sys/param.h> @@ -33,8 +33,12 @@ #include <sys/kernel.h> #include <sys/module.h> #include <sys/syslog.h> +#include <sys/consio.h> +#include <sys/fbio.h> -#include <saver.h> +#include <dev/fb/fbreg.h> +#include <dev/fb/splashreg.h> +#include <dev/syscons/syscons.h> static u_char *vid; static int banksize, scrmode, bpsl, scrw, scrh; @@ -104,6 +108,7 @@ logo_saver(video_adapter_t *adp, int blank) #endif blanked++; vid = (u_char *)adp->va_window; + banksize = adp->va_window_size; bpsl = adp->va_line_width; splx(pl); for (i = 0; i < bpsl*scrh; i += banksize) { @@ -132,7 +137,6 @@ logo_init(video_adapter_t *adp) return ENODEV; } - banksize = info.vi_window_size; scrw = info.vi_width; scrh = info.vi_height; blanked = 0; diff --git a/sys/dev/syscons/rain/rain_saver.c b/sys/dev/syscons/rain/rain_saver.c index 9aa7370..200dc59 100644 --- a/sys/dev/syscons/rain/rain_saver.c +++ b/sys/dev/syscons/rain/rain_saver.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: rain_saver.c,v 1.2 1999/01/11 03:18:50 yokota Exp $ + * $Id: rain_saver.c,v 1.3 1999/04/12 13:34:57 des Exp $ */ #include <sys/param.h> @@ -33,10 +33,14 @@ #include <sys/kernel.h> #include <sys/module.h> #include <sys/syslog.h> +#include <sys/consio.h> +#include <sys/fbio.h> #include <machine/random.h> -#include <saver.h> +#include <dev/fb/fbreg.h> +#include <dev/fb/splashreg.h> +#include <dev/syscons/syscons.h> static u_char *vid; diff --git a/sys/dev/syscons/scgfbrndr.c b/sys/dev/syscons/scgfbrndr.c new file mode 100644 index 0000000..16c40e2 --- /dev/null +++ b/sys/dev/syscons/scgfbrndr.c @@ -0,0 +1,829 @@ +/*- + * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer as + * the first lines of this file unmodified. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Id:$ + */ + +#include "sc.h" +#include "vga.h" +#include "opt_syscons.h" +#include "opt_vga.h" + +#if NSC > 0 && NVGA > 0 + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> + +#include <machine/console.h> +#include <machine/md_var.h> + +#include <dev/fb/fbreg.h> +#include <dev/fb/vgareg.h> +#include <dev/syscons/syscons.h> + +#include <isa/isareg.h> + +#ifndef SC_MOUSE_CHAR +#define SC_MOUSE_CHAR (0xd0) +#endif + +#ifndef SC_RENDER_DEBUG +#define SC_RENDER_DEBUG 0 +#endif + +static vr_clear_t vga_txtclear; +static vr_draw_border_t vga_txtborder; +static vr_draw_t vga_txtdraw; +static vr_set_cursor_t vga_txtcursor_shape; +static vr_draw_cursor_t vga_txtcursor; +static vr_blink_cursor_t vga_txtblink; +#ifndef SC_NO_CUTPASTE +static vr_draw_mouse_t vga_txtmouse; +#else +#define vga_txtmouse (vr_draw_mouse_t *)vga_nop +#endif + +#ifdef SC_PIXEL_MODE +static vr_clear_t vga_pxlclear; +static vr_draw_border_t vga_pxlborder; +static vr_draw_t vga_egadraw; +static vr_draw_t vga_vgadraw; +static vr_set_cursor_t vga_pxlcursor_shape; +static vr_draw_cursor_t vga_pxlcursor; +static vr_blink_cursor_t vga_pxlblink; +#ifndef SC_NO_CUTPASTE +static vr_draw_mouse_t vga_pxlmouse; +#else +#define vga_pxlmouse (vr_draw_mouse_t *)vga_nop +#endif +#endif /* SC_PIXEL_MODE */ + +#ifndef SC_NO_MODE_CHANGE +static vr_draw_border_t vga_grborder; +#endif + +static void vga_nop(scr_stat *scp, ...); + +static sc_rndr_sw_t txtrndrsw = { + vga_txtclear, + vga_txtborder, + vga_txtdraw, + vga_txtcursor_shape, + vga_txtcursor, + vga_txtblink, + (vr_set_mouse_t *)vga_nop, + vga_txtmouse, +}; +RENDERER(mda, 0, txtrndrsw); +RENDERER(cga, 0, txtrndrsw); +RENDERER(ega, 0, txtrndrsw); +RENDERER(vga, 0, txtrndrsw); + +#ifdef SC_PIXEL_MODE +static sc_rndr_sw_t egarndrsw = { + vga_pxlclear, + vga_pxlborder, + vga_egadraw, + vga_pxlcursor_shape, + vga_pxlcursor, + vga_pxlblink, + (vr_set_mouse_t *)vga_nop, + vga_pxlmouse, +}; +RENDERER(ega, PIXEL_MODE, egarndrsw); + +static sc_rndr_sw_t vgarndrsw = { + vga_pxlclear, + vga_pxlborder, + vga_vgadraw, + vga_pxlcursor_shape, + vga_pxlcursor, + vga_pxlblink, + (vr_set_mouse_t *)vga_nop, + vga_pxlmouse, +}; +RENDERER(vga, PIXEL_MODE, vgarndrsw); +#endif /* SC_PIXEL_MODE */ + +#ifndef SC_NO_MODE_CHANGE +static sc_rndr_sw_t grrndrsw = { + (vr_clear_t *)vga_nop, + vga_grborder, + (vr_draw_t *)vga_nop, + (vr_set_cursor_t *)vga_nop, + (vr_draw_cursor_t *)vga_nop, + (vr_blink_cursor_t *)vga_nop, + (vr_set_mouse_t *)vga_nop, + (vr_draw_mouse_t *)vga_nop, +}; +RENDERER(cga, GRAPHICS_MODE, grrndrsw); +RENDERER(ega, GRAPHICS_MODE, grrndrsw); +RENDERER(vga, GRAPHICS_MODE, grrndrsw); +#endif /* SC_NO_MODE_CHANGE */ + +#ifndef SC_NO_CUTPASTE +static u_short mouse_and_mask[16] = { + 0xc000, 0xe000, 0xf000, 0xf800, 0xfc00, 0xfe00, 0xff00, 0xff80, + 0xfe00, 0x1e00, 0x1f00, 0x0f00, 0x0f00, 0x0000, 0x0000, 0x0000 +}; +static u_short mouse_or_mask[16] = { + 0x0000, 0x4000, 0x6000, 0x7000, 0x7800, 0x7c00, 0x7e00, 0x6800, + 0x0c00, 0x0c00, 0x0600, 0x0600, 0x0000, 0x0000, 0x0000, 0x0000 +}; +#endif + +static void +vga_nop(scr_stat *scp, ...) +{ +} + +/* text mode renderer */ + +static void +vga_txtclear(scr_stat *scp, int c, int attr) +{ + sc_vtb_clear(&scp->scr, c, attr); +} + +static void +vga_txtborder(scr_stat *scp, int color) +{ + (*vidsw[scp->sc->adapter]->set_border)(scp->sc->adp, color); +} + +static void +vga_txtdraw(scr_stat *scp, int from, int count, int flip) +{ + vm_offset_t p; + int c; + int a; + + if (from + count > scp->xsize*scp->ysize) + count = scp->xsize*scp->ysize - from; + + if (flip) { + for (p = sc_vtb_pointer(&scp->scr, from); count-- > 0; ++from) { + c = sc_vtb_getc(&scp->vtb, from); + a = sc_vtb_geta(&scp->vtb, from); + a = (a & 0x8800) | ((a & 0x7000) >> 4) + | ((a & 0x0700) << 4); + p = sc_vtb_putchar(&scp->scr, p, c, a); + } + } else { + sc_vtb_copy(&scp->vtb, from, &scp->scr, from, count); + } +} + +static void +vga_txtcursor_shape(scr_stat *scp, int base, int height, int blink) +{ + if (base < 0 || base >= scp->font_size) + return; + /* the caller may set height <= 0 in order to disable the cursor */ +#if 0 + scp->cursor_base = base; + scp->cursor_height = height; +#endif + (*vidsw[scp->sc->adapter]->set_hw_cursor_shape)(scp->sc->adp, + base, height, + scp->font_size, blink); +} + +static void +vga_txtcursor(scr_stat *scp, int at, int blink, int on, int flip) +{ + video_adapter_t *adp; + int cursor_attr; + + if (scp->cursor_height <= 0) /* the text cursor is disabled */ + return; + + adp = scp->sc->adp; + if (blink) { + scp->status |= VR_CURSOR_BLINK; + if (on) { + scp->status |= VR_CURSOR_ON; + (*vidsw[adp->va_index]->set_hw_cursor)(adp, + at%scp->xsize, + at/scp->xsize); + } else { + if (scp->status & VR_CURSOR_ON) + (*vidsw[adp->va_index]->set_hw_cursor)(adp, + -1, -1); + scp->status &= ~VR_CURSOR_ON; + } + } else { + scp->status &= ~VR_CURSOR_BLINK; + if (on) { + scp->status |= VR_CURSOR_ON; + cursor_attr = sc_vtb_geta(&scp->vtb, at); + scp->cursor_saveunder_char = sc_vtb_getc(&scp->scr, at); + scp->cursor_saveunder_attr = cursor_attr; + if ((cursor_attr & 0x7000) == 0x7000) { + cursor_attr &= 0x8f00; + if ((cursor_attr & 0x0700) == 0) + cursor_attr |= 0x0700; + } else { + cursor_attr |= 0x7000; + if ((cursor_attr & 0x0700) == 0x0700) + cursor_attr &= 0xf000; + } + if (flip) + cursor_attr = (cursor_attr & 0x8800) + | ((cursor_attr & 0x7000) >> 4) + | ((cursor_attr & 0x0700) << 4); + sc_vtb_putc(&scp->scr, at, + sc_vtb_getc(&scp->scr, at), + cursor_attr); + } else { + cursor_attr = scp->cursor_saveunder_attr; + if (flip) + cursor_attr = (cursor_attr & 0x8800) + | ((cursor_attr & 0x7000) >> 4) + | ((cursor_attr & 0x0700) << 4); + if (scp->status & VR_CURSOR_ON) + sc_vtb_putc(&scp->scr, at, + scp->cursor_saveunder_char, + cursor_attr); + scp->status &= ~VR_CURSOR_ON; + } + } +} + +static void +vga_txtblink(scr_stat *scp, int at, int flip) +{ +} + +#ifndef SC_NO_CUTPASTE + +static void +draw_txtmouse(scr_stat *scp, int x, int y) +{ +#ifndef SC_ALT_MOUSE_IMAGE + u_char font_buf[128]; + u_short cursor[32]; + int pos; + int xoffset, yoffset; + int crtc_addr; + int i; + + /* prepare mousepointer char's bitmaps */ + pos = (y/scp->font_size - scp->yoff)*scp->xsize + x/8 - scp->xoff; + bcopy(scp->font + sc_vtb_getc(&scp->vtb, pos)*scp->font_size, + &font_buf[0], scp->font_size); + bcopy(scp->font + sc_vtb_getc(&scp->vtb, pos + 1)*scp->font_size, + &font_buf[32], scp->font_size); + bcopy(scp->font + + sc_vtb_getc(&scp->vtb, pos + scp->xsize)*scp->font_size, + &font_buf[64], scp->font_size); + bcopy(scp->font + + sc_vtb_getc(&scp->vtb, pos + scp->xsize + 1)*scp->font_size, + &font_buf[96], scp->font_size); + for (i = 0; i < scp->font_size; ++i) { + cursor[i] = font_buf[i]<<8 | font_buf[i+32]; + cursor[i + scp->font_size] = font_buf[i+64]<<8 | font_buf[i+96]; + } + + /* now and-or in the mousepointer image */ + xoffset = x%8; + yoffset = y%scp->font_size; + for (i = 0; i < 16; ++i) { + cursor[i + yoffset] = + (cursor[i + yoffset] & ~(mouse_and_mask[i] >> xoffset)) + | (mouse_or_mask[i] >> xoffset); + } + for (i = 0; i < scp->font_size; ++i) { + font_buf[i] = (cursor[i] & 0xff00) >> 8; + font_buf[i + 32] = cursor[i] & 0xff; + font_buf[i + 64] = (cursor[i + scp->font_size] & 0xff00) >> 8; + font_buf[i + 96] = cursor[i + scp->font_size] & 0xff; + } + +#if 1 + /* wait for vertical retrace to avoid jitter on some videocards */ + crtc_addr = scp->sc->adp->va_crtc_addr; + while (!(inb(crtc_addr + 6) & 0x08)) /* idle */ ; +#endif + (*vidsw[scp->sc->adapter]->load_font)(scp->sc->adp, 0, 32, font_buf, + SC_MOUSE_CHAR, 4); + + sc_vtb_putc(&scp->scr, pos, SC_MOUSE_CHAR, sc_vtb_geta(&scp->scr, pos)); + /* FIXME: may be out of range! */ + sc_vtb_putc(&scp->scr, pos + scp->xsize, SC_MOUSE_CHAR + 2, + sc_vtb_geta(&scp->scr, pos + scp->xsize)); + if (x < (scp->xsize - 1)*8) { + sc_vtb_putc(&scp->scr, pos + 1, SC_MOUSE_CHAR + 1, + sc_vtb_geta(&scp->scr, pos + 1)); + sc_vtb_putc(&scp->scr, pos + scp->xsize + 1, SC_MOUSE_CHAR + 3, + sc_vtb_geta(&scp->scr, pos + scp->xsize + 1)); + } +#else /* SC_ALT_MOUSE_IMAGE */ + /* Red, magenta and brown are mapped to green to to keep it readable */ + static const int col_conv[16] = { + 6, 6, 6, 6, 2, 2, 2, 6, 14, 14, 14, 14, 10, 10, 10, 14 + }; + int pos; + int color; + int a; + + pos = (y/scp->font_size - scp->yoff)*scp->xsize + x/8 - scp->xoff; + a = sc_vtb_geta(&scp->scr, pos); + if (scp->sc->adp->va_flags & V_ADP_COLOR) + color = (col_conv[(a & 0xf000) >> 12] << 12) + | ((a & 0x0f00) | 0x0800); + else + color = ((a & 0xf000) >> 4) | ((a & 0x0f00) << 4); + sc_vtb_putc(&scp->scr, pos, sc_vtb_getc(&scp->scr, pos), color); +#endif /* SC_ALT_MOUSE_IMAGE */ +} + +static void +remove_txtmouse(scr_stat *scp, int x, int y) +{ +} + +static void +vga_txtmouse(scr_stat *scp, int x, int y, int on) +{ + if (on) + draw_txtmouse(scp, x, y); + else + remove_txtmouse(scp, x, y); +} + +#endif /* SC_NO_CUTPASTE */ + +#ifdef SC_PIXEL_MODE + +/* pixel (raster text) mode renderer */ + +static void +vga_pxlclear(scr_stat *scp, int c, int attr) +{ + vm_offset_t p; + int line_width; + int lines; + int i; + + /* XXX: we are just filling the screen with the background color... */ + outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */ + outw(GDCIDX, 0x0003); /* data rotate/function select */ + outw(GDCIDX, 0x0f01); /* set/reset enable */ + outw(GDCIDX, 0xff08); /* bit mask */ + outw(GDCIDX, ((attr & 0xf000) >> 4) | 0x00); /* set/reset */ + line_width = scp->sc->adp->va_line_width; + lines = scp->ysize*scp->font_size; + p = scp->sc->adp->va_window + line_width*scp->yoff*scp->font_size + + scp->xoff; + for (i = 0; i < lines; ++i) { + bzero_io((void *)p, scp->xsize); + p += line_width; + } + outw(GDCIDX, 0x0000); /* set/reset */ + outw(GDCIDX, 0x0001); /* set/reset enable */ +} + +static void +vga_pxlborder(scr_stat *scp, int color) +{ + vm_offset_t p; + int line_width; + int i; + + (*vidsw[scp->sc->adapter]->set_border)(scp->sc->adp, color); + + outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */ + outw(GDCIDX, 0x0003); /* data rotate/function select */ + outw(GDCIDX, 0x0f01); /* set/reset enable */ + outw(GDCIDX, 0xff08); /* bit mask */ + outw(GDCIDX, (color << 8) | 0x00); /* set/reset */ + line_width = scp->sc->adp->va_line_width; + p = scp->sc->adp->va_window; + if (scp->yoff > 0) { + bzero_io((void *)p, line_width*scp->yoff*scp->font_size); + bzero_io((void *)(p + line_width*(scp->yoff + scp->ysize) + *scp->font_size), + line_width*(scp->ypixel + - (scp->yoff + scp->ysize)*scp->font_size)); + } + if (scp->xoff > 0) { + for (i = 0; i < scp->ysize*scp->font_size; ++i) { + bzero_io((void *)(p + line_width + *(scp->yoff*scp->font_size + i)), + scp->xoff); + bzero_io((void *)(p + line_width + *(scp->yoff*scp->font_size + i) + + scp->xoff + scp->xsize), + scp->xpixel/8 - scp->xoff - scp->xsize); + } + } + outw(GDCIDX, 0x0000); /* set/reset */ + outw(GDCIDX, 0x0001); /* set/reset enable */ +} + +static void +vga_egadraw(scr_stat *scp, int from, int count, int flip) +{ + vm_offset_t d; + vm_offset_t e; + u_char *f; + u_short bg; + u_short col1, col2; + int line_width; + int i, j; + int a; + u_char c; + + line_width = scp->sc->adp->va_line_width; + d = scp->sc->adp->va_window + + scp->xoff + + scp->yoff*scp->font_size*line_width + + (from%scp->xsize) + + scp->font_size*line_width*(from/scp->xsize); + + outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */ + outw(GDCIDX, 0x0003); /* data rotate/function select */ + outw(GDCIDX, 0x0f01); /* set/reset enable */ + bg = -1; + if (from + count > scp->xsize*scp->ysize) + count = scp->xsize*scp->ysize - from; + for (i = from; count-- > 0; ++i) { + a = sc_vtb_geta(&scp->vtb, i); + if (flip) { + col1 = ((a & 0x7000) >> 4) | (a & 0x0800); + col2 = ((a & 0x8000) >> 4) | (a & 0x0700); + } else { + col1 = (a & 0x0f00); + col2 = (a & 0xf000) >> 4; + } + /* set background color in EGA/VGA latch */ + if (bg != col2) { + bg = col2; + outw(GDCIDX, bg | 0x00); /* set/reset */ + outw(GDCIDX, 0xff08); /* bit mask */ + writeb(d, 0); + c = readb(d); /* set bg color in the latch */ + } + /* foreground color */ + outw(GDCIDX, col1 | 0x00); /* set/reset */ + e = d; + f = &(scp->font[sc_vtb_getc(&scp->vtb, i)*scp->font_size]); + for (j = 0; j < scp->font_size; ++j, ++f) { + outw(GDCIDX, (*f << 8) | 0x08); /* bit mask */ + writeb(e, 0); + e += line_width; + } + ++d; + if ((i % scp->xsize) == scp->xsize - 1) + d += scp->xoff*2 + + (scp->font_size - 1)*line_width; + } + outw(GDCIDX, 0x0000); /* set/reset */ + outw(GDCIDX, 0x0001); /* set/reset enable */ + outw(GDCIDX, 0xff08); /* bit mask */ +} + +static void +vga_vgadraw(scr_stat *scp, int from, int count, int flip) +{ + vm_offset_t d; + vm_offset_t e; + u_char *f; + u_short bg; + u_short col1, col2; + int line_width; + int i, j; + int a; + u_char c; + + line_width = scp->sc->adp->va_line_width; + d = scp->sc->adp->va_window + + scp->xoff + + scp->yoff*scp->font_size*line_width + + (from%scp->xsize) + + scp->font_size*line_width*(from/scp->xsize); + + outw(GDCIDX, 0x0305); /* read mode 0, write mode 3 */ + outw(GDCIDX, 0x0003); /* data rotate/function select */ + outw(GDCIDX, 0x0f01); /* set/reset enable */ + outw(GDCIDX, 0xff08); /* bit mask */ + bg = -1; + if (from + count > scp->xsize*scp->ysize) + count = scp->xsize*scp->ysize - from; + for (i = from; count-- > 0; ++i) { + a = sc_vtb_geta(&scp->vtb, i); + if (flip) { + col1 = ((a & 0x7000) >> 4) | (a & 0x0800); + col2 = ((a & 0x8000) >> 4) | (a & 0x0700); + } else { + col1 = (a & 0x0f00); + col2 = (a & 0xf000) >> 4; + } + /* set background color in EGA/VGA latch */ + if (bg != col2) { + bg = col2; + outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */ + outw(GDCIDX, bg | 0x00); /* set/reset */ + writeb(d, 0); + c = readb(d); /* set bg color in the latch */ + outw(GDCIDX, 0x0305); /* read mode 0, write mode 3 */ + } + /* foreground color */ + outw(GDCIDX, col1 | 0x00); /* set/reset */ + e = d; + f = &(scp->font[sc_vtb_getc(&scp->vtb, i)*scp->font_size]); + for (j = 0; j < scp->font_size; ++j, ++f) { + writeb(e, *f); + e += line_width; + } + ++d; + if ((i % scp->xsize) == scp->xsize - 1) + d += scp->xoff*2 + + (scp->font_size - 1)*line_width; + } + outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */ + outw(GDCIDX, 0x0000); /* set/reset */ + outw(GDCIDX, 0x0001); /* set/reset enable */ +} + +static void +vga_pxlcursor_shape(scr_stat *scp, int base, int height, int blink) +{ + if (base < 0 || base >= scp->font_size) + return; + /* the caller may set height <= 0 in order to disable the cursor */ +#if 0 + scp->cursor_base = base; + scp->cursor_height = height; +#endif +} + +static void +draw_pxlcursor(scr_stat *scp, int at, int on, int flip) +{ + vm_offset_t d; + u_char *f; + int line_width; + int height; + int col; + int a; + int i; + u_char c; + + line_width = scp->sc->adp->va_line_width; + d = scp->sc->adp->va_window + + scp->xoff + + scp->yoff*scp->font_size*line_width + + (at%scp->xsize) + + scp->font_size*line_width*(at/scp->xsize) + + (scp->font_size - scp->cursor_base - 1)*line_width; + + outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */ + outw(GDCIDX, 0x0003); /* data rotate/function select */ + outw(GDCIDX, 0x0f01); /* set/reset enable */ + /* set background color in EGA/VGA latch */ + a = sc_vtb_geta(&scp->vtb, at); + if (flip) + col = (on) ? ((a & 0xf000) >> 4) : (a & 0x0f00); + else + col = (on) ? (a & 0x0f00) : ((a & 0xf000) >> 4); + outw(GDCIDX, col | 0x00); /* set/reset */ + outw(GDCIDX, 0xff08); /* bit mask */ + writeb(d, 0); + c = readb(d); /* set bg color in the latch */ + /* foreground color */ + if (flip) + col = (on) ? (a & 0x0f00) : ((a & 0xf000) >> 4); + else + col = (on) ? ((a & 0xf000) >> 4) : (a & 0x0f00); + outw(GDCIDX, col | 0x00); /* set/reset */ + f = &(scp->font[sc_vtb_getc(&scp->vtb, at)*scp->font_size + + scp->font_size - scp->cursor_base - 1]); + height = imin(scp->cursor_height, scp->font_size); + for (i = 0; i < height; ++i, --f) { + outw(GDCIDX, (*f << 8) | 0x08); /* bit mask */ + writeb(d, 0); + d -= line_width; + } + outw(GDCIDX, 0x0000); /* set/reset */ + outw(GDCIDX, 0x0001); /* set/reset enable */ + outw(GDCIDX, 0xff08); /* bit mask */ +} + +static void +vga_pxlcursor(scr_stat *scp, int at, int blink, int on, int flip) +{ + if (scp->cursor_height <= 0) /* the text cursor is disabled */ + return; + + if (on) { + scp->status |= VR_CURSOR_ON; + draw_pxlcursor(scp, at, on, flip); + } else { + if (scp->status & VR_CURSOR_ON) + draw_pxlcursor(scp, at, on, flip); + scp->status &= ~VR_CURSOR_ON; + } + if (blink) + scp->status |= VR_CURSOR_BLINK; + else + scp->status &= ~VR_CURSOR_BLINK; +} + +static void +vga_pxlblink(scr_stat *scp, int at, int flip) +{ + static int blinkrate = 0; + + if (!(scp->status & VR_CURSOR_BLINK)) + return; + if (!(++blinkrate & 4)) + return; + blinkrate = 0; + scp->status ^= VR_CURSOR_ON; + draw_pxlcursor(scp, at, scp->status & VR_CURSOR_ON, flip); +} + +#ifndef SC_NO_CUTPASTE + +static void +draw_pxlmouse(scr_stat *scp, int x, int y) +{ + vm_offset_t p; + int line_width; + int xoff, yoff; + int ymax; + u_short m; + int i, j; + + line_width = scp->sc->adp->va_line_width; + xoff = (x - scp->xoff*8)%8; + yoff = y - (y/line_width)*line_width; + ymax = imin(y + 16, scp->ypixel); + + outw(GDCIDX, 0x0805); /* read mode 1, write mode 0 */ + outw(GDCIDX, 0x0001); /* set/reset enable */ + outw(GDCIDX, 0x0002); /* color compare */ + outw(GDCIDX, 0x0007); /* color don't care */ + outw(GDCIDX, 0xff08); /* bit mask */ + outw(GDCIDX, 0x0803); /* data rotate/function select (and) */ + p = scp->sc->adp->va_window + line_width*y + x/8; + if (x < scp->xpixel - 16) { + for (i = y, j = 0; i < ymax; ++i, ++j) { + m = ~(mouse_and_mask[j] >> xoff); +#ifdef __i386__ + *(u_char *)p &= m >> 8; + *(u_char *)(p + 1) &= m; +#elif defined(__alpha__) + writeb(p, readb(p) & (m >> 8)); + writeb(p + 1, readb(p + 1) & (m >> 8)); +#endif + p += line_width; + } + } else { + xoff += 8; + for (i = y, j = 0; i < ymax; ++i, ++j) { + m = ~(mouse_and_mask[j] >> xoff); +#ifdef __i386__ + *(u_char *)p &= m; +#elif defined(__alpha__) + writeb(p, readb(p) & (m >> 8)); +#endif + p += line_width; + } + } + outw(GDCIDX, 0x1003); /* data rotate/function select (or) */ + p = scp->sc->adp->va_window + line_width*y + x/8; + if (x < scp->xpixel - 16) { + for (i = y, j = 0; i < ymax; ++i, ++j) { + m = mouse_or_mask[j] >> xoff; +#ifdef __i386__ + *(u_char *)p &= m >> 8; + *(u_char *)(p + 1) &= m; +#elif defined(__alpha__) + writeb(p, readb(p) & (m >> 8)); + writeb(p + 1, readb(p + 1) & (m >> 8)); +#endif + p += line_width; + } + } else { + for (i = y, j = 0; i < ymax; ++i, ++j) { + m = mouse_or_mask[j] >> xoff; +#ifdef __i386__ + *(u_char *)p &= m; +#elif defined(__alpha__) + writeb(p, readb(p) & (m >> 8)); +#endif + p += line_width; + } + } + outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */ + outw(GDCIDX, 0x0003); /* data rotate/function select */ +} + +static void +remove_pxlmouse(scr_stat *scp, int x, int y) +{ + vm_offset_t p; + int col, row; + int pos; + int line_width; + int ymax; + int i; + + /* erase the mouse cursor image */ + col = x/8 - scp->xoff; + row = y/scp->font_size - scp->yoff; + pos = row*scp->xsize + col; + i = (col < scp->xsize - 1) ? 2 : 1; + (*scp->rndr->draw)(scp, pos, i, FALSE); + if (row < scp->ysize - 1) + (*scp->rndr->draw)(scp, pos + scp->xsize, i, FALSE); + + /* paint border if necessary */ + line_width = scp->sc->adp->va_line_width; + outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */ + outw(GDCIDX, 0x0003); /* data rotate/function select */ + outw(GDCIDX, 0x0f01); /* set/reset enable */ + outw(GDCIDX, 0xff08); /* bit mask */ + outw(GDCIDX, (scp->border << 8) | 0x00); /* set/reset */ + if (row == scp->ysize - 1) { + i = (scp->ysize + scp->yoff)*scp->font_size; + ymax = imin(i + scp->font_size, scp->ypixel); + p = scp->sc->adp->va_window + i*line_width + scp->xoff + col; + if (col < scp->xsize - 1) { + for (; i < ymax; ++i) { + writeb(p, 0); + writeb(p + 1, 0); + p += line_width; + } + } else { + for (; i < ymax; ++i) { + writeb(p, 0); + p += line_width; + } + } + } + if ((col == scp->xsize - 1) && (scp->xoff > 0)) { + i = (row + scp->yoff)*scp->font_size; + ymax = imin(i + scp->font_size*2, scp->ypixel); + p = scp->sc->adp->va_window + i*line_width + + scp->xoff + scp->xsize; + for (; i < ymax; ++i) { + writeb(p, 0); + p += line_width; + } + } + outw(GDCIDX, 0x0000); /* set/reset */ + outw(GDCIDX, 0x0001); /* set/reset enable */ +} + +static void +vga_pxlmouse(scr_stat *scp, int x, int y, int on) +{ + if (on) + draw_pxlmouse(scp, x, y); + else + remove_pxlmouse(scp, x, y); +} + +#endif /* SC_NO_CUTPASTE */ +#endif /* SC_PIXEL_MODE */ + +#ifndef SC_NO_MODE_CHANGE + +/* graphics mode renderer */ + +static void +vga_grborder(scr_stat *scp, int color) +{ + (*vidsw[scp->sc->adapter]->set_border)(scp->sc->adp, color); +} + +#endif + +#endif /* NSC > 0 && NVGA > 0 */ diff --git a/sys/dev/syscons/schistory.c b/sys/dev/syscons/schistory.c new file mode 100644 index 0000000..765733c --- /dev/null +++ b/sys/dev/syscons/schistory.c @@ -0,0 +1,222 @@ +/*- + * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp> + * Copyright (c) 1992-1998 Søren Schmidt + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer, + * without modification, immediately at the beginning of the file. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Id:$ + */ + +#include "sc.h" +#include "opt_syscons.h" + +#if NSC > 0 + +#ifndef SC_NO_HISTORY + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/tty.h> +#include <sys/kernel.h> +#include <sys/malloc.h> + +#include <machine/console.h> + +#include <dev/syscons/syscons.h> + +#if !defined(SC_MAX_HISTORY_SIZE) +#define SC_MAX_HISTORY_SIZE (1000 * MAXCONS * NSC) +#endif + +#if !defined(SC_HISTORY_SIZE) +#define SC_HISTORY_SIZE (ROW * 4) +#endif + +#if (SC_HISTORY_SIZE * MAXCONS * NSC) > SC_MAX_HISTORY_SIZE +#undef SC_MAX_HISTORY_SIZE +#define SC_MAX_HISTORY_SIZE (SC_HISTORY_SIZE * MAXCONS * NSC) +#endif + +/* local variables */ +static int extra_history_size + = SC_MAX_HISTORY_SIZE - SC_HISTORY_SIZE*MAXCONS; + +/* local functions */ +static void history_to_screen(scr_stat *scp); + +/* allocate a history buffer */ +int +sc_alloc_history_buffer(scr_stat *scp, int lines, int wait) +{ + /* + * syscons unconditionally allocates buffers upto + * SC_HISTORY_SIZE lines or scp->ysize lines, whichever + * is larger. A value greater than that is allowed, + * subject to extra_history_size. + */ + sc_vtb_t *history; + int cur_lines; /* current buffer size */ + int min_lines; /* guaranteed buffer size */ + + if (lines <= 0) + lines = SC_HISTORY_SIZE; /* use the default value */ + lines = imax(lines, scp->ysize); + min_lines = imax(SC_HISTORY_SIZE, scp->ysize); + + history = scp->history; + scp->history = NULL; + if (history == NULL) { + cur_lines = 0; + } else { + cur_lines = sc_vtb_rows(history); + if (cur_lines > min_lines) + extra_history_size += cur_lines - min_lines; + sc_vtb_destroy(history); + } + + if (lines > min_lines) + extra_history_size -= lines - min_lines; + history = (sc_vtb_t *)malloc(sizeof(*history), + M_DEVBUF, (wait) ? M_WAITOK : M_NOWAIT); + if (history != NULL) + sc_vtb_init(history, VTB_RINGBUFFER, scp->xsize, lines, + NULL, wait); + scp->history_pos = 0; + scp->history = history; + + return 0; +} + +/* copy entire screen into the top of the history buffer */ +void +sc_hist_save(scr_stat *scp) +{ + sc_vtb_append(&scp->vtb, 0, scp->history, scp->xsize*scp->ysize); + scp->history_pos = sc_vtb_tail(scp->history); +} + +/* restore the screen by copying from the history buffer */ +int +sc_hist_restore(scr_stat *scp) +{ + int ret; + + if (scp->history_pos != sc_vtb_tail(scp->history)) { + scp->history_pos = sc_vtb_tail(scp->history); + history_to_screen(scp); + ret = 0; + } else { + ret = 1; + } + sc_vtb_seek(scp->history, sc_vtb_pos(scp->history, + sc_vtb_tail(scp->history), + -scp->xsize*scp->ysize)); + return ret; +} + +/* copy screen-full of saved lines */ +static void +history_to_screen(scr_stat *scp) +{ + int pos; + int i; + + pos = scp->history_pos; + for (i = 1; i <= scp->ysize; ++i) { + pos = sc_vtb_pos(scp->history, pos, -scp->xsize); + sc_vtb_copy(scp->history, pos, + &scp->vtb, scp->xsize*(scp->ysize - i), + scp->xsize); + } + mark_all(scp); +} + +/* go to the tail of the history buffer */ +void +sc_hist_home(scr_stat *scp) +{ + scp->history_pos = sc_vtb_tail(scp->history); + history_to_screen(scp); +} + +/* go to the top of the history buffer */ +void +sc_hist_end(scr_stat *scp) +{ + scp->history_pos = sc_vtb_pos(scp->history, sc_vtb_tail(scp->history), + scp->xsize*scp->ysize); + history_to_screen(scp); +} + +/* move one line up */ +int +sc_hist_up_line(scr_stat *scp) +{ + if (sc_vtb_pos(scp->history, scp->history_pos, -(scp->xsize*scp->ysize)) + == sc_vtb_tail(scp->history)) + return -1; + scp->history_pos = sc_vtb_pos(scp->history, scp->history_pos, + -scp->xsize); + history_to_screen(scp); + return 0; +} + +/* move one line down */ +int +sc_hist_down_line(scr_stat *scp) +{ + if (scp->history_pos == sc_vtb_tail(scp->history)) + return -1; + scp->history_pos = sc_vtb_pos(scp->history, scp->history_pos, + scp->xsize); + history_to_screen(scp); + return 0; +} + +int +sc_hist_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, + struct proc *p) +{ + scr_stat *scp; + + switch (cmd) { + + case CONS_HISTORY: /* set history size */ + scp = sc_get_scr_stat(tp->t_dev); + if (*(int *)data <= 0) + return EINVAL; + if (scp->status & BUFFER_SAVED) + return EBUSY; + return sc_alloc_history_buffer(scp, + imax(*(int *)data, scp->ysize), + TRUE); + } + + return ENOIOCTL; +} + +#endif /* SC_NO_HISTORY */ + +#endif /* NSC */ diff --git a/sys/dev/syscons/scmouse.c b/sys/dev/syscons/scmouse.c new file mode 100644 index 0000000..8d8dc67 --- /dev/null +++ b/sys/dev/syscons/scmouse.c @@ -0,0 +1,1083 @@ +/*- + * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer as + * the first lines of this file unmodified. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Id:$ + */ + +#include "sc.h" +#include "opt_syscons.h" + +#if NSC > 0 + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/conf.h> +#include <sys/signalvar.h> +#include <sys/proc.h> +#include <sys/tty.h> +#include <sys/kernel.h> +#include <sys/malloc.h> + +#include <machine/console.h> +#include <machine/mouse.h> + +#include <dev/syscons/syscons.h> + +#define SC_WAKEUP_DELTA 20 + +/* for backward compatibility */ +#define OLD_CONS_MOUSECTL _IOWR('c', 10, old_mouse_info_t) + +typedef struct old_mouse_data { + int x; + int y; + int buttons; +} old_mouse_data_t; + +typedef struct old_mouse_info { + int operation; + union { + struct old_mouse_data data; + struct mouse_mode mode; + } u; +} old_mouse_info_t; + +/* local variables */ +#ifndef SC_NO_SYSMOUSE +static int mouse_level; /* sysmouse protocol level */ +static mousestatus_t mouse_status = { 0, 0, 0, 0, 0, 0 }; +static int cut_buffer_size; +static u_char *cut_buffer; +#endif /* SC_NO_SYSMOUE */ + +/* local functions */ +#ifndef SC_NO_SYSMOUSE +static void set_mouse_pos(scr_stat *scp); +#ifndef SC_NO_CUTPASTE +static int skip_spc_right(scr_stat *scp, int p); +static int skip_spc_left(scr_stat *scp, int p); +static void mouse_cut(scr_stat *scp); +static void mouse_cut_start(scr_stat *scp); +static void mouse_cut_end(scr_stat *scp); +static void mouse_cut_word(scr_stat *scp); +static void mouse_cut_line(scr_stat *scp); +static void mouse_cut_extend(scr_stat *scp); +static void mouse_paste(scr_stat *scp); +#endif /* SC_NO_CUTPASTE */ +#endif /* SC_NO_SYSMOUE */ + +#ifndef SC_NO_CUTPASTE +/* allocate a cut buffer */ +void +sc_alloc_cut_buffer(scr_stat *scp, int wait) +{ + u_char *p; + + if ((cut_buffer == NULL) + || (cut_buffer_size < scp->xsize * scp->ysize + 1)) { + p = cut_buffer; + cut_buffer = NULL; + if (p != NULL) + free(p, M_DEVBUF); + cut_buffer_size = scp->xsize * scp->ysize + 1; + p = (u_char *)malloc(cut_buffer_size, + M_DEVBUF, (wait) ? M_WAITOK : M_NOWAIT); + if (p != NULL) + p[0] = '\0'; + cut_buffer = p; + } +} +#endif /* SC_NO_CUTPASTE */ + +#ifndef SC_NO_SYSMOUSE + +/* modify the sysmouse software level */ +void +sc_mouse_set_level(int level) +{ + mouse_level = level; +} + +/* move mouse */ +void +sc_mouse_move(scr_stat *scp, int x, int y) +{ + int s; + + s = spltty(); + scp->mouse_xpos = x; + scp->mouse_ypos = y; + scp->mouse_pos = scp->mouse_oldpos = + (y/scp->font_size - scp->yoff)*scp->xsize + x/8 - scp->xoff; + splx(s); +} + +/* adjust mouse position */ +static void +set_mouse_pos(scr_stat *scp) +{ + static int last_xpos = -1, last_ypos = -1; + + if (scp->mouse_xpos < scp->xoff*8) + scp->mouse_xpos = scp->xoff*8; + if (scp->mouse_ypos < scp->yoff*scp->font_size) + scp->mouse_ypos = scp->yoff*scp->font_size; + if (ISGRAPHSC(scp)) { + if (scp->mouse_xpos > scp->xpixel-1) + scp->mouse_xpos = scp->xpixel-1; + if (scp->mouse_ypos > scp->ypixel-1) + scp->mouse_ypos = scp->ypixel-1; + return; + } else { + if (scp->mouse_xpos > (scp->xsize + scp->xoff)*8 - 1) + scp->mouse_xpos = (scp->xsize + scp->xoff)*8 - 1; + if (scp->mouse_ypos > (scp->ysize + scp->yoff)*scp->font_size - 1) + scp->mouse_ypos = (scp->ysize + scp->yoff)*scp->font_size - 1; + } + + if (scp->mouse_xpos != last_xpos || scp->mouse_ypos != last_ypos) { + scp->status |= MOUSE_MOVED; + scp->mouse_pos = + (scp->mouse_ypos/scp->font_size - scp->yoff)*scp->xsize + + scp->mouse_xpos/8 - scp->xoff; +#ifndef SC_NO_CUTPASTE + if ((scp->status & MOUSE_VISIBLE) && (scp->status & MOUSE_CUTTING)) + mouse_cut(scp); +#endif + } +} + +#ifndef SC_NO_CUTPASTE + +void +sc_draw_mouse_image(scr_stat *scp) +{ + if (ISGRAPHSC(scp)) + return; + + ++scp->sc->videoio_in_progress; + (*scp->rndr->draw_mouse)(scp, scp->mouse_xpos, scp->mouse_ypos, TRUE); + scp->mouse_oldpos = scp->mouse_pos; + --scp->sc->videoio_in_progress; +} + +void +sc_remove_mouse_image(scr_stat *scp) +{ + int size; + int i; + + if (ISGRAPHSC(scp)) + return; + + ++scp->sc->videoio_in_progress; + (*scp->rndr->draw_mouse)(scp, + (scp->mouse_oldpos%scp->xsize + scp->xoff)*8, + (scp->mouse_oldpos/scp->xsize + scp->yoff) + * scp->font_size, + FALSE); + size = scp->xsize*scp->ysize; + i = scp->mouse_oldpos; + mark_for_update(scp, i); + mark_for_update(scp, i); +#ifndef PC98 + if (i + scp->xsize + 1 < size) { + mark_for_update(scp, i + scp->xsize + 1); + } else if (i + scp->xsize < size) { + mark_for_update(scp, i + scp->xsize); + } else if (i + 1 < size) { + mark_for_update(scp, i + 1); + } +#endif /* PC98 */ + --scp->sc->videoio_in_progress; +} + +int +sc_inside_cutmark(scr_stat *scp, int pos) +{ + int start; + int end; + + if (scp->mouse_cut_end < 0) + return FALSE; + if (scp->mouse_cut_start <= scp->mouse_cut_end) { + start = scp->mouse_cut_start; + end = scp->mouse_cut_end; + } else { + start = scp->mouse_cut_end; + end = scp->mouse_cut_start - 1; + } + return ((start <= pos) && (pos <= end)); +} + +void +sc_remove_cutmarking(scr_stat *scp) +{ + int s; + + s = spltty(); + if (scp->mouse_cut_end >= 0) { + mark_for_update(scp, scp->mouse_cut_start); + mark_for_update(scp, scp->mouse_cut_end); + } + scp->mouse_cut_start = scp->xsize*scp->ysize; + scp->mouse_cut_end = -1; + splx(s); + scp->status &= ~MOUSE_CUTTING; +} + +void +sc_remove_all_cutmarkings(sc_softc_t *sc) +{ + int i; + + /* delete cut markings in all vtys */ + for (i = 0; i < sc->vtys; ++i) { + if (sc->console[i] == NULL) + continue; + sc_remove_cutmarking(sc->console[i]); + } +} + +void +sc_remove_all_mouse(sc_softc_t *sc) +{ + int i; + + for (i = 0; i < sc->vtys; ++i) { + if (sc->console[i] == NULL) + continue; + if (sc->console[i]->status & MOUSE_VISIBLE) { + sc->console[i]->status &= ~MOUSE_VISIBLE; + mark_all(sc->console[i]); + } + } +} + +#define isspace(c) (((c) & 0xff) == ' ') + +/* skip spaces to right */ +static int +skip_spc_right(scr_stat *scp, int p) +{ + int c; + int i; + + for (i = p % scp->xsize; i < scp->xsize; ++i) { + c = sc_vtb_getc(&scp->vtb, p); + if (!isspace(c)) + break; + ++p; + } + return i; +} + +/* skip spaces to left */ +static int +skip_spc_left(scr_stat *scp, int p) +{ + int c; + int i; + + for (i = p-- % scp->xsize - 1; i >= 0; --i) { + c = sc_vtb_getc(&scp->vtb, p); + if (!isspace(c)) + break; + --p; + } + return i; +} + +/* copy marked region to the cut buffer */ +static void +mouse_cut(scr_stat *scp) +{ + int start; + int end; + int from; + int to; + int blank; + int c; + int p; + int s; + int i; + + start = scp->mouse_cut_start; + end = scp->mouse_cut_end; + if (scp->mouse_pos >= start) { + from = start; + to = end = scp->mouse_pos; + } else { + from = end = scp->mouse_pos; + to = start - 1; + } + for (p = from, i = blank = 0; p <= to; ++p) { + cut_buffer[i] = sc_vtb_getc(&scp->vtb, p); + /* remember the position of the last non-space char */ + if (!isspace(cut_buffer[i++])) + blank = i; /* the first space after the last non-space */ + /* trim trailing blank when crossing lines */ + if ((p % scp->xsize) == (scp->xsize - 1)) { + cut_buffer[blank] = '\r'; + i = blank + 1; + } + } + cut_buffer[i] = '\0'; + + /* scan towards the end of the last line */ + --p; + for (i = p % scp->xsize; i < scp->xsize; ++i) { + c = sc_vtb_getc(&scp->vtb, p); + if (!isspace(c)) + break; + ++p; + } + /* if there is nothing but blank chars, trim them, but mark towards eol */ + if (i >= scp->xsize) { + if (end >= start) + to = end = p - 1; + else + to = start = p; + cut_buffer[blank++] = '\r'; + cut_buffer[blank] = '\0'; + } + + /* remove the current marking */ + s = spltty(); + if (scp->mouse_cut_start <= scp->mouse_cut_end) { + mark_for_update(scp, scp->mouse_cut_start); + mark_for_update(scp, scp->mouse_cut_end); + } else if (scp->mouse_cut_end >= 0) { + mark_for_update(scp, scp->mouse_cut_end); + mark_for_update(scp, scp->mouse_cut_start); + } + + /* mark the new region */ + scp->mouse_cut_start = start; + scp->mouse_cut_end = end; + mark_for_update(scp, from); + mark_for_update(scp, to); + splx(s); +} + +/* a mouse button is pressed, start cut operation */ +static void +mouse_cut_start(scr_stat *scp) +{ + int i; + int j; + int s; + + if (scp->status & MOUSE_VISIBLE) { + i = scp->mouse_cut_start; + j = scp->mouse_cut_end; + sc_remove_all_cutmarkings(scp->sc); + if (scp->mouse_pos == i && i == j) { + cut_buffer[0] = '\0'; + } else if (skip_spc_right(scp, scp->mouse_pos) >= scp->xsize) { + /* if the pointer is on trailing blank chars, mark towards eol */ + i = skip_spc_left(scp, scp->mouse_pos) + 1; + s = spltty(); + scp->mouse_cut_start = + (scp->mouse_pos / scp->xsize) * scp->xsize + i; + scp->mouse_cut_end = + (scp->mouse_pos / scp->xsize + 1) * scp->xsize - 1; + splx(s); + cut_buffer[0] = '\r'; + cut_buffer[1] = '\0'; + scp->status |= MOUSE_CUTTING; + } else { + s = spltty(); + scp->mouse_cut_start = scp->mouse_pos; + scp->mouse_cut_end = scp->mouse_cut_start; + splx(s); + cut_buffer[0] = sc_vtb_getc(&scp->vtb, scp->mouse_cut_start); + cut_buffer[1] = '\0'; + scp->status |= MOUSE_CUTTING; + } + mark_all(scp); /* this is probably overkill XXX */ + } +} + +/* end of cut operation */ +static void +mouse_cut_end(scr_stat *scp) +{ + if (scp->status & MOUSE_VISIBLE) + scp->status &= ~MOUSE_CUTTING; +} + +/* copy a word under the mouse pointer */ +static void +mouse_cut_word(scr_stat *scp) +{ + int start; + int end; + int sol; + int eol; + int c; + int s; + int i; + int j; + + /* + * Because we don't have locale information in the kernel, + * we only distinguish space char and non-space chars. Punctuation + * chars, symbols and other regular chars are all treated alike. + */ + if (scp->status & MOUSE_VISIBLE) { + /* remove the current cut mark */ + s = spltty(); + if (scp->mouse_cut_start <= scp->mouse_cut_end) { + mark_for_update(scp, scp->mouse_cut_start); + mark_for_update(scp, scp->mouse_cut_end); + } else if (scp->mouse_cut_end >= 0) { + mark_for_update(scp, scp->mouse_cut_end); + mark_for_update(scp, scp->mouse_cut_start); + } + scp->mouse_cut_start = scp->xsize*scp->ysize; + scp->mouse_cut_end = -1; + splx(s); + + sol = (scp->mouse_pos / scp->xsize) * scp->xsize; + eol = sol + scp->xsize; + c = sc_vtb_getc(&scp->vtb, scp->mouse_pos); + if (isspace(c)) { + /* blank space */ + for (j = scp->mouse_pos; j >= sol; --j) { + c = sc_vtb_getc(&scp->vtb, j); + if (!isspace(c)) + break; + } + start = ++j; + for (j = scp->mouse_pos; j < eol; ++j) { + c = sc_vtb_getc(&scp->vtb, j); + if (!isspace(c)) + break; + } + end = j - 1; + } else { + /* non-space word */ + for (j = scp->mouse_pos; j >= sol; --j) { + c = sc_vtb_getc(&scp->vtb, j); + if (isspace(c)) + break; + } + start = ++j; + for (j = scp->mouse_pos; j < eol; ++j) { + c = sc_vtb_getc(&scp->vtb, j); + if (isspace(c)) + break; + } + end = j - 1; + } + + /* copy the found word */ + for (i = 0, j = start; j <= end; ++j) + cut_buffer[i++] = sc_vtb_getc(&scp->vtb, j); + cut_buffer[i] = '\0'; + scp->status |= MOUSE_CUTTING; + + /* mark the region */ + s = spltty(); + scp->mouse_cut_start = start; + scp->mouse_cut_end = end; + mark_for_update(scp, start); + mark_for_update(scp, end); + splx(s); + } +} + +/* copy a line under the mouse pointer */ +static void +mouse_cut_line(scr_stat *scp) +{ + int s; + int i; + int j; + + if (scp->status & MOUSE_VISIBLE) { + /* remove the current cut mark */ + s = spltty(); + if (scp->mouse_cut_start <= scp->mouse_cut_end) { + mark_for_update(scp, scp->mouse_cut_start); + mark_for_update(scp, scp->mouse_cut_end); + } else if (scp->mouse_cut_end >= 0) { + mark_for_update(scp, scp->mouse_cut_end); + mark_for_update(scp, scp->mouse_cut_start); + } + + /* mark the entire line */ + scp->mouse_cut_start = + (scp->mouse_pos / scp->xsize) * scp->xsize; + scp->mouse_cut_end = scp->mouse_cut_start + scp->xsize - 1; + mark_for_update(scp, scp->mouse_cut_start); + mark_for_update(scp, scp->mouse_cut_end); + splx(s); + + /* copy the line into the cut buffer */ + for (i = 0, j = scp->mouse_cut_start; j <= scp->mouse_cut_end; ++j) + cut_buffer[i++] = sc_vtb_getc(&scp->vtb, j); + cut_buffer[i++] = '\r'; + cut_buffer[i] = '\0'; + scp->status |= MOUSE_CUTTING; + } +} + +/* extend the marked region to the mouse pointer position */ +static void +mouse_cut_extend(scr_stat *scp) +{ + int start; + int end; + int s; + + if ((scp->status & MOUSE_VISIBLE) && !(scp->status & MOUSE_CUTTING) + && (scp->mouse_cut_end >= 0)) { + if (scp->mouse_cut_start <= scp->mouse_cut_end) { + start = scp->mouse_cut_start; + end = scp->mouse_cut_end; + } else { + start = scp->mouse_cut_end; + end = scp->mouse_cut_start - 1; + } + s = spltty(); + if (scp->mouse_pos > end) { + scp->mouse_cut_start = start; + scp->mouse_cut_end = end; + } else if (scp->mouse_pos < start) { + scp->mouse_cut_start = end + 1; + scp->mouse_cut_end = start; + } else { + if (scp->mouse_pos - start > end + 1 - scp->mouse_pos) { + scp->mouse_cut_start = start; + scp->mouse_cut_end = end; + } else { + scp->mouse_cut_start = end + 1; + scp->mouse_cut_end = start; + } + } + splx(s); + mouse_cut(scp); + scp->status |= MOUSE_CUTTING; + } +} + +/* paste cut buffer contents into the current vty */ +static void +mouse_paste(scr_stat *scp) +{ + if (scp->status & MOUSE_VISIBLE) + sc_paste(scp, cut_buffer, strlen(cut_buffer)); +} + +#endif /* SC_NO_CUTPASTE */ + +int +sc_mouse_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, + struct proc *p) +{ + + scr_stat *scp; + int s; + int i; + + /* scp == NULL, if tp == sc_get_mouse_tty() (/dev/sysmouse) */ + scp = sc_get_scr_stat(tp->t_dev); + + switch (cmd) { + + case CONS_MOUSECTL: /* control mouse arrow */ + case OLD_CONS_MOUSECTL: + { + /* MOUSE_BUTTON?DOWN -> MOUSE_MSC_BUTTON?UP */ + static int butmap[8] = { + MOUSE_MSC_BUTTON1UP | MOUSE_MSC_BUTTON2UP | MOUSE_MSC_BUTTON3UP, + MOUSE_MSC_BUTTON2UP | MOUSE_MSC_BUTTON3UP, + MOUSE_MSC_BUTTON1UP | MOUSE_MSC_BUTTON3UP, + MOUSE_MSC_BUTTON3UP, + MOUSE_MSC_BUTTON1UP | MOUSE_MSC_BUTTON2UP, + MOUSE_MSC_BUTTON2UP, + MOUSE_MSC_BUTTON1UP, + 0, + }; + mouse_info_t *mouse = (mouse_info_t*)data; + mouse_info_t buf; + scr_stat *cur_scp; + struct tty *mtty; + + if (scp == NULL) + return ENOTTY; + + if (cmd == OLD_CONS_MOUSECTL) { + static u_char swapb[] = { 0, 4, 2, 6, 1, 5, 3, 7 }; + old_mouse_info_t *old_mouse = (old_mouse_info_t *)data; + + mouse = &buf; + mouse->operation = old_mouse->operation; + switch (mouse->operation) { + case MOUSE_MODE: + mouse->u.mode = old_mouse->u.mode; + break; + case MOUSE_SHOW: + case MOUSE_HIDE: + break; + case MOUSE_MOVEABS: + case MOUSE_MOVEREL: + case MOUSE_ACTION: + mouse->u.data.x = old_mouse->u.data.x; + mouse->u.data.y = old_mouse->u.data.y; + mouse->u.data.z = 0; + mouse->u.data.buttons = swapb[old_mouse->u.data.buttons & 0x7]; + break; + case MOUSE_GETINFO: + old_mouse->u.data.x = scp->mouse_xpos; + old_mouse->u.data.y = scp->mouse_ypos; + old_mouse->u.data.buttons = swapb[scp->mouse_buttons & 0x7]; + break; + default: + return EINVAL; + } + } + + cur_scp = scp->sc->cur_scp; + + switch (mouse->operation) { + case MOUSE_MODE: + if (ISSIGVALID(mouse->u.mode.signal)) { + scp->mouse_signal = mouse->u.mode.signal; + scp->mouse_proc = p; + scp->mouse_pid = p->p_pid; + } + else { + scp->mouse_signal = 0; + scp->mouse_proc = NULL; + scp->mouse_pid = 0; + } + return 0; + + case MOUSE_SHOW: + if (!ISMOUSEAVAIL(scp->sc->adp->va_flags)) + return EINVAL; + s = spltty(); + if (!(scp->sc->flags & SC_MOUSE_ENABLED)) { + scp->sc->flags |= SC_MOUSE_ENABLED; + if (!ISGRAPHSC(cur_scp)) { + cur_scp->status |= MOUSE_VISIBLE; + mark_all(cur_scp); + } + splx(s); + return 0; + } else { + splx(s); + return EINVAL; + } + break; +#if 0 + if (!(scp->status & MOUSE_ENABLED)) { + scp->mouse_oldpos = scp->mouse_pos; + scp->status |= MOUSE_ENABLED; + if (!ISGRAPHSC(scp)) + scp->status |= MOUSE_VISIBLE; + splx(s); + mark_all(scp); + return 0; + } else { + splx(s); + return EINVAL; + } + break; +#endif + + case MOUSE_HIDE: + s = spltty(); + if (scp->sc->flags & SC_MOUSE_ENABLED) { + scp->sc->flags &= ~SC_MOUSE_ENABLED; + sc_remove_all_mouse(scp->sc); + splx(s); + return 0; + } else { + splx(s); + return EINVAL; + } + break; +#if 0 + if (scp->status & MOUSE_ENABLED) { + scp->status &= ~(MOUSE_ENABLED | MOUSE_VISIBLE); + mark_all(scp); + splx(s); + return 0; + } else { + splx(s); + return EINVAL; + } + break; +#endif + + case MOUSE_MOVEABS: + s = spltty(); + scp->mouse_xpos = mouse->u.data.x; + scp->mouse_ypos = mouse->u.data.y; + set_mouse_pos(scp); + splx(s); + break; + + case MOUSE_MOVEREL: + s = spltty(); + scp->mouse_xpos += mouse->u.data.x; + scp->mouse_ypos += mouse->u.data.y; + set_mouse_pos(scp); + splx(s); + break; + + case MOUSE_GETINFO: + mouse->u.data.x = scp->mouse_xpos; + mouse->u.data.y = scp->mouse_ypos; + mouse->u.data.z = 0; + mouse->u.data.buttons = scp->mouse_buttons; + return 0; + + case MOUSE_ACTION: + case MOUSE_MOTION_EVENT: + /* send out mouse event on /dev/sysmouse */ +#if 0 + /* this should maybe only be settable from /dev/consolectl SOS */ + if (SC_VTY(tp->t_dev) != SC_CONSOLECTL) + return ENOTTY; +#endif + mouse_status.dx += mouse->u.data.x; + mouse_status.dy += mouse->u.data.y; + mouse_status.dz += mouse->u.data.z; + if (mouse->operation == MOUSE_ACTION) + mouse_status.button = mouse->u.data.buttons; + mouse_status.flags |= + ((mouse->u.data.x || mouse->u.data.y || mouse->u.data.z) ? + MOUSE_POSCHANGED : 0) + | (mouse_status.obutton ^ mouse_status.button); + if (mouse_status.flags == 0) + return 0; + + mtty = sc_get_mouse_tty(); + if (mtty->t_state & TS_ISOPEN) { + u_char buf[MOUSE_SYS_PACKETSIZE]; + + /* the first five bytes are compatible with MouseSystems' */ + buf[0] = MOUSE_MSC_SYNC + | butmap[mouse_status.button & MOUSE_STDBUTTONS]; + i = imax(imin(mouse->u.data.x, 255), -256); + buf[1] = i >> 1; + buf[3] = i - buf[1]; + i = -imax(imin(mouse->u.data.y, 255), -256); + buf[2] = i >> 1; + buf[4] = i - buf[2]; + for (i = 0; i < MOUSE_MSC_PACKETSIZE; i++) + (*linesw[mtty->t_line].l_rint)(buf[i], mtty); + if (mouse_level >= 1) { /* extended part */ + i = imax(imin(mouse->u.data.z, 127), -128); + buf[5] = (i >> 1) & 0x7f; + buf[6] = (i - (i >> 1)) & 0x7f; + /* buttons 4-10 */ + buf[7] = (~mouse_status.button >> 3) & 0x7f; + for (i = MOUSE_MSC_PACKETSIZE; + i < MOUSE_SYS_PACKETSIZE; i++) + (*linesw[mtty->t_line].l_rint)(buf[i], mtty); + } + } + + if (cur_scp->mouse_signal) { + cur_scp->mouse_buttons = mouse->u.data.buttons; + /* has controlling process died? */ + if (cur_scp->mouse_proc && + (cur_scp->mouse_proc != pfind(cur_scp->mouse_pid))){ + cur_scp->mouse_signal = 0; + cur_scp->mouse_proc = NULL; + cur_scp->mouse_pid = 0; + } + else + psignal(cur_scp->mouse_proc, cur_scp->mouse_signal); + break; + } + + /* + * If any buttons are down or the mouse has moved a lot, + * stop the screen saver. + */ + if (((mouse->operation == MOUSE_ACTION) && mouse->u.data.buttons) + || (mouse->u.data.x*mouse->u.data.x + + mouse->u.data.y*mouse->u.data.y + >= SC_WAKEUP_DELTA*SC_WAKEUP_DELTA)) { + sc_touch_scrn_saver(); + } + + if (ISGRAPHSC(cur_scp) || (cut_buffer == NULL)) + break; + +#ifndef SC_NO_CUTPASTE + if (cur_scp->sc->flags & SC_MOUSE_ENABLED) + cur_scp->status |= MOUSE_VISIBLE; + + if (mouse->operation == MOUSE_ACTION) { + /* process button presses */ + if (cur_scp->mouse_buttons ^ mouse->u.data.buttons) { + cur_scp->mouse_buttons = mouse->u.data.buttons; + if (cur_scp->mouse_buttons & MOUSE_BUTTON1DOWN) + mouse_cut_start(cur_scp); + else + mouse_cut_end(cur_scp); + if (cur_scp->mouse_buttons & MOUSE_BUTTON2DOWN || + cur_scp->mouse_buttons & MOUSE_BUTTON3DOWN) + mouse_paste(cur_scp); + } + } +#else /* SC_NO_CUTPASTE */ + if (mouse->operation == MOUSE_ACTION) + cur_scp->mouse_buttons = mouse->u.data.buttons; +#endif /* SC_NO_CUTPASTE */ + + if (mouse->u.data.x != 0 || mouse->u.data.y != 0) { + s = spltty(); + cur_scp->mouse_xpos += mouse->u.data.x; + cur_scp->mouse_ypos += mouse->u.data.y; + set_mouse_pos(cur_scp); + splx(s); + } + break; + + case MOUSE_BUTTON_EVENT: + if ((mouse->u.event.id & MOUSE_BUTTONS) == 0) + return EINVAL; + if (mouse->u.event.value < 0) + return EINVAL; +#if 0 + /* this should maybe only be settable from /dev/consolectl SOS */ + if (SC_VTY(tp->t_dev) != SC_CONSOLECTL) + return ENOTTY; +#endif + if (mouse->u.event.value > 0) { + cur_scp->mouse_buttons |= mouse->u.event.id; + mouse_status.button |= mouse->u.event.id; + } else { + cur_scp->mouse_buttons &= ~mouse->u.event.id; + mouse_status.button &= ~mouse->u.event.id; + } + mouse_status.flags |= mouse_status.obutton ^ mouse_status.button; + if (mouse_status.flags == 0) + return 0; + + mtty = sc_get_mouse_tty(); + if (mtty->t_state & TS_ISOPEN) { + u_char buf[MOUSE_SYS_PACKETSIZE]; + + buf[0] = MOUSE_MSC_SYNC + | butmap[mouse_status.button & MOUSE_STDBUTTONS]; + buf[7] = (~mouse_status.button >> 3) & 0x7f; + buf[1] = buf[2] = buf[3] = buf[4] = buf[5] = buf[6] = 0; + for (i = 0; + i < ((mouse_level >= 1) ? MOUSE_SYS_PACKETSIZE + : MOUSE_MSC_PACKETSIZE); i++) + (*linesw[mtty->t_line].l_rint)(buf[i], mtty); + } + + if (cur_scp->mouse_signal) { + if (cur_scp->mouse_proc && + (cur_scp->mouse_proc != pfind(cur_scp->mouse_pid))){ + cur_scp->mouse_signal = 0; + cur_scp->mouse_proc = NULL; + cur_scp->mouse_pid = 0; + } + else + psignal(cur_scp->mouse_proc, cur_scp->mouse_signal); + break; + } + + /* if a button is held down, stop the screen saver */ + if (mouse->u.event.value > 0) + sc_touch_scrn_saver(); + + if (ISGRAPHSC(cur_scp) || (cut_buffer == NULL)) + break; + +#ifndef SC_NO_CUTPASTE + if (cur_scp->sc->flags & SC_MOUSE_ENABLED) + cur_scp->status |= MOUSE_VISIBLE; + + switch (mouse->u.event.id) { + case MOUSE_BUTTON1DOWN: + switch (mouse->u.event.value % 4) { + case 0: /* up */ + mouse_cut_end(cur_scp); + break; + case 1: /* single click: start cut operation */ + mouse_cut_start(cur_scp); + break; + case 2: /* double click: cut a word */ + mouse_cut_word(cur_scp); + mouse_cut_end(cur_scp); + break; + case 3: /* triple click: cut a line */ + mouse_cut_line(cur_scp); + mouse_cut_end(cur_scp); + break; + } + break; + case MOUSE_BUTTON2DOWN: + switch (mouse->u.event.value) { + case 0: /* up */ + break; + default: + mouse_paste(cur_scp); + break; + } + break; + case MOUSE_BUTTON3DOWN: + switch (mouse->u.event.value) { + case 0: /* up */ + if (!(cur_scp->mouse_buttons & MOUSE_BUTTON1DOWN)) + mouse_cut_end(cur_scp); + break; + default: + mouse_cut_extend(cur_scp); + break; + } + break; + } +#endif /* SC_NO_CUTPASTE */ + break; + + default: + return EINVAL; + } + + return 0; + } + + /* MOUSE_XXX: /dev/sysmouse ioctls */ + case MOUSE_GETHWINFO: /* get device information */ + { + mousehw_t *hw = (mousehw_t *)data; + + if (tp != sc_get_mouse_tty()) + return ENOTTY; + hw->buttons = 10; /* XXX unknown */ + hw->iftype = MOUSE_IF_SYSMOUSE; + hw->type = MOUSE_MOUSE; + hw->model = MOUSE_MODEL_GENERIC; + hw->hwid = 0; + return 0; + } + + case MOUSE_GETMODE: /* get protocol/mode */ + { + mousemode_t *mode = (mousemode_t *)data; + + if (tp != sc_get_mouse_tty()) + return ENOTTY; + mode->level = mouse_level; + switch (mode->level) { + case 0: + /* at this level, sysmouse emulates MouseSystems protocol */ + mode->protocol = MOUSE_PROTO_MSC; + mode->rate = -1; /* unknown */ + mode->resolution = -1; /* unknown */ + mode->accelfactor = 0; /* disabled */ + mode->packetsize = MOUSE_MSC_PACKETSIZE; + mode->syncmask[0] = MOUSE_MSC_SYNCMASK; + mode->syncmask[1] = MOUSE_MSC_SYNC; + break; + + case 1: + /* at this level, sysmouse uses its own protocol */ + mode->protocol = MOUSE_PROTO_SYSMOUSE; + mode->rate = -1; + mode->resolution = -1; + mode->accelfactor = 0; + mode->packetsize = MOUSE_SYS_PACKETSIZE; + mode->syncmask[0] = MOUSE_SYS_SYNCMASK; + mode->syncmask[1] = MOUSE_SYS_SYNC; + break; + } + return 0; + } + + case MOUSE_SETMODE: /* set protocol/mode */ + { + mousemode_t *mode = (mousemode_t *)data; + + if (tp != sc_get_mouse_tty()) + return ENOTTY; + if ((mode->level < 0) || (mode->level > 1)) + return EINVAL; + sc_mouse_set_level(mode->level); + return 0; + } + + case MOUSE_GETLEVEL: /* get operation level */ + if (tp != sc_get_mouse_tty()) + return ENOTTY; + *(int *)data = mouse_level; + return 0; + + case MOUSE_SETLEVEL: /* set operation level */ + if (tp != sc_get_mouse_tty()) + return ENOTTY; + if ((*(int *)data < 0) || (*(int *)data > 1)) + return EINVAL; + sc_mouse_set_level(*(int *)data); + return 0; + + case MOUSE_GETSTATUS: /* get accumulated mouse events */ + if (tp != sc_get_mouse_tty()) + return ENOTTY; + s = spltty(); + *(mousestatus_t *)data = mouse_status; + mouse_status.flags = 0; + mouse_status.obutton = mouse_status.button; + mouse_status.dx = 0; + mouse_status.dy = 0; + mouse_status.dz = 0; + splx(s); + return 0; + +#if notyet + case MOUSE_GETVARS: /* get internal mouse variables */ + case MOUSE_SETVARS: /* set internal mouse variables */ + if (tp != sc_get_mouse_tty()) + return ENOTTY; + return ENODEV; +#endif + + case MOUSE_READSTATE: /* read status from the device */ + case MOUSE_READDATA: /* read data from the device */ + if (tp != sc_get_mouse_tty()) + return ENOTTY; + return ENODEV; + } + + return ENOIOCTL; +} + +#endif /* SC_NO_SYSMOUSE */ + +#endif /* NSC */ diff --git a/sys/dev/syscons/scvesactl.c b/sys/dev/syscons/scvesactl.c index b71f071..114c5ec 100644 --- a/sys/dev/syscons/scvesactl.c +++ b/sys/dev/syscons/scvesactl.c @@ -23,7 +23,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: scvesactl.c,v 1.9 1999/01/11 03:18:26 yokota Exp $ + * $Id: scvesactl.c,v 1.10 1999/06/01 18:17:31 jlemon Exp $ */ #include "sc.h" @@ -44,7 +44,6 @@ #include <sys/tty.h> #include <sys/kernel.h> -#include <machine/apm_bios.h> #include <machine/console.h> #include <machine/pc/vesa.h> @@ -71,7 +70,7 @@ vesa_ioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) case SW_TEXT_132x25: case SW_TEXT_132x30: case SW_TEXT_132x43: case SW_TEXT_132x50: case SW_TEXT_132x60: - if (!(scp->adp->va_flags & V_ADP_MODECHANGE)) + if (!(scp->sc->adp->va_flags & V_ADP_MODECHANGE)) return ENODEV; return sc_set_text_mode(scp, tp, cmd & 0xff, 0, 0, 0); @@ -81,7 +80,7 @@ vesa_ioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) case SW_VESA_C132x43: case SW_VESA_C132x50: case SW_VESA_C132x60: - if (!(scp->adp->va_flags & V_ADP_MODECHANGE)) + if (!(scp->sc->adp->va_flags & V_ADP_MODECHANGE)) return ENODEV; mode = (cmd & 0xff) + M_VESA_BASE; return sc_set_text_mode(scp, tp, mode, 0, 0, 0); @@ -107,7 +106,7 @@ vesa_ioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) case SW_VESA_1280x1024: case SW_VESA_CG1280x1024: case SW_VESA_32K_1280: case SW_VESA_64K_1280: case SW_VESA_FULL_1280: - if (!(scp->adp->va_flags & V_ADP_MODECHANGE)) + if (!(scp->sc->adp->va_flags & V_ADP_MODECHANGE)) return ENODEV; mode = (cmd & 0xff) + M_VESA_BASE; return sc_set_graphics_mode(scp, tp, mode); diff --git a/sys/dev/syscons/scvgarndr.c b/sys/dev/syscons/scvgarndr.c new file mode 100644 index 0000000..16c40e2 --- /dev/null +++ b/sys/dev/syscons/scvgarndr.c @@ -0,0 +1,829 @@ +/*- + * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer as + * the first lines of this file unmodified. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Id:$ + */ + +#include "sc.h" +#include "vga.h" +#include "opt_syscons.h" +#include "opt_vga.h" + +#if NSC > 0 && NVGA > 0 + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> + +#include <machine/console.h> +#include <machine/md_var.h> + +#include <dev/fb/fbreg.h> +#include <dev/fb/vgareg.h> +#include <dev/syscons/syscons.h> + +#include <isa/isareg.h> + +#ifndef SC_MOUSE_CHAR +#define SC_MOUSE_CHAR (0xd0) +#endif + +#ifndef SC_RENDER_DEBUG +#define SC_RENDER_DEBUG 0 +#endif + +static vr_clear_t vga_txtclear; +static vr_draw_border_t vga_txtborder; +static vr_draw_t vga_txtdraw; +static vr_set_cursor_t vga_txtcursor_shape; +static vr_draw_cursor_t vga_txtcursor; +static vr_blink_cursor_t vga_txtblink; +#ifndef SC_NO_CUTPASTE +static vr_draw_mouse_t vga_txtmouse; +#else +#define vga_txtmouse (vr_draw_mouse_t *)vga_nop +#endif + +#ifdef SC_PIXEL_MODE +static vr_clear_t vga_pxlclear; +static vr_draw_border_t vga_pxlborder; +static vr_draw_t vga_egadraw; +static vr_draw_t vga_vgadraw; +static vr_set_cursor_t vga_pxlcursor_shape; +static vr_draw_cursor_t vga_pxlcursor; +static vr_blink_cursor_t vga_pxlblink; +#ifndef SC_NO_CUTPASTE +static vr_draw_mouse_t vga_pxlmouse; +#else +#define vga_pxlmouse (vr_draw_mouse_t *)vga_nop +#endif +#endif /* SC_PIXEL_MODE */ + +#ifndef SC_NO_MODE_CHANGE +static vr_draw_border_t vga_grborder; +#endif + +static void vga_nop(scr_stat *scp, ...); + +static sc_rndr_sw_t txtrndrsw = { + vga_txtclear, + vga_txtborder, + vga_txtdraw, + vga_txtcursor_shape, + vga_txtcursor, + vga_txtblink, + (vr_set_mouse_t *)vga_nop, + vga_txtmouse, +}; +RENDERER(mda, 0, txtrndrsw); +RENDERER(cga, 0, txtrndrsw); +RENDERER(ega, 0, txtrndrsw); +RENDERER(vga, 0, txtrndrsw); + +#ifdef SC_PIXEL_MODE +static sc_rndr_sw_t egarndrsw = { + vga_pxlclear, + vga_pxlborder, + vga_egadraw, + vga_pxlcursor_shape, + vga_pxlcursor, + vga_pxlblink, + (vr_set_mouse_t *)vga_nop, + vga_pxlmouse, +}; +RENDERER(ega, PIXEL_MODE, egarndrsw); + +static sc_rndr_sw_t vgarndrsw = { + vga_pxlclear, + vga_pxlborder, + vga_vgadraw, + vga_pxlcursor_shape, + vga_pxlcursor, + vga_pxlblink, + (vr_set_mouse_t *)vga_nop, + vga_pxlmouse, +}; +RENDERER(vga, PIXEL_MODE, vgarndrsw); +#endif /* SC_PIXEL_MODE */ + +#ifndef SC_NO_MODE_CHANGE +static sc_rndr_sw_t grrndrsw = { + (vr_clear_t *)vga_nop, + vga_grborder, + (vr_draw_t *)vga_nop, + (vr_set_cursor_t *)vga_nop, + (vr_draw_cursor_t *)vga_nop, + (vr_blink_cursor_t *)vga_nop, + (vr_set_mouse_t *)vga_nop, + (vr_draw_mouse_t *)vga_nop, +}; +RENDERER(cga, GRAPHICS_MODE, grrndrsw); +RENDERER(ega, GRAPHICS_MODE, grrndrsw); +RENDERER(vga, GRAPHICS_MODE, grrndrsw); +#endif /* SC_NO_MODE_CHANGE */ + +#ifndef SC_NO_CUTPASTE +static u_short mouse_and_mask[16] = { + 0xc000, 0xe000, 0xf000, 0xf800, 0xfc00, 0xfe00, 0xff00, 0xff80, + 0xfe00, 0x1e00, 0x1f00, 0x0f00, 0x0f00, 0x0000, 0x0000, 0x0000 +}; +static u_short mouse_or_mask[16] = { + 0x0000, 0x4000, 0x6000, 0x7000, 0x7800, 0x7c00, 0x7e00, 0x6800, + 0x0c00, 0x0c00, 0x0600, 0x0600, 0x0000, 0x0000, 0x0000, 0x0000 +}; +#endif + +static void +vga_nop(scr_stat *scp, ...) +{ +} + +/* text mode renderer */ + +static void +vga_txtclear(scr_stat *scp, int c, int attr) +{ + sc_vtb_clear(&scp->scr, c, attr); +} + +static void +vga_txtborder(scr_stat *scp, int color) +{ + (*vidsw[scp->sc->adapter]->set_border)(scp->sc->adp, color); +} + +static void +vga_txtdraw(scr_stat *scp, int from, int count, int flip) +{ + vm_offset_t p; + int c; + int a; + + if (from + count > scp->xsize*scp->ysize) + count = scp->xsize*scp->ysize - from; + + if (flip) { + for (p = sc_vtb_pointer(&scp->scr, from); count-- > 0; ++from) { + c = sc_vtb_getc(&scp->vtb, from); + a = sc_vtb_geta(&scp->vtb, from); + a = (a & 0x8800) | ((a & 0x7000) >> 4) + | ((a & 0x0700) << 4); + p = sc_vtb_putchar(&scp->scr, p, c, a); + } + } else { + sc_vtb_copy(&scp->vtb, from, &scp->scr, from, count); + } +} + +static void +vga_txtcursor_shape(scr_stat *scp, int base, int height, int blink) +{ + if (base < 0 || base >= scp->font_size) + return; + /* the caller may set height <= 0 in order to disable the cursor */ +#if 0 + scp->cursor_base = base; + scp->cursor_height = height; +#endif + (*vidsw[scp->sc->adapter]->set_hw_cursor_shape)(scp->sc->adp, + base, height, + scp->font_size, blink); +} + +static void +vga_txtcursor(scr_stat *scp, int at, int blink, int on, int flip) +{ + video_adapter_t *adp; + int cursor_attr; + + if (scp->cursor_height <= 0) /* the text cursor is disabled */ + return; + + adp = scp->sc->adp; + if (blink) { + scp->status |= VR_CURSOR_BLINK; + if (on) { + scp->status |= VR_CURSOR_ON; + (*vidsw[adp->va_index]->set_hw_cursor)(adp, + at%scp->xsize, + at/scp->xsize); + } else { + if (scp->status & VR_CURSOR_ON) + (*vidsw[adp->va_index]->set_hw_cursor)(adp, + -1, -1); + scp->status &= ~VR_CURSOR_ON; + } + } else { + scp->status &= ~VR_CURSOR_BLINK; + if (on) { + scp->status |= VR_CURSOR_ON; + cursor_attr = sc_vtb_geta(&scp->vtb, at); + scp->cursor_saveunder_char = sc_vtb_getc(&scp->scr, at); + scp->cursor_saveunder_attr = cursor_attr; + if ((cursor_attr & 0x7000) == 0x7000) { + cursor_attr &= 0x8f00; + if ((cursor_attr & 0x0700) == 0) + cursor_attr |= 0x0700; + } else { + cursor_attr |= 0x7000; + if ((cursor_attr & 0x0700) == 0x0700) + cursor_attr &= 0xf000; + } + if (flip) + cursor_attr = (cursor_attr & 0x8800) + | ((cursor_attr & 0x7000) >> 4) + | ((cursor_attr & 0x0700) << 4); + sc_vtb_putc(&scp->scr, at, + sc_vtb_getc(&scp->scr, at), + cursor_attr); + } else { + cursor_attr = scp->cursor_saveunder_attr; + if (flip) + cursor_attr = (cursor_attr & 0x8800) + | ((cursor_attr & 0x7000) >> 4) + | ((cursor_attr & 0x0700) << 4); + if (scp->status & VR_CURSOR_ON) + sc_vtb_putc(&scp->scr, at, + scp->cursor_saveunder_char, + cursor_attr); + scp->status &= ~VR_CURSOR_ON; + } + } +} + +static void +vga_txtblink(scr_stat *scp, int at, int flip) +{ +} + +#ifndef SC_NO_CUTPASTE + +static void +draw_txtmouse(scr_stat *scp, int x, int y) +{ +#ifndef SC_ALT_MOUSE_IMAGE + u_char font_buf[128]; + u_short cursor[32]; + int pos; + int xoffset, yoffset; + int crtc_addr; + int i; + + /* prepare mousepointer char's bitmaps */ + pos = (y/scp->font_size - scp->yoff)*scp->xsize + x/8 - scp->xoff; + bcopy(scp->font + sc_vtb_getc(&scp->vtb, pos)*scp->font_size, + &font_buf[0], scp->font_size); + bcopy(scp->font + sc_vtb_getc(&scp->vtb, pos + 1)*scp->font_size, + &font_buf[32], scp->font_size); + bcopy(scp->font + + sc_vtb_getc(&scp->vtb, pos + scp->xsize)*scp->font_size, + &font_buf[64], scp->font_size); + bcopy(scp->font + + sc_vtb_getc(&scp->vtb, pos + scp->xsize + 1)*scp->font_size, + &font_buf[96], scp->font_size); + for (i = 0; i < scp->font_size; ++i) { + cursor[i] = font_buf[i]<<8 | font_buf[i+32]; + cursor[i + scp->font_size] = font_buf[i+64]<<8 | font_buf[i+96]; + } + + /* now and-or in the mousepointer image */ + xoffset = x%8; + yoffset = y%scp->font_size; + for (i = 0; i < 16; ++i) { + cursor[i + yoffset] = + (cursor[i + yoffset] & ~(mouse_and_mask[i] >> xoffset)) + | (mouse_or_mask[i] >> xoffset); + } + for (i = 0; i < scp->font_size; ++i) { + font_buf[i] = (cursor[i] & 0xff00) >> 8; + font_buf[i + 32] = cursor[i] & 0xff; + font_buf[i + 64] = (cursor[i + scp->font_size] & 0xff00) >> 8; + font_buf[i + 96] = cursor[i + scp->font_size] & 0xff; + } + +#if 1 + /* wait for vertical retrace to avoid jitter on some videocards */ + crtc_addr = scp->sc->adp->va_crtc_addr; + while (!(inb(crtc_addr + 6) & 0x08)) /* idle */ ; +#endif + (*vidsw[scp->sc->adapter]->load_font)(scp->sc->adp, 0, 32, font_buf, + SC_MOUSE_CHAR, 4); + + sc_vtb_putc(&scp->scr, pos, SC_MOUSE_CHAR, sc_vtb_geta(&scp->scr, pos)); + /* FIXME: may be out of range! */ + sc_vtb_putc(&scp->scr, pos + scp->xsize, SC_MOUSE_CHAR + 2, + sc_vtb_geta(&scp->scr, pos + scp->xsize)); + if (x < (scp->xsize - 1)*8) { + sc_vtb_putc(&scp->scr, pos + 1, SC_MOUSE_CHAR + 1, + sc_vtb_geta(&scp->scr, pos + 1)); + sc_vtb_putc(&scp->scr, pos + scp->xsize + 1, SC_MOUSE_CHAR + 3, + sc_vtb_geta(&scp->scr, pos + scp->xsize + 1)); + } +#else /* SC_ALT_MOUSE_IMAGE */ + /* Red, magenta and brown are mapped to green to to keep it readable */ + static const int col_conv[16] = { + 6, 6, 6, 6, 2, 2, 2, 6, 14, 14, 14, 14, 10, 10, 10, 14 + }; + int pos; + int color; + int a; + + pos = (y/scp->font_size - scp->yoff)*scp->xsize + x/8 - scp->xoff; + a = sc_vtb_geta(&scp->scr, pos); + if (scp->sc->adp->va_flags & V_ADP_COLOR) + color = (col_conv[(a & 0xf000) >> 12] << 12) + | ((a & 0x0f00) | 0x0800); + else + color = ((a & 0xf000) >> 4) | ((a & 0x0f00) << 4); + sc_vtb_putc(&scp->scr, pos, sc_vtb_getc(&scp->scr, pos), color); +#endif /* SC_ALT_MOUSE_IMAGE */ +} + +static void +remove_txtmouse(scr_stat *scp, int x, int y) +{ +} + +static void +vga_txtmouse(scr_stat *scp, int x, int y, int on) +{ + if (on) + draw_txtmouse(scp, x, y); + else + remove_txtmouse(scp, x, y); +} + +#endif /* SC_NO_CUTPASTE */ + +#ifdef SC_PIXEL_MODE + +/* pixel (raster text) mode renderer */ + +static void +vga_pxlclear(scr_stat *scp, int c, int attr) +{ + vm_offset_t p; + int line_width; + int lines; + int i; + + /* XXX: we are just filling the screen with the background color... */ + outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */ + outw(GDCIDX, 0x0003); /* data rotate/function select */ + outw(GDCIDX, 0x0f01); /* set/reset enable */ + outw(GDCIDX, 0xff08); /* bit mask */ + outw(GDCIDX, ((attr & 0xf000) >> 4) | 0x00); /* set/reset */ + line_width = scp->sc->adp->va_line_width; + lines = scp->ysize*scp->font_size; + p = scp->sc->adp->va_window + line_width*scp->yoff*scp->font_size + + scp->xoff; + for (i = 0; i < lines; ++i) { + bzero_io((void *)p, scp->xsize); + p += line_width; + } + outw(GDCIDX, 0x0000); /* set/reset */ + outw(GDCIDX, 0x0001); /* set/reset enable */ +} + +static void +vga_pxlborder(scr_stat *scp, int color) +{ + vm_offset_t p; + int line_width; + int i; + + (*vidsw[scp->sc->adapter]->set_border)(scp->sc->adp, color); + + outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */ + outw(GDCIDX, 0x0003); /* data rotate/function select */ + outw(GDCIDX, 0x0f01); /* set/reset enable */ + outw(GDCIDX, 0xff08); /* bit mask */ + outw(GDCIDX, (color << 8) | 0x00); /* set/reset */ + line_width = scp->sc->adp->va_line_width; + p = scp->sc->adp->va_window; + if (scp->yoff > 0) { + bzero_io((void *)p, line_width*scp->yoff*scp->font_size); + bzero_io((void *)(p + line_width*(scp->yoff + scp->ysize) + *scp->font_size), + line_width*(scp->ypixel + - (scp->yoff + scp->ysize)*scp->font_size)); + } + if (scp->xoff > 0) { + for (i = 0; i < scp->ysize*scp->font_size; ++i) { + bzero_io((void *)(p + line_width + *(scp->yoff*scp->font_size + i)), + scp->xoff); + bzero_io((void *)(p + line_width + *(scp->yoff*scp->font_size + i) + + scp->xoff + scp->xsize), + scp->xpixel/8 - scp->xoff - scp->xsize); + } + } + outw(GDCIDX, 0x0000); /* set/reset */ + outw(GDCIDX, 0x0001); /* set/reset enable */ +} + +static void +vga_egadraw(scr_stat *scp, int from, int count, int flip) +{ + vm_offset_t d; + vm_offset_t e; + u_char *f; + u_short bg; + u_short col1, col2; + int line_width; + int i, j; + int a; + u_char c; + + line_width = scp->sc->adp->va_line_width; + d = scp->sc->adp->va_window + + scp->xoff + + scp->yoff*scp->font_size*line_width + + (from%scp->xsize) + + scp->font_size*line_width*(from/scp->xsize); + + outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */ + outw(GDCIDX, 0x0003); /* data rotate/function select */ + outw(GDCIDX, 0x0f01); /* set/reset enable */ + bg = -1; + if (from + count > scp->xsize*scp->ysize) + count = scp->xsize*scp->ysize - from; + for (i = from; count-- > 0; ++i) { + a = sc_vtb_geta(&scp->vtb, i); + if (flip) { + col1 = ((a & 0x7000) >> 4) | (a & 0x0800); + col2 = ((a & 0x8000) >> 4) | (a & 0x0700); + } else { + col1 = (a & 0x0f00); + col2 = (a & 0xf000) >> 4; + } + /* set background color in EGA/VGA latch */ + if (bg != col2) { + bg = col2; + outw(GDCIDX, bg | 0x00); /* set/reset */ + outw(GDCIDX, 0xff08); /* bit mask */ + writeb(d, 0); + c = readb(d); /* set bg color in the latch */ + } + /* foreground color */ + outw(GDCIDX, col1 | 0x00); /* set/reset */ + e = d; + f = &(scp->font[sc_vtb_getc(&scp->vtb, i)*scp->font_size]); + for (j = 0; j < scp->font_size; ++j, ++f) { + outw(GDCIDX, (*f << 8) | 0x08); /* bit mask */ + writeb(e, 0); + e += line_width; + } + ++d; + if ((i % scp->xsize) == scp->xsize - 1) + d += scp->xoff*2 + + (scp->font_size - 1)*line_width; + } + outw(GDCIDX, 0x0000); /* set/reset */ + outw(GDCIDX, 0x0001); /* set/reset enable */ + outw(GDCIDX, 0xff08); /* bit mask */ +} + +static void +vga_vgadraw(scr_stat *scp, int from, int count, int flip) +{ + vm_offset_t d; + vm_offset_t e; + u_char *f; + u_short bg; + u_short col1, col2; + int line_width; + int i, j; + int a; + u_char c; + + line_width = scp->sc->adp->va_line_width; + d = scp->sc->adp->va_window + + scp->xoff + + scp->yoff*scp->font_size*line_width + + (from%scp->xsize) + + scp->font_size*line_width*(from/scp->xsize); + + outw(GDCIDX, 0x0305); /* read mode 0, write mode 3 */ + outw(GDCIDX, 0x0003); /* data rotate/function select */ + outw(GDCIDX, 0x0f01); /* set/reset enable */ + outw(GDCIDX, 0xff08); /* bit mask */ + bg = -1; + if (from + count > scp->xsize*scp->ysize) + count = scp->xsize*scp->ysize - from; + for (i = from; count-- > 0; ++i) { + a = sc_vtb_geta(&scp->vtb, i); + if (flip) { + col1 = ((a & 0x7000) >> 4) | (a & 0x0800); + col2 = ((a & 0x8000) >> 4) | (a & 0x0700); + } else { + col1 = (a & 0x0f00); + col2 = (a & 0xf000) >> 4; + } + /* set background color in EGA/VGA latch */ + if (bg != col2) { + bg = col2; + outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */ + outw(GDCIDX, bg | 0x00); /* set/reset */ + writeb(d, 0); + c = readb(d); /* set bg color in the latch */ + outw(GDCIDX, 0x0305); /* read mode 0, write mode 3 */ + } + /* foreground color */ + outw(GDCIDX, col1 | 0x00); /* set/reset */ + e = d; + f = &(scp->font[sc_vtb_getc(&scp->vtb, i)*scp->font_size]); + for (j = 0; j < scp->font_size; ++j, ++f) { + writeb(e, *f); + e += line_width; + } + ++d; + if ((i % scp->xsize) == scp->xsize - 1) + d += scp->xoff*2 + + (scp->font_size - 1)*line_width; + } + outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */ + outw(GDCIDX, 0x0000); /* set/reset */ + outw(GDCIDX, 0x0001); /* set/reset enable */ +} + +static void +vga_pxlcursor_shape(scr_stat *scp, int base, int height, int blink) +{ + if (base < 0 || base >= scp->font_size) + return; + /* the caller may set height <= 0 in order to disable the cursor */ +#if 0 + scp->cursor_base = base; + scp->cursor_height = height; +#endif +} + +static void +draw_pxlcursor(scr_stat *scp, int at, int on, int flip) +{ + vm_offset_t d; + u_char *f; + int line_width; + int height; + int col; + int a; + int i; + u_char c; + + line_width = scp->sc->adp->va_line_width; + d = scp->sc->adp->va_window + + scp->xoff + + scp->yoff*scp->font_size*line_width + + (at%scp->xsize) + + scp->font_size*line_width*(at/scp->xsize) + + (scp->font_size - scp->cursor_base - 1)*line_width; + + outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */ + outw(GDCIDX, 0x0003); /* data rotate/function select */ + outw(GDCIDX, 0x0f01); /* set/reset enable */ + /* set background color in EGA/VGA latch */ + a = sc_vtb_geta(&scp->vtb, at); + if (flip) + col = (on) ? ((a & 0xf000) >> 4) : (a & 0x0f00); + else + col = (on) ? (a & 0x0f00) : ((a & 0xf000) >> 4); + outw(GDCIDX, col | 0x00); /* set/reset */ + outw(GDCIDX, 0xff08); /* bit mask */ + writeb(d, 0); + c = readb(d); /* set bg color in the latch */ + /* foreground color */ + if (flip) + col = (on) ? (a & 0x0f00) : ((a & 0xf000) >> 4); + else + col = (on) ? ((a & 0xf000) >> 4) : (a & 0x0f00); + outw(GDCIDX, col | 0x00); /* set/reset */ + f = &(scp->font[sc_vtb_getc(&scp->vtb, at)*scp->font_size + + scp->font_size - scp->cursor_base - 1]); + height = imin(scp->cursor_height, scp->font_size); + for (i = 0; i < height; ++i, --f) { + outw(GDCIDX, (*f << 8) | 0x08); /* bit mask */ + writeb(d, 0); + d -= line_width; + } + outw(GDCIDX, 0x0000); /* set/reset */ + outw(GDCIDX, 0x0001); /* set/reset enable */ + outw(GDCIDX, 0xff08); /* bit mask */ +} + +static void +vga_pxlcursor(scr_stat *scp, int at, int blink, int on, int flip) +{ + if (scp->cursor_height <= 0) /* the text cursor is disabled */ + return; + + if (on) { + scp->status |= VR_CURSOR_ON; + draw_pxlcursor(scp, at, on, flip); + } else { + if (scp->status & VR_CURSOR_ON) + draw_pxlcursor(scp, at, on, flip); + scp->status &= ~VR_CURSOR_ON; + } + if (blink) + scp->status |= VR_CURSOR_BLINK; + else + scp->status &= ~VR_CURSOR_BLINK; +} + +static void +vga_pxlblink(scr_stat *scp, int at, int flip) +{ + static int blinkrate = 0; + + if (!(scp->status & VR_CURSOR_BLINK)) + return; + if (!(++blinkrate & 4)) + return; + blinkrate = 0; + scp->status ^= VR_CURSOR_ON; + draw_pxlcursor(scp, at, scp->status & VR_CURSOR_ON, flip); +} + +#ifndef SC_NO_CUTPASTE + +static void +draw_pxlmouse(scr_stat *scp, int x, int y) +{ + vm_offset_t p; + int line_width; + int xoff, yoff; + int ymax; + u_short m; + int i, j; + + line_width = scp->sc->adp->va_line_width; + xoff = (x - scp->xoff*8)%8; + yoff = y - (y/line_width)*line_width; + ymax = imin(y + 16, scp->ypixel); + + outw(GDCIDX, 0x0805); /* read mode 1, write mode 0 */ + outw(GDCIDX, 0x0001); /* set/reset enable */ + outw(GDCIDX, 0x0002); /* color compare */ + outw(GDCIDX, 0x0007); /* color don't care */ + outw(GDCIDX, 0xff08); /* bit mask */ + outw(GDCIDX, 0x0803); /* data rotate/function select (and) */ + p = scp->sc->adp->va_window + line_width*y + x/8; + if (x < scp->xpixel - 16) { + for (i = y, j = 0; i < ymax; ++i, ++j) { + m = ~(mouse_and_mask[j] >> xoff); +#ifdef __i386__ + *(u_char *)p &= m >> 8; + *(u_char *)(p + 1) &= m; +#elif defined(__alpha__) + writeb(p, readb(p) & (m >> 8)); + writeb(p + 1, readb(p + 1) & (m >> 8)); +#endif + p += line_width; + } + } else { + xoff += 8; + for (i = y, j = 0; i < ymax; ++i, ++j) { + m = ~(mouse_and_mask[j] >> xoff); +#ifdef __i386__ + *(u_char *)p &= m; +#elif defined(__alpha__) + writeb(p, readb(p) & (m >> 8)); +#endif + p += line_width; + } + } + outw(GDCIDX, 0x1003); /* data rotate/function select (or) */ + p = scp->sc->adp->va_window + line_width*y + x/8; + if (x < scp->xpixel - 16) { + for (i = y, j = 0; i < ymax; ++i, ++j) { + m = mouse_or_mask[j] >> xoff; +#ifdef __i386__ + *(u_char *)p &= m >> 8; + *(u_char *)(p + 1) &= m; +#elif defined(__alpha__) + writeb(p, readb(p) & (m >> 8)); + writeb(p + 1, readb(p + 1) & (m >> 8)); +#endif + p += line_width; + } + } else { + for (i = y, j = 0; i < ymax; ++i, ++j) { + m = mouse_or_mask[j] >> xoff; +#ifdef __i386__ + *(u_char *)p &= m; +#elif defined(__alpha__) + writeb(p, readb(p) & (m >> 8)); +#endif + p += line_width; + } + } + outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */ + outw(GDCIDX, 0x0003); /* data rotate/function select */ +} + +static void +remove_pxlmouse(scr_stat *scp, int x, int y) +{ + vm_offset_t p; + int col, row; + int pos; + int line_width; + int ymax; + int i; + + /* erase the mouse cursor image */ + col = x/8 - scp->xoff; + row = y/scp->font_size - scp->yoff; + pos = row*scp->xsize + col; + i = (col < scp->xsize - 1) ? 2 : 1; + (*scp->rndr->draw)(scp, pos, i, FALSE); + if (row < scp->ysize - 1) + (*scp->rndr->draw)(scp, pos + scp->xsize, i, FALSE); + + /* paint border if necessary */ + line_width = scp->sc->adp->va_line_width; + outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */ + outw(GDCIDX, 0x0003); /* data rotate/function select */ + outw(GDCIDX, 0x0f01); /* set/reset enable */ + outw(GDCIDX, 0xff08); /* bit mask */ + outw(GDCIDX, (scp->border << 8) | 0x00); /* set/reset */ + if (row == scp->ysize - 1) { + i = (scp->ysize + scp->yoff)*scp->font_size; + ymax = imin(i + scp->font_size, scp->ypixel); + p = scp->sc->adp->va_window + i*line_width + scp->xoff + col; + if (col < scp->xsize - 1) { + for (; i < ymax; ++i) { + writeb(p, 0); + writeb(p + 1, 0); + p += line_width; + } + } else { + for (; i < ymax; ++i) { + writeb(p, 0); + p += line_width; + } + } + } + if ((col == scp->xsize - 1) && (scp->xoff > 0)) { + i = (row + scp->yoff)*scp->font_size; + ymax = imin(i + scp->font_size*2, scp->ypixel); + p = scp->sc->adp->va_window + i*line_width + + scp->xoff + scp->xsize; + for (; i < ymax; ++i) { + writeb(p, 0); + p += line_width; + } + } + outw(GDCIDX, 0x0000); /* set/reset */ + outw(GDCIDX, 0x0001); /* set/reset enable */ +} + +static void +vga_pxlmouse(scr_stat *scp, int x, int y, int on) +{ + if (on) + draw_pxlmouse(scp, x, y); + else + remove_pxlmouse(scp, x, y); +} + +#endif /* SC_NO_CUTPASTE */ +#endif /* SC_PIXEL_MODE */ + +#ifndef SC_NO_MODE_CHANGE + +/* graphics mode renderer */ + +static void +vga_grborder(scr_stat *scp, int color) +{ + (*vidsw[scp->sc->adapter]->set_border)(scp->sc->adp, color); +} + +#endif + +#endif /* NSC > 0 && NVGA > 0 */ diff --git a/sys/dev/syscons/scvidctl.c b/sys/dev/syscons/scvidctl.c index 732f386c..f84b14d 100644 --- a/sys/dev/syscons/scvidctl.c +++ b/sys/dev/syscons/scvidctl.c @@ -23,7 +23,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: scvidctl.c,v 1.7 1999/01/19 11:31:16 yokota Exp $ + * $Id: $ */ #include "sc.h" @@ -37,19 +37,21 @@ #include <sys/tty.h> #include <sys/kernel.h> -#ifdef __i386__ -#include <machine/apm_bios.h> -#endif +#include <vm/vm.h> +#include <vm/pmap.h> + #include <machine/console.h> #include <dev/fb/fbreg.h> #include <dev/syscons/syscons.h> /* for compatibility with previous versions */ +/* 3.0-RELEASE used the following structure */ typedef struct old_video_adapter { int va_index; int va_type; int va_flags; +/* flag bits are the same as the -CURRENT #define V_ADP_COLOR (1<<0) #define V_ADP_MODECHANGE (1<<1) #define V_ADP_STATESAVE (1<<2) @@ -58,6 +60,7 @@ typedef struct old_video_adapter { #define V_ADP_PALETTE (1<<5) #define V_ADP_BORDER (1<<6) #define V_ADP_VESA (1<<7) +*/ int va_crtc_addr; u_int va_window; /* virtual address */ size_t va_window_size; @@ -71,39 +74,100 @@ typedef struct old_video_adapter { #define OLD_CONS_ADPINFO _IOWR('c', 101, old_video_adapter_t) -/* variables */ -extern scr_stat *cur_console; -extern int fonts_loaded; -extern int sc_history_size; -extern u_char palette[]; +/* 3.1-RELEASE used the following structure */ +typedef struct old_video_adapter_info { + int va_index; + int va_type; + char va_name[16]; + int va_unit; + int va_flags; + int va_io_base; + int va_io_size; + int va_crtc_addr; + int va_mem_base; + int va_mem_size; + u_int va_window; /* virtual address */ + size_t va_window_size; + size_t va_window_gran; + u_int va_buffer;; + size_t va_buffer_size; + int va_initial_mode; + int va_initial_bios_mode; + int va_mode; + int va_line_width; +} old_video_adapter_info_t; + +#define OLD_CONS_ADPINFO2 _IOWR('c', 101, old_video_adapter_info_t) + +/* 3.0-RELEASE and 3.1-RELEASE used the following structure */ +typedef struct old_video_info { + int vi_mode; + int vi_flags; +/* flag bits are the same as the -CURRENT +#define V_INFO_COLOR (1<<0) +#define V_INFO_GRAPHICS (1<<1) +#define V_INFO_LINEAR (1<<2) +#define V_INFO_VESA (1<<3) +*/ + int vi_width; + int vi_height; + int vi_cwidth; + int vi_cheight; + int vi_depth; + int vi_planes; + u_int vi_window; /* physical address */ + size_t vi_window_size; + size_t vi_window_gran; + u_int vi_buffer; /* physical address */ + size_t vi_buffer_size; +} old_video_info_t; + +#define OLD_CONS_MODEINFO _IOWR('c', 102, old_video_info_t) +#define OLD_CONS_FINDMODE _IOWR('c', 103, old_video_info_t) int sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, int xsize, int ysize, int fontsize) { video_info_t info; + sc_rndr_sw_t *rndr; + u_char *font; int error; int s; - int i; - if ((*vidsw[scp->ad]->get_info)(scp->adp, mode, &info)) + if ((*vidsw[scp->sc->adapter]->get_info)(scp->sc->adp, mode, &info)) return ENODEV; - + /* adjust argument values */ if (fontsize <= 0) fontsize = info.vi_cheight; if (fontsize < 14) { fontsize = 8; - if (!(fonts_loaded & FONT_8)) +#ifndef SC_NO_FONT_LOADING + if (!(scp->sc->fonts_loaded & FONT_8)) return EINVAL; + font = scp->sc->font_8; +#else + font = NULL; +#endif } else if (fontsize >= 16) { fontsize = 16; - if (!(fonts_loaded & FONT_16)) +#ifndef SC_NO_FONT_LOADING + if (!(scp->sc->fonts_loaded & FONT_16)) return EINVAL; + font = scp->sc->font_16; +#else + font = NULL; +#endif } else { fontsize = 14; - if (!(fonts_loaded & FONT_14)) +#ifndef SC_NO_FONT_LOADING + if (!(scp->sc->fonts_loaded & FONT_14)) return EINVAL; + font = scp->sc->font_14; +#else + font = NULL; +#endif } if ((xsize <= 0) || (xsize > info.vi_width)) xsize = info.vi_width; @@ -117,12 +181,13 @@ sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, int xsize, int ysize, return error; } + rndr = sc_render_match(scp, scp->sc->adp, 0); + if (rndr == NULL) { + splx(s); + return ENODEV; + } + /* set up scp */ - if (scp->history != NULL) - i = imax(scp->history_size / scp->xsize - - imax(sc_history_size, scp->ysize), 0); - else - i = 0; /* * This is a kludge to fend off scrn_update() while we * muck around with scp. XXX @@ -130,22 +195,27 @@ sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, int xsize, int ysize, scp->status |= UNKNOWN_MODE; scp->status &= ~(GRAPHICS_MODE | PIXEL_MODE); scp->mode = mode; - scp->font_size = fontsize; scp->xsize = xsize; scp->ysize = ysize; scp->xoff = 0; scp->yoff = 0; scp->xpixel = scp->xsize*8; scp->ypixel = scp->ysize*fontsize; + scp->font = font; + scp->font_size = fontsize; /* allocate buffers */ sc_alloc_scr_buffer(scp, TRUE, TRUE); - if (ISMOUSEAVAIL(scp->adp->va_flags)) - sc_alloc_cut_buffer(scp, FALSE); - sc_alloc_history_buffer(scp, sc_history_size, i, FALSE); +#ifndef SC_NO_CUTPASTE + sc_alloc_cut_buffer(scp, FALSE); +#endif +#ifndef SC_NO_HISTORY + sc_alloc_history_buffer(scp, 0, FALSE); +#endif + scp->rndr = rndr; splx(s); - if (scp == cur_console) + if (scp == scp->sc->cur_scp) set_mode(scp); scp->status &= ~UNKNOWN_MODE; @@ -164,11 +234,15 @@ sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, int xsize, int ysize, int sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode) { +#ifdef SC_NO_MODE_CHANGE + return ENODEV; +#else video_info_t info; + sc_rndr_sw_t *rndr; int error; int s; - if ((*vidsw[scp->ad]->get_info)(scp->adp, mode, &info)) + if ((*vidsw[scp->sc->adapter]->get_info)(scp->sc->adp, mode, &info)) return ENODEV; /* stop screen saver, etc */ @@ -178,22 +252,32 @@ sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode) return error; } + rndr = sc_render_match(scp, scp->sc->adp, GRAPHICS_MODE); + if (rndr == NULL) { + splx(s); + return ENODEV; + } + /* set up scp */ scp->status |= (UNKNOWN_MODE | GRAPHICS_MODE); scp->status &= ~PIXEL_MODE; scp->mode = mode; + scp->xsize = info.vi_width/8; + scp->ysize = info.vi_height/info.vi_cheight; scp->xoff = 0; scp->yoff = 0; scp->xpixel = info.vi_width; scp->ypixel = info.vi_height; - scp->xsize = info.vi_width/8; - scp->ysize = info.vi_height/info.vi_cheight; + scp->font = NULL; scp->font_size = FONT_NONE; +#ifndef SC_NO_SYSMOUSE /* move the mouse cursor at the center of the screen */ - sc_move_mouse(scp, scp->xpixel / 2, scp->ypixel / 2); + sc_mouse_move(scp, scp->xpixel / 2, scp->ypixel / 2); +#endif + scp->rndr = rndr; splx(s); - if (scp == cur_console) + if (scp == scp->sc->cur_scp) set_mode(scp); /* clear_graphics();*/ scp->status &= ~UNKNOWN_MODE; @@ -208,18 +292,23 @@ sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode) } return 0; +#endif /* SC_NO_MODE_CHANGE */ } int sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize, int fontsize) { +#ifndef SC_PIXEL_MODE + return ENODEV; +#else video_info_t info; + sc_rndr_sw_t *rndr; + u_char *font; int error; int s; - int i; - if ((*vidsw[scp->ad]->get_info)(scp->adp, scp->mode, &info)) + if ((*vidsw[scp->sc->adapter]->get_info)(scp->sc->adp, scp->mode, &info)) return ENODEV; /* this shouldn't happen */ #ifdef SC_VIDEO_DEBUG @@ -234,16 +323,31 @@ sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize, fontsize = info.vi_cheight; if (fontsize < 14) { fontsize = 8; - if (!(fonts_loaded & FONT_8)) +#ifndef SC_NO_FONT_LOADING + if (!(scp->sc->fonts_loaded & FONT_8)) return EINVAL; + font = scp->sc->font_8; +#else + font = NULL; +#endif } else if (fontsize >= 16) { fontsize = 16; - if (!(fonts_loaded & FONT_16)) +#ifndef SC_NO_FONT_LOADING + if (!(scp->sc->fonts_loaded & FONT_16)) return EINVAL; + font = scp->sc->font_16; +#else + font = NULL; +#endif } else { fontsize = 14; - if (!(fonts_loaded & FONT_14)) +#ifndef SC_NO_FONT_LOADING + if (!(scp->sc->fonts_loaded & FONT_14)) return EINVAL; + font = scp->sc->font_14; +#else + font = NULL; +#endif } if (xsize <= 0) xsize = info.vi_width/8; @@ -254,8 +358,8 @@ sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize, if (scp->scr_buf != NULL) { printf("set_pixel_mode(): mode:%x, col:%d, row:%d, font:%d\n", scp->mode, xsize, ysize, fontsize); - printf("set_pixel_mode(): window:%x, %dx%d, xoff:%d, yoff:%d\n", - scp->adp->va_window, info.vi_width, info.vi_height, + printf("set_pixel_mode(): window:%p, %dx%d, xoff:%d, yoff:%d\n", + (void *)scp->sc->adp->va_window, info.vi_width, info.vi_height, (info.vi_width/8 - xsize)/2, (info.vi_height/fontsize - ysize)/2); } @@ -283,29 +387,37 @@ sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize, return error; } + rndr = sc_render_match(scp, scp->sc->adp, PIXEL_MODE); + if (rndr == NULL) { + splx(s); + return ENODEV; + } + /* set up scp */ - if (scp->history != NULL) - i = imax(scp->history_size / scp->xsize - - imax(sc_history_size, scp->ysize), 0); - else - i = 0; scp->status |= (UNKNOWN_MODE | PIXEL_MODE); - scp->status &= ~(GRAPHICS_MODE | MOUSE_ENABLED); + scp->status &= ~GRAPHICS_MODE; scp->xsize = xsize; scp->ysize = ysize; - scp->font_size = fontsize; scp->xoff = (scp->xpixel/8 - xsize)/2; scp->yoff = (scp->ypixel/fontsize - ysize)/2; + scp->font = font; + scp->font_size = fontsize; /* allocate buffers */ sc_alloc_scr_buffer(scp, TRUE, TRUE); - if (ISMOUSEAVAIL(scp->adp->va_flags)) - sc_alloc_cut_buffer(scp, FALSE); - sc_alloc_history_buffer(scp, sc_history_size, i, FALSE); +#ifndef SC_NO_CUTPASTE + sc_alloc_cut_buffer(scp, FALSE); +#endif +#ifndef SC_NO_HISTORY + sc_alloc_history_buffer(scp, 0, FALSE); +#endif + scp->rndr = rndr; splx(s); - if (scp == cur_console) + if (scp == scp->sc->cur_scp) { set_border(scp, scp->border); + sc_set_cursor_image(scp); + } scp->status &= ~UNKNOWN_MODE; @@ -323,99 +435,182 @@ sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize, } return 0; +#endif /* SC_PIXEL_MODE */ +} + +sc_rndr_sw_t +*sc_render_match(scr_stat *scp, video_adapter_t *adp, int mode) +{ + const sc_renderer_t **list; + const sc_renderer_t *p; + + list = (const sc_renderer_t **)scrndr_set.ls_items; + while ((p = *list++) != NULL) { + if ((strcmp(p->name, adp->va_name) == 0) + && (mode == p->mode)) { + scp->status &= ~(VR_CURSOR_ON | VR_CURSOR_BLINK); + return p->rndrsw; + } + } + + return NULL; } +#define fb_ioctl(a, c, d) \ + (((a) == NULL) ? ENODEV : \ + (*vidsw[(a)->va_index]->ioctl)((a), (c), (caddr_t)(d))) + int sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p) { scr_stat *scp; + video_adapter_t *adp; + video_info_t info; + video_adapter_info_t adp_info; int error; int s; scp = sc_get_scr_stat(tp->t_dev); + if (scp == NULL) /* tp == SC_MOUSE */ + return ENOIOCTL; + adp = scp->sc->adp; + if (adp == NULL) /* shouldn't happen??? */ + return ENODEV; switch (cmd) { - case CONS_CURRENT: /* get current adapter type */ - if (scp->adp == NULL) - return ENODEV; - *(int *)data = scp->adp->va_type; - return 0; - case CONS_CURRENTADP: /* get current adapter index */ - *(int *)data = scp->ad; - return 0; + case FBIO_ADAPTER: + return fb_ioctl(adp, FBIO_ADAPTER, data); - case OLD_CONS_ADPINFO: /* adapter information */ - if (scp->adp == NULL) - return ENODEV; - ((old_video_adapter_t *)data)->va_index = scp->adp->va_index; - ((old_video_adapter_t *)data)->va_type = scp->adp->va_type; - ((old_video_adapter_t *)data)->va_flags = scp->adp->va_flags; - ((old_video_adapter_t *)data)->va_crtc_addr = scp->adp->va_crtc_addr; - ((old_video_adapter_t *)data)->va_window = scp->adp->va_window; - ((old_video_adapter_t *)data)->va_window_size - = scp->adp->va_window_size; - ((old_video_adapter_t *)data)->va_window_gran - = scp->adp->va_window_gran; - ((old_video_adapter_t *)data)->va_buffer = scp->adp->va_buffer; - ((old_video_adapter_t *)data)->va_buffer_size - = scp->adp->va_buffer_size; - ((old_video_adapter_t *)data)->va_mode = scp->adp->va_mode; - ((old_video_adapter_t *)data)->va_initial_mode - = scp->adp->va_initial_mode; + case CONS_CURRENT: /* get current adapter type */ + case FBIO_ADPTYPE: + return fb_ioctl(adp, FBIO_ADPTYPE, data); + + case OLD_CONS_ADPINFO: /* adapter information (old interface) */ + if (((old_video_adapter_t *)data)->va_index >= 0) { + adp = vid_get_adapter(((old_video_adapter_t *)data)->va_index); + if (adp == NULL) + return ENODEV; + } + ((old_video_adapter_t *)data)->va_index = adp->va_index; + ((old_video_adapter_t *)data)->va_type = adp->va_type; + ((old_video_adapter_t *)data)->va_flags = adp->va_flags; + ((old_video_adapter_t *)data)->va_crtc_addr = adp->va_crtc_addr; + ((old_video_adapter_t *)data)->va_window = adp->va_window; + ((old_video_adapter_t *)data)->va_window_size = adp->va_window_size; + ((old_video_adapter_t *)data)->va_window_gran = adp->va_window_gran; + ((old_video_adapter_t *)data)->va_buffer = adp->va_buffer; + ((old_video_adapter_t *)data)->va_buffer_size = adp->va_buffer_size; + ((old_video_adapter_t *)data)->va_mode = adp->va_mode; + ((old_video_adapter_t *)data)->va_initial_mode = adp->va_initial_mode; ((old_video_adapter_t *)data)->va_initial_bios_mode - = scp->adp->va_initial_bios_mode; + = adp->va_initial_bios_mode; return 0; + case OLD_CONS_ADPINFO2: /* adapter information (yet another old I/F) */ + adp_info.va_index = ((old_video_adapter_info_t *)data)->va_index; + if (adp_info.va_index >= 0) { + adp = vid_get_adapter(adp_info.va_index); + if (adp == NULL) + return ENODEV; + } + error = fb_ioctl(adp, FBIO_ADPINFO, &adp_info); + if (error == 0) + bcopy(&adp_info, data, sizeof(old_video_adapter_info_t)); + return error; + case CONS_ADPINFO: /* adapter information */ - if (scp->adp == NULL) - return ENODEV; - ((video_adapter_info_t *)data)->va_index = scp->adp->va_index; - ((video_adapter_info_t *)data)->va_type = scp->adp->va_type; - bcopy(scp->adp->va_name, ((video_adapter_info_t *)data)->va_name, - imin(strlen(scp->adp->va_name) + 1, - sizeof(((video_adapter_info_t *)data)->va_name))); - ((video_adapter_info_t *)data)->va_unit = scp->adp->va_unit; - ((video_adapter_info_t *)data)->va_flags = scp->adp->va_flags; - ((video_adapter_info_t *)data)->va_io_base = scp->adp->va_io_base; - ((video_adapter_info_t *)data)->va_io_size = scp->adp->va_io_size; - ((video_adapter_info_t *)data)->va_crtc_addr = scp->adp->va_crtc_addr; - ((video_adapter_info_t *)data)->va_mem_base = scp->adp->va_mem_base; - ((video_adapter_info_t *)data)->va_mem_size = scp->adp->va_mem_size; - ((video_adapter_info_t *)data)->va_window = scp->adp->va_window; - ((video_adapter_info_t *)data)->va_window_size - = scp->adp->va_window_size; - ((video_adapter_info_t *)data)->va_window_gran - = scp->adp->va_window_gran; - ((video_adapter_info_t *)data)->va_buffer = scp->adp->va_buffer; - ((video_adapter_info_t *)data)->va_buffer_size - = scp->adp->va_buffer_size; - ((video_adapter_info_t *)data)->va_mode = scp->adp->va_mode; - ((video_adapter_info_t *)data)->va_initial_mode - = scp->adp->va_initial_mode; - ((video_adapter_info_t *)data)->va_initial_bios_mode - = scp->adp->va_initial_bios_mode; - ((video_adapter_info_t *)data)->va_line_width = scp->adp->va_line_width; - return 0; + case FBIO_ADPINFO: + if (((video_adapter_info_t *)data)->va_index >= 0) { + adp = vid_get_adapter(((video_adapter_info_t *)data)->va_index); + if (adp == NULL) + return ENODEV; + } + return fb_ioctl(adp, FBIO_ADPINFO, data); case CONS_GET: /* get current video mode */ + case FBIO_GETMODE: *(int *)data = scp->mode; return 0; +#ifndef SC_NO_MODE_CHANGE + case FBIO_SETMODE: /* set video mode */ + if (!(adp->va_flags & V_ADP_MODECHANGE)) + return ENODEV; + info.vi_mode = *(int *)data; + error = fb_ioctl(adp, FBIO_MODEINFO, &info); + if (error) + return error; + if (info.vi_flags & V_INFO_GRAPHICS) + return sc_set_graphics_mode(scp, tp, *(int *)data); + else + return sc_set_text_mode(scp, tp, *(int *)data, 0, 0, 0); +#endif /* SC_NO_MODE_CHANGE */ + + case OLD_CONS_MODEINFO: /* get mode information (old infterface) */ + info.vi_mode = ((old_video_info_t *)data)->vi_mode; + error = fb_ioctl(adp, FBIO_MODEINFO, &info); + if (error == 0) + bcopy(&info, (old_video_info_t *)data, sizeof(old_video_info_t)); + return error; + case CONS_MODEINFO: /* get mode information */ - return ((*vidsw[scp->ad]->get_info)(scp->adp, - ((video_info_t *)data)->vi_mode, (video_info_t *)data) - ? ENODEV : 0); + case FBIO_MODEINFO: + return fb_ioctl(adp, FBIO_MODEINFO, data); + + case OLD_CONS_FINDMODE: /* find a matching video mode (old interface) */ + bzero(&info, sizeof(info)); + bcopy((old_video_info_t *)data, &info, sizeof(old_video_info_t)); + error = fb_ioctl(adp, FBIO_FINDMODE, &info); + if (error == 0) + bcopy(&info, (old_video_info_t *)data, sizeof(old_video_info_t)); + return error; case CONS_FINDMODE: /* find a matching video mode */ - return ((*vidsw[scp->ad]->query_mode)(scp->adp, (video_info_t *)data) - ? ENODEV : 0); - - case CONS_SETWINORG: - return ((*vidsw[scp->ad]->set_win_org)(scp->adp, *(u_int *)data) - ? ENODEV : 0); + case FBIO_FINDMODE: + return fb_ioctl(adp, FBIO_FINDMODE, data); + + case CONS_SETWINORG: /* set frame buffer window origin */ + case FBIO_SETWINORG: + if (scp != scp->sc->cur_scp) + return ENODEV; /* XXX */ + return fb_ioctl(adp, FBIO_SETWINORG, data); + + case FBIO_GETWINORG: /* get frame buffer window origin */ + if (scp != scp->sc->cur_scp) + return ENODEV; /* XXX */ + return fb_ioctl(adp, FBIO_GETWINORG, data); + + case FBIO_GETDISPSTART: + case FBIO_SETDISPSTART: + case FBIO_GETLINEWIDTH: + case FBIO_SETLINEWIDTH: + if (scp != scp->sc->cur_scp) + return ENODEV; /* XXX */ + return fb_ioctl(adp, cmd, data); + + /* XXX */ + case FBIO_GETPALETTE: + case FBIO_SETPALETTE: + case FBIOPUTCMAP: + case FBIOGETCMAP: + return ENODEV; + case FBIOGTYPE: + case FBIOGATTR: + case FBIOSVIDEO: + case FBIOGVIDEO: + case FBIOSCURSOR: + case FBIOGCURSOR: + case FBIOSCURPOS: + case FBIOGCURPOS: + case FBIOGCURMAX: + if (scp != scp->sc->cur_scp) + return ENODEV; /* XXX */ + return fb_ioctl(adp, cmd, data); + +#ifndef SC_NO_MODE_CHANGE /* generic text modes */ case SW_TEXT_80x25: case SW_TEXT_80x30: case SW_TEXT_80x43: case SW_TEXT_80x50: @@ -428,6 +623,11 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p) case SW_VGA_C80x30: case SW_VGA_M80x30: case SW_VGA_C80x50: case SW_VGA_M80x50: case SW_VGA_C80x60: case SW_VGA_M80x60: + case SW_VGA_C90x25: case SW_VGA_M90x25: + case SW_VGA_C90x30: case SW_VGA_M90x30: + case SW_VGA_C90x43: case SW_VGA_M90x43: + case SW_VGA_C90x50: case SW_VGA_M90x50: + case SW_VGA_C90x60: case SW_VGA_M90x60: case SW_B40x25: case SW_C40x25: case SW_B80x25: case SW_C80x25: case SW_ENH_B40x25: case SW_ENH_C40x25: @@ -440,7 +640,7 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p) case SW_PC98_80x25: case SW_PC98_80x30: #endif - if (!(scp->adp->va_flags & V_ADP_MODECHANGE)) + if (!(adp->va_flags & V_ADP_MODECHANGE)) return ENODEV; return sc_set_text_mode(scp, tp, cmd & 0xff, 0, 0, 0); @@ -450,9 +650,10 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p) case SW_CG640x350: case SW_ENH_CG640: case SW_BG640x480: case SW_CG640x480: case SW_VGA_CG320: case SW_VGA_MODEX: - if (!(scp->adp->va_flags & V_ADP_MODECHANGE)) + if (!(adp->va_flags & V_ADP_MODECHANGE)) return ENODEV; return sc_set_graphics_mode(scp, tp, cmd & 0xff); +#endif /* SC_NO_MODE_CHANGE */ case KDSETMODE: /* set current mode of this (virtual) console */ switch (*(int *)data) { @@ -465,24 +666,31 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p) return EINVAL; /* restore fonts & palette ! */ #if 0 - if (ISFONTAVAIL(scp->adp->va_flags) +#ifndef SC_NO_FONT_LOADING + if (ISFONTAVAIL(adp->va_flags) && !(scp->status & (GRAPHICS_MODE | PIXEL_MODE))) /* * FONT KLUDGE * Don't load fonts for now... XXX */ - if (fonts_loaded & FONT_8) - copy_font(scp, LOAD, 8, font_8); - if (fonts_loaded & FONT_14) - copy_font(scp, LOAD, 14, font_14); - if (fonts_loaded & FONT_16) - copy_font(scp, LOAD, 16, font_16); + if (scp->sc->fonts_loaded & FONT_8) + copy_font(scp, LOAD, 8, scp->sc->font_8); + if (scp->sc->fonts_loaded & FONT_14) + copy_font(scp, LOAD, 14, scp->sc->font_14); + if (scp->sc->fonts_loaded & FONT_16) + copy_font(scp, LOAD, 16, scp->sc->font_16); } +#endif /* SC_NO_FONT_LOADING */ #endif - load_palette(scp->adp, palette); +#ifndef SC_NO_PALETTE_LOADING + load_palette(adp, scp->sc->palette); +#endif + +#ifndef PC98 /* move hardware cursor out of the way */ - (*vidsw[scp->ad]->set_hw_cursor)(scp->adp, -1, -1); + (*vidsw[adp->va_index]->set_hw_cursor)(adp, -1, -1); +#endif /* FALL THROUGH */ @@ -502,20 +710,21 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p) scp->status |= UNKNOWN_MODE; splx(s); /* no restore fonts & palette */ - if (scp == cur_console) + if (scp == scp->sc->cur_scp) set_mode(scp); sc_clear_screen(scp); scp->status &= ~UNKNOWN_MODE; #else /* PC98 */ scp->status &= ~UNKNOWN_MODE; /* no restore fonts & palette */ - if (scp == cur_console) + if (scp == scp->sc->cur_scp) set_mode(scp); sc_clear_screen(scp); splx(s); #endif /* PC98 */ return 0; +#ifdef SC_PIXEL_MODE case KD_PIXEL: /* pixel (raster) display */ if (!(scp->status & (GRAPHICS_MODE | PIXEL_MODE))) return EINVAL; @@ -529,13 +738,16 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p) } scp->status |= (UNKNOWN_MODE | PIXEL_MODE); splx(s); - if (scp == cur_console) { + if (scp == scp->sc->cur_scp) { set_mode(scp); - load_palette(scp->adp, palette); +#ifndef SC_NO_PALETTE_LOADING + load_palette(adp, scp->sc->palette); +#endif } sc_clear_screen(scp); scp->status &= ~UNKNOWN_MODE; return 0; +#endif /* SC_PIXEL_MODE */ case KD_GRAPHICS: /* switch to GRAPHICS (unknown) mode */ s = spltty(); @@ -546,7 +758,7 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p) scp->status |= UNKNOWN_MODE; splx(s); #ifdef PC98 - if (scp == cur_console) + if (scp == scp->sc->cur_scp) set_mode(scp); #endif return 0; @@ -556,11 +768,13 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p) } /* NOT REACHED */ +#ifdef SC_PIXEL_MODE case KDRASTER: /* set pixel (raster) display mode */ if (ISUNKNOWNSC(scp) || ISTEXTSC(scp)) return ENODEV; return sc_set_pixel_mode(scp, tp, ((int *)data)[0], ((int *)data)[1], ((int *)data)[2]); +#endif /* SC_PIXEL_MODE */ case KDGETMODE: /* get current mode of this (virtual) console */ /* @@ -572,7 +786,7 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p) case KDSBORDER: /* set border color of this (virtual) console */ scp->border = *data; - if (scp == cur_console) + if (scp == scp->sc->cur_scp) set_border(scp, scp->border); return 0; } diff --git a/sys/dev/syscons/scvtb.c b/sys/dev/syscons/scvtb.c new file mode 100644 index 0000000..a7d1a71 --- /dev/null +++ b/sys/dev/syscons/scvtb.c @@ -0,0 +1,283 @@ +/*- + * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer as + * the first lines of this file unmodified. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Id:$ + */ + +#include "sc.h" +#include "opt_syscons.h" + +#if NSC > 0 + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/malloc.h> + +#include <machine/console.h> +#include <machine/md_var.h> + +#include <dev/fb/fbreg.h> +#include <dev/syscons/syscons.h> + +#define vtb_wrap(vtb, at, offset) \ + (((at) + (offset) + (vtb)->vtb_size)%(vtb)->vtb_size) + +void +sc_vtb_init(sc_vtb_t *vtb, int type, int cols, int rows, void *buf, int wait) +{ + vtb->vtb_flags = 0; + vtb->vtb_type = type; + vtb->vtb_cols = cols; + vtb->vtb_rows = rows; + vtb->vtb_size = cols*rows; + vtb->vtb_buffer = NULL; + vtb->vtb_tail = 0; + + switch (type) { + case VTB_MEMORY: + case VTB_RINGBUFFER: + if ((buf == NULL) && (cols*rows != 0)) { + vtb->vtb_buffer = + (vm_offset_t)malloc(cols*rows*sizeof(u_int16_t), + M_DEVBUF, + (wait) ? M_WAITOK : M_NOWAIT); + if (vtb->vtb_buffer != NULL) + bzero((void *)sc_vtb_pointer(vtb, 0), + cols*rows*sizeof(u_int16_t)); + } else { + vtb->vtb_buffer = (vm_offset_t)buf; + } + vtb->vtb_flags |= VTB_VALID; + break; + case VTB_FRAMEBUFFER: + vtb->vtb_buffer = (vm_offset_t)buf; + vtb->vtb_flags |= VTB_VALID; + break; + default: + break; + } +} + +void +sc_vtb_destroy(sc_vtb_t *vtb) +{ + vm_offset_t p; + + vtb->vtb_flags = 0; + vtb->vtb_cols = 0; + vtb->vtb_rows = 0; + vtb->vtb_size = 0; + vtb->vtb_tail = 0; + + p = vtb->vtb_buffer; + vtb->vtb_buffer = NULL; + switch (vtb->vtb_type) { + case VTB_MEMORY: + case VTB_RINGBUFFER: + if (p != NULL) + free((void *)p, M_DEVBUF); + break; + default: + break; + } + vtb->vtb_type = VTB_INVALID; +} + +size_t +sc_vtb_size(int cols, int rows) +{ + return (size_t)(cols*rows*sizeof(u_int16_t)); +} + +int +sc_vtb_getc(sc_vtb_t *vtb, int at) +{ + if (vtb->vtb_type == VTB_FRAMEBUFFER) + return (readw(sc_vtb_pointer(vtb, at)) & 0x00ff); + else + return (*(u_int16_t *)sc_vtb_pointer(vtb, at) & 0x00ff); +} + +int +sc_vtb_geta(sc_vtb_t *vtb, int at) +{ + if (vtb->vtb_type == VTB_FRAMEBUFFER) + return (readw(sc_vtb_pointer(vtb, at)) & 0xff00); + else + return (*(u_int16_t *)sc_vtb_pointer(vtb, at) & 0xff00); +} + +void +sc_vtb_putc(sc_vtb_t *vtb, int at, int c, int a) +{ + if (vtb->vtb_type == VTB_FRAMEBUFFER) + writew(sc_vtb_pointer(vtb, at), a | c); + else + *(u_int16_t *)sc_vtb_pointer(vtb, at) = a | c; +} + +vm_offset_t +sc_vtb_putchar(sc_vtb_t *vtb, vm_offset_t p, int c, int a) +{ + if (vtb->vtb_type == VTB_FRAMEBUFFER) + writew(p, a | c); + else + *(u_int16_t *)p = a | c; + return (p + sizeof(u_int16_t)); +} + +vm_offset_t +sc_vtb_pointer(sc_vtb_t *vtb, int at) +{ + return (vtb->vtb_buffer + sizeof(u_int16_t)*(at)); +} + +int +sc_vtb_pos(sc_vtb_t *vtb, int pos, int offset) +{ + return ((pos + offset + vtb->vtb_size)%vtb->vtb_size); +} + +void +sc_vtb_clear(sc_vtb_t *vtb, int c, int attr) +{ + if (vtb->vtb_type == VTB_FRAMEBUFFER) + fillw_io(attr | c, sc_vtb_pointer(vtb, 0), vtb->vtb_size); + else + fillw(attr | c, (void *)sc_vtb_pointer(vtb, 0), vtb->vtb_size); +} + +void +sc_vtb_copy(sc_vtb_t *vtb1, int from, sc_vtb_t *vtb2, int to, int count) +{ + /* XXX if both are VTB_VRAMEBUFFER... */ + if (vtb2->vtb_type == VTB_FRAMEBUFFER) { + bcopy_toio(sc_vtb_pointer(vtb1, from), + sc_vtb_pointer(vtb2, to), + count*sizeof(u_int16_t)); + } else if (vtb1->vtb_type == VTB_FRAMEBUFFER) { + bcopy_fromio(sc_vtb_pointer(vtb1, from), + sc_vtb_pointer(vtb2, to), + count*sizeof(u_int16_t)); + } else { + bcopy((void *)sc_vtb_pointer(vtb1, from), + (void *)sc_vtb_pointer(vtb2, to), + count*sizeof(u_int16_t)); + } +} + +void +sc_vtb_append(sc_vtb_t *vtb1, int from, sc_vtb_t *vtb2, int count) +{ + int len; + + if (vtb2->vtb_type != VTB_RINGBUFFER) + return; + + while (count > 0) { + len = imin(count, vtb2->vtb_size - vtb2->vtb_tail); + if (vtb1->vtb_type == VTB_FRAMEBUFFER) { + bcopy_fromio(sc_vtb_pointer(vtb1, from), + sc_vtb_pointer(vtb2, vtb2->vtb_tail), + len*sizeof(u_int16_t)); + } else { + bcopy((void *)sc_vtb_pointer(vtb1, from), + (void *)sc_vtb_pointer(vtb2, vtb2->vtb_tail), + len*sizeof(u_int16_t)); + } + from += len; + count -= len; + vtb2->vtb_tail = vtb_wrap(vtb2, vtb2->vtb_tail, len); + } +} + +void +sc_vtb_seek(sc_vtb_t *vtb, int pos) +{ + vtb->vtb_tail = pos%vtb->vtb_size; +} + +void +sc_vtb_erase(sc_vtb_t *vtb, int at, int count, int c, int attr) +{ + if (at + count > vtb->vtb_size) + count = vtb->vtb_size - at; + if (vtb->vtb_type == VTB_FRAMEBUFFER) + fillw_io(attr | c, sc_vtb_pointer(vtb, at), count); + else + fillw(attr | c, (void *)sc_vtb_pointer(vtb, at), count); +} + +void +sc_vtb_delete(sc_vtb_t *vtb, int at, int count, int c, int attr) +{ + int len; + + if (at + count > vtb->vtb_size) + count = vtb->vtb_size - at; + len = vtb->vtb_size - at - count; + if (len > 0) { + if (vtb->vtb_type == VTB_FRAMEBUFFER) { + bcopy_io(sc_vtb_pointer(vtb, at + count), + sc_vtb_pointer(vtb, at), + len*sizeof(u_int16_t)); + } else { + bcopy((void *)sc_vtb_pointer(vtb, at + count), + (void *)sc_vtb_pointer(vtb, at), + len*sizeof(u_int16_t)); + } + } + if (vtb->vtb_type == VTB_FRAMEBUFFER) + fillw_io(attr | c, sc_vtb_pointer(vtb, at + len), + vtb->vtb_size - at - len); + else + fillw(attr | c, (void *)sc_vtb_pointer(vtb, at + len), + vtb->vtb_size - at - len); +} + +void +sc_vtb_ins(sc_vtb_t *vtb, int at, int count, int c, int attr) +{ + if (at + count > vtb->vtb_size) { + count = vtb->vtb_size - at; + } else { + if (vtb->vtb_type == VTB_FRAMEBUFFER) { + bcopy_io(sc_vtb_pointer(vtb, at), + sc_vtb_pointer(vtb, at + count), + (vtb->vtb_size - at - count)*sizeof(u_int16_t)); + } else { + bcopy((void *)sc_vtb_pointer(vtb, at), + (void *)sc_vtb_pointer(vtb, at + count), + (vtb->vtb_size - at - count)*sizeof(u_int16_t)); + } + } + if (vtb->vtb_type == VTB_FRAMEBUFFER) + fillw_io(attr | c, sc_vtb_pointer(vtb, at), count); + else + fillw(attr | c, (void *)sc_vtb_pointer(vtb, at), count); +} + +#endif /* NSC */ diff --git a/sys/dev/syscons/snake/snake_saver.c b/sys/dev/syscons/snake/snake_saver.c index ef64741..51e1746 100644 --- a/sys/dev/syscons/snake/snake_saver.c +++ b/sys/dev/syscons/snake/snake_saver.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: snake_saver.c,v 1.22 1999/01/17 14:25:19 yokota Exp $ + * $Id: snake_saver.c,v 1.23 1999/02/05 12:40:15 des Exp $ */ #include <sys/param.h> @@ -34,16 +34,18 @@ #include <sys/malloc.h> #include <sys/kernel.h> #include <sys/sysctl.h> +#include <sys/consio.h> +#include <sys/fbio.h> -#include <machine/md_var.h> #include <machine/pc/display.h> -#include <saver.h> +#include <dev/fb/fbreg.h> +#include <dev/fb/splashreg.h> +#include <dev/syscons/syscons.h> static char *message; -static u_char **messagep; +static int *messagep; static int messagelen; -static u_short *window; static int blanked; static int @@ -51,36 +53,50 @@ snake_saver(video_adapter_t *adp, int blank) { static int dirx, diry; int f; - scr_stat *scp = cur_console; + sc_softc_t *sc; + scr_stat *scp; /* XXX hack for minimal changes. */ #define save message #define savs messagep + sc = sc_find_softc(adp, NULL); + if (sc == NULL) + return EAGAIN; + scp = sc->cur_scp; + if (blank) { if (adp->va_info.vi_flags & V_INFO_GRAPHICS) return EAGAIN; if (blanked <= 0) { - window = (u_short *)adp->va_window; - fillw(((FG_LIGHTGREY|BG_BLACK)<<8) | scr_map[0x20], - window, scp->xsize * scp->ysize); +#ifdef PC98 + if (epson_machine_id == 0x20) { + outb(0x43f, 0x42); + outb(0x0c17, inb(0xc17) & ~0x08); + outb(0x43f, 0x40); + } +#endif /* PC98 */ + sc_vtb_clear(&scp->scr, sc->scr_map[0x20], + (FG_LIGHTGREY | BG_BLACK) << 8); + (*vidsw[adp->va_index]->set_hw_cursor)(adp, -1, -1); set_border(scp, 0); dirx = (scp->xpos ? 1 : -1); diry = (scp->ypos ? scp->xsize : -scp->xsize); for (f=0; f< messagelen; f++) - savs[f] = (u_char *)window + 2 * - (scp->xpos+scp->ypos*scp->xsize); - *(savs[0]) = scr_map[*save]; + savs[f] = scp->xpos + scp->ypos*scp->xsize; + sc_vtb_putc(&scp->scr, savs[0], sc->scr_map[*save], + (FG_LIGHTGREY | BG_BLACK) << 8); blanked = 1; } if (blanked++ < 4) return 0; blanked = 1; - *(savs[messagelen-1]) = scr_map[0x20]; + sc_vtb_putc(&scp->scr, savs[messagelen - 1], sc->scr_map[0x20], + (FG_LIGHTGREY | BG_BLACK) << 8); for (f=messagelen-1; f > 0; f--) savs[f] = savs[f-1]; - f = (savs[0] - (u_char *)window) / 2; + f = savs[0]; if ((f % scp->xsize) == 0 || (f % scp->xsize) == scp->xsize - 1 || (random() % 50) == 0) @@ -89,11 +105,19 @@ snake_saver(video_adapter_t *adp, int blank) (f / scp->xsize) == scp->ysize - 1 || (random() % 20) == 0) diry = -diry; - savs[0] += 2*dirx + 2*diry; + savs[0] += dirx + diry; for (f=messagelen-1; f>=0; f--) - *(savs[f]) = scr_map[save[f]]; + sc_vtb_putc(&scp->scr, savs[f], sc->scr_map[save[f]], + (FG_LIGHTGREY | BG_BLACK) << 8); } else { +#ifdef PC98 + if (epson_machine_id == 0x20) { + outb(0x43f, 0x42); + outb(0x0c17, inb(0xc17) | 0x08); + outb(0x43f, 0x40); + } +#endif /* PC98 */ blanked = 0; } return 0; diff --git a/sys/dev/syscons/star/star_saver.c b/sys/dev/syscons/star/star_saver.c index aaa23fb..56408dc 100644 --- a/sys/dev/syscons/star/star_saver.c +++ b/sys/dev/syscons/star/star_saver.c @@ -25,22 +25,24 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: star_saver.c,v 1.19 1999/01/17 14:25:19 yokota Exp $ + * $Id: star_saver.c,v 1.20 1999/02/05 12:40:16 des Exp $ */ #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> #include <sys/module.h> +#include <sys/consio.h> +#include <sys/fbio.h> -#include <machine/md_var.h> #include <machine/pc/display.h> -#include <saver.h> +#include <dev/fb/fbreg.h> +#include <dev/fb/splashreg.h> +#include <dev/syscons/syscons.h> #define NUM_STARS 50 -static u_short *window; static int blanked; /* @@ -50,21 +52,39 @@ static int blanked; static int star_saver(video_adapter_t *adp, int blank) { - scr_stat *scp = cur_console; + sc_softc_t *sc; + scr_stat *scp; int cell, i; char pattern[] = {"...........++++*** "}; +#ifndef PC98 char colors[] = {FG_DARKGREY, FG_LIGHTGREY, FG_WHITE, FG_LIGHTCYAN}; +#else + char colors[] = {FG_BLUE, FG_LIGHTGREY, + FG_LIGHTGREY, FG_CYAN}; +#endif /* PC98 */ static u_short stars[NUM_STARS][2]; + sc = sc_find_softc(adp, NULL); + if (sc == NULL) + return EAGAIN; + scp = sc->cur_scp; + if (blank) { if (adp->va_info.vi_flags & V_INFO_GRAPHICS) return EAGAIN; if (!blanked) { - window = (u_short *)adp->va_window; +#ifdef PC98 + if (epson_machine_id == 0x20) { + outb(0x43f, 0x42); + outb(0x0c17, inb(0xc17) & ~0x08); + outb(0x43f, 0x40); + } +#endif /* PC98 */ /* clear the screen and set the border color */ - fillw(((FG_LIGHTGREY|BG_BLACK) << 8) | scr_map[0x20], - window, scp->xsize * scp->ysize); + sc_vtb_clear(&scp->scr, sc->scr_map[0x20], + (FG_LIGHTGREY | BG_BLACK) << 8); + (*vidsw[adp->va_index]->set_hw_cursor)(adp, -1, -1); set_border(scp, 0); blanked = TRUE; for(i=0; i<NUM_STARS; i++) { @@ -74,15 +94,22 @@ star_saver(video_adapter_t *adp, int blank) } } cell = random() % NUM_STARS; - *((u_short*)(window + stars[cell][0])) = - scr_map[pattern[stars[cell][1]]] | - colors[random()%sizeof(colors)] << 8; + sc_vtb_putc(&scp->scr, stars[cell][0], + sc->scr_map[pattern[stars[cell][1]]], + colors[random()%sizeof(colors)] << 8); if ((stars[cell][1]+=(random()%4)) >= sizeof(pattern)-1) { stars[cell][0] = random() % (scp->xsize*scp->ysize); stars[cell][1] = 0; } } else { +#ifdef PC98 + if (epson_machine_id == 0x20) { + outb(0x43f, 0x42); + outb(0x0c17, inb(0xc17) | 0x08); + outb(0x43f, 0x40); + } +#endif /* PC98 */ blanked = FALSE; } return 0; diff --git a/sys/dev/syscons/syscons.c b/sys/dev/syscons/syscons.c index df527fc..937dcbc 100644 --- a/sys/dev/syscons/syscons.c +++ b/sys/dev/syscons/syscons.c @@ -30,15 +30,12 @@ #include "sc.h" #include "splash.h" -#ifdef __i386__ -#include "apm.h" -#endif +#include "opt_syscons.h" #include "opt_ddb.h" #include "opt_devfs.h" #ifdef __i386__ -#include "opt_vesa.h" +#include "apm.h" #endif -#include "opt_syscons.h" #if NSC > 0 #include <sys/param.h> @@ -54,308 +51,158 @@ #include <sys/devfsext.h> #endif -#include <machine/bootinfo.h> #include <machine/clock.h> #include <machine/cons.h> #include <machine/console.h> -#include <machine/mouse.h> -#include <machine/md_var.h> #include <machine/psl.h> -#include <machine/frame.h> #include <machine/pc/display.h> #ifdef __i386__ -#include <machine/pc/vesa.h> #include <machine/apm_bios.h> +#include <machine/frame.h> #include <machine/random.h> #endif -#include <vm/vm.h> -#include <vm/vm_param.h> -#include <vm/pmap.h> - #include <dev/kbd/kbdreg.h> #include <dev/fb/fbreg.h> -#include <dev/fb/vgareg.h> #include <dev/fb/splashreg.h> #include <dev/syscons/syscons.h> -#ifndef __i386__ -#include <isa/isareg.h> -#else -#include <i386/isa/isa.h> -#include <i386/isa/isa_device.h> -#include <i386/isa/timerreg.h> -#endif - -#if !defined(MAXCONS) -#define MAXCONS 16 -#endif - -#if !defined(SC_MAX_HISTORY_SIZE) -#define SC_MAX_HISTORY_SIZE (1000 * MAXCONS) -#endif - -#if !defined(SC_HISTORY_SIZE) -#define SC_HISTORY_SIZE (ROW * 4) -#endif - -#if (SC_HISTORY_SIZE * MAXCONS) > SC_MAX_HISTORY_SIZE -#undef SC_MAX_HISTORY_SIZE -#define SC_MAX_HISTORY_SIZE (SC_HISTORY_SIZE * MAXCONS) -#endif - -#if !defined(SC_MOUSE_CHAR) -#define SC_MOUSE_CHAR (0xd0) -#endif - #define COLD 0 #define WARM 1 #define DEFAULT_BLANKTIME (5*60) /* 5 minutes */ #define MAX_BLANKTIME (7*24*60*60) /* 7 days!? */ -/* for backward compatibility */ -#define OLD_CONS_MOUSECTL _IOWR('c', 10, old_mouse_info_t) - -typedef struct old_mouse_data { - int x; - int y; - int buttons; -} old_mouse_data_t; - -typedef struct old_mouse_info { - int operation; - union { - struct old_mouse_data data; - struct mouse_mode mode; - } u; -} old_mouse_info_t; +#define KEYCODE_BS 0x0e /* "<-- Backspace" key, XXX */ static default_attr user_default = { - (FG_LIGHTGREY | BG_BLACK) << 8, - (FG_BLACK | BG_LIGHTGREY) << 8 + SC_NORM_ATTR << 8, + SC_NORM_REV_ATTR << 8, }; static default_attr kernel_default = { - (FG_WHITE | BG_BLACK) << 8, - (FG_BLACK | BG_LIGHTGREY) << 8 + SC_KERNEL_CONS_ATTR << 8, + SC_KERNEL_CONS_REV_ATTR << 8, }; -static scr_stat main_console; -static scr_stat *console[MAXCONS]; +static int sc_console_unit = -1; +static scr_stat *sc_console; #ifdef DEVFS -static void *sc_devfs_token[MAXCONS]; static void *sc_mouse_devfs_token; static void *sc_console_devfs_token; #endif - scr_stat *cur_console; -static scr_stat *new_scp, *old_scp; static term_stat kernel_console; static default_attr *current_default; -static int sc_flags; + static char init_done = COLD; -static u_short sc_buffer[ROW*COL]; static char shutdown_in_progress = FALSE; -static char font_loading_in_progress = FALSE; -static char switch_in_progress = FALSE; -static char write_in_progress = FALSE; -static char blink_in_progress = FALSE; -static int blinkrate = 0; -static int adapter = -1; -static int keyboard = -1; -static keyboard_t *kbd; -static int delayed_next_scr = FALSE; -static long scrn_blank_time = 0; /* screen saver timeout value */ -static int scrn_blanked = FALSE; /* screen saver active flag */ -static long scrn_time_stamp; +static char sc_malloc = FALSE; + static int saver_mode = CONS_LKM_SAVER; /* LKM/user saver */ static int run_scrn_saver = FALSE; /* should run the saver? */ -static int scrn_idle = FALSE; /* about to run the saver */ -#if NSPLASH > 0 -static int scrn_saver_failed; -#endif - u_char scr_map[256]; - u_char scr_rmap[256]; -static int initial_video_mode; /* initial video mode # */ - int fonts_loaded = 0 -#ifdef STD8X16FONT - | FONT_16 -#endif - ; +static long scrn_blank_time = 0; /* screen saver timeout value */ +static int scrn_blanked; /* # of blanked screen */ +static int sticky_splash = FALSE; - u_char font_8[256*8]; - u_char font_14[256*14]; -#ifdef STD8X16FONT -extern +static void none_saver(sc_softc_t *sc, int blank) { } +static void (*current_saver)(sc_softc_t *, int) = none_saver; + +#if !defined(SC_NO_FONT_LOADING) && defined(SC_DFLT_FONT) +#include "font.h" #endif - u_char font_16[256*16]; - u_char palette[256*3]; -static u_char *cut_buffer; -static int cut_buffer_size; -static int mouse_level; /* sysmouse protocol level */ -static mousestatus_t mouse_status = { 0, 0, 0, 0, 0, 0 }; -static u_short mouse_and_mask[16] = { - 0xc000, 0xe000, 0xf000, 0xf800, - 0xfc00, 0xfe00, 0xff00, 0xff80, - 0xfe00, 0x1e00, 0x1f00, 0x0f00, - 0x0f00, 0x0000, 0x0000, 0x0000 - }; -static u_short mouse_or_mask[16] = { - 0x0000, 0x4000, 0x6000, 0x7000, - 0x7800, 0x7c00, 0x7e00, 0x6800, - 0x0c00, 0x0c00, 0x0600, 0x0600, - 0x0000, 0x0000, 0x0000, 0x0000 - }; - - int sc_history_size = SC_HISTORY_SIZE; -static int extra_history_size = - SC_MAX_HISTORY_SIZE - SC_HISTORY_SIZE * MAXCONS; - -static void none_saver(int blank) { } -static void (*current_saver)(int blank) = none_saver; + d_ioctl_t *sc_user_ioctl; -static int sticky_splash = FALSE; -static struct { - u_int8_t cursor_start; - u_int8_t cursor_end; - u_int8_t shift_state; - } bios_value; - -/* OS specific stuff */ -#ifdef not_yet_done -#define VIRTUAL_TTY(x) (sccons[x] = ttymalloc(sccons[x])) -struct CONSOLE_TTY (sccons[MAXCONS] = ttymalloc(sccons[MAXCONS])) -struct MOUSE_TTY (sccons[MAXCONS+1] = ttymalloc(sccons[MAXCONS+1])) -struct tty *sccons[MAXCONS+2]; -#else -#define VIRTUAL_TTY(x) &sccons[x] -#define CONSOLE_TTY &sccons[MAXCONS] -#define MOUSE_TTY &sccons[MAXCONS+1] -static struct tty sccons[MAXCONS+2]; -#endif +static bios_values_t bios_value; + +static struct tty sccons[2]; #define SC_MOUSE 128 -#define SC_CONSOLE 255 -static const int nsccons = MAXCONS+2; - -#define WRAPHIST(scp, pointer, offset) \ - ((scp)->history + ((((pointer) - (scp)->history) + (scp)->history_size \ - + (offset)) % (scp)->history_size)) -#define ISSIGVALID(sig) ((sig) > 0 && (sig) < NSIG) - -/* some useful macros */ -#define kbd_read_char(kbd, wait) \ - (*kbdsw[(kbd)->kb_index]->read_char)((kbd), (wait)) -#define kbd_check_char(kbd) \ - (*kbdsw[(kbd)->kb_index]->check_char)((kbd)) -#define kbd_enable(kbd) \ - (*kbdsw[(kbd)->kb_index]->enable)((kbd)) -#define kbd_disable(kbd) \ - (*kbdsw[(kbd)->kb_index]->disable)((kbd)) -#define kbd_lock(kbd, lockf) \ - (*kbdsw[(kbd)->kb_index]->lock)((kbd), (lockf)) -#define kbd_ioctl(kbd, cmd, arg) \ - (((kbd) == NULL) ? \ - ENODEV : (*kbdsw[(kbd)->kb_index]->ioctl)((kbd), (cmd), (arg))) -#define kbd_clear_state(kbd) \ - (*kbdsw[(kbd)->kb_index]->clear_state)((kbd)) -#define kbd_get_fkeystr(kbd, fkey, len) \ - (*kbdsw[(kbd)->kb_index]->get_fkeystr)((kbd), (fkey), (len)) -#define kbd_poll(kbd, on) \ - (*kbdsw[(kbd)->kb_index]->poll)((kbd), (on)) +#define SC_CONSOLECTL 255 + +#define VIRTUAL_TTY(sc, x) (&((sc)->tty[(x) - (sc)->first_vty])) +#define CONSOLE_TTY (&sccons[0]) +#define MOUSE_TTY (&sccons[1]) + +#define debugger FALSE + +#ifdef __i386__ +#ifdef DDB +extern int in_Debugger; +#undef debugger +#define debugger in_Debugger +#endif /* DDB */ +#endif /* __i386__ */ /* prototypes */ -static kbd_callback_func_t sckbdevent; -static int scparam(struct tty *tp, struct termios *t); static int scvidprobe(int unit, int flags, int cons); static int sckbdprobe(int unit, int flags, int cons); +static void scmeminit(void *arg); +static int scdevtounit(dev_t dev); +static kbd_callback_func_t sckbdevent; +static int scparam(struct tty *tp, struct termios *t); static void scstart(struct tty *tp); static void scmousestart(struct tty *tp); -static void scinit(void); +static void scinit(int unit, int flags); +static void scterm(int unit, int flags); static void scshutdown(int howto, void *arg); -static u_int scgetc(keyboard_t *kbd, u_int flags); +static u_int scgetc(sc_softc_t *sc, u_int flags); #define SCGETC_CN 1 #define SCGETC_NONBLOCK 2 static int sccngetch(int flags); static void sccnupdate(scr_stat *scp); -static scr_stat *alloc_scp(void); -static void init_scp(scr_stat *scp); -static void get_bios_values(void); -static void sc_bcopy(scr_stat *scp, u_short *p, int from, int to, int mark); -static int get_scr_num(void); +static scr_stat *alloc_scp(sc_softc_t *sc, int vty); +static void init_scp(sc_softc_t *sc, int vty, scr_stat *scp); static timeout_t scrn_timer; +static int and_region(int *s1, int *e1, int s2, int e2); static void scrn_update(scr_stat *scp, int show_cursor); + #if NSPLASH > 0 -static int scsplash_callback(int); -static void scsplash_saver(int show); -static int add_scrn_saver(void (*this_saver)(int)); -static int remove_scrn_saver(void (*this_saver)(int)); +static int scsplash_callback(int event, void *arg); +static void scsplash_saver(sc_softc_t *sc, int show); +static int add_scrn_saver(void (*this_saver)(sc_softc_t *, int)); +static int remove_scrn_saver(void (*this_saver)(sc_softc_t *, int)); static int set_scrn_saver_mode(scr_stat *scp, int mode, u_char *pal, int border); static int restore_scrn_saver_mode(scr_stat *scp, int changemode); -static void stop_scrn_saver(void (*saver)(int)); -static int wait_scrn_saver_stop(void); +static void stop_scrn_saver(sc_softc_t *sc, void (*saver)(sc_softc_t *, int)); +static int wait_scrn_saver_stop(sc_softc_t *sc); #define scsplash_stick(stick) (sticky_splash = (stick)) #else /* !NSPLASH */ -#define stop_scrn_saver(saver) -#define wait_scrn_saver_stop() 0 #define scsplash_stick(stick) #endif /* NSPLASH */ -static int switch_scr(scr_stat *scp, u_int next_scr); -static void exchange_scr(void); + +static int switch_scr(sc_softc_t *sc, u_int next_scr); +static int do_switch_scr(sc_softc_t *sc, int s); +static int vt_proc_alive(scr_stat *scp); +static int signal_vt_rel(scr_stat *scp); +static int signal_vt_acq(scr_stat *scp); +static void exchange_scr(sc_softc_t *sc); static void scan_esc(scr_stat *scp, u_char c); static void ansi_put(scr_stat *scp, u_char *buf, int len); -static void draw_cursor_image(scr_stat *scp); -static void remove_cursor_image(scr_stat *scp); +static void draw_cursor_image(scr_stat *scp); +static void remove_cursor_image(scr_stat *scp); +static void update_cursor_image(scr_stat *scp); static void move_crsr(scr_stat *scp, int x, int y); -static void history_to_screen(scr_stat *scp); -static int history_up_line(scr_stat *scp); -static int history_down_line(scr_stat *scp); static int mask2attr(struct term_stat *term); static int save_kbd_state(scr_stat *scp); -static int update_kbd_state(int state, int mask); -static int update_kbd_leds(int which); -static void set_destructive_cursor(scr_stat *scp); -static void set_mouse_pos(scr_stat *scp); -static int skip_spc_right(scr_stat *scp, u_short *p); -static int skip_spc_left(scr_stat *scp, u_short *p); -static void mouse_cut(scr_stat *scp); -static void mouse_cut_start(scr_stat *scp); -static void mouse_cut_end(scr_stat *scp); -static void mouse_cut_word(scr_stat *scp); -static void mouse_cut_line(scr_stat *scp); -static void mouse_cut_extend(scr_stat *scp); -static void mouse_paste(scr_stat *scp); -static void draw_mouse_image(scr_stat *scp); -static void remove_mouse_image(scr_stat *scp); -static void draw_cutmarking(scr_stat *scp); -static void remove_cutmarking(scr_stat *scp); +static int update_kbd_state(scr_stat *scp, int state, int mask); +static int update_kbd_leds(scr_stat *scp, int which); static void do_bell(scr_stat *scp, int pitch, int duration); static timeout_t blink_screen; #define CDEV_MAJOR 12 -#ifdef __i386__ - static cn_probe_t sccnprobe; static cn_init_t sccninit; static cn_getc_t sccngetc; static cn_checkc_t sccncheckc; static cn_putc_t sccnputc; +static cn_term_t sccnterm; -CONS_DRIVER(sc, sccnprobe, sccninit, sccngetc, sccncheckc, sccnputc); - -#else /* !__i386__ */ - -static cn_getc_t sccngetc; -static cn_checkc_t sccncheckc; -static cn_putc_t sccnputc; - -struct consdev sc_cons = { - NULL, NULL, sccngetc, sccncheckc, sccnputc, - NULL, 0, CN_NORMAL, -}; +#if __alpha__ +void sccnattach(void); +#endif -#endif /* __i386__ */ +CONS_DRIVER(sc, sccnprobe, sccninit, sccnterm, sccngetc, sccncheckc, sccnputc); static d_open_t scopen; static d_close_t scclose; @@ -386,118 +233,6 @@ static struct cdevsw sc_cdevsw = { /* bmaj */ -1 }; -#ifdef __i386__ - -#define fillw_io(p, b, c) fillw((p), (void *)(b), (c)) - -#endif - -#ifdef __alpha__ - -static void -fillw(int pat, void *base, size_t cnt) -{ - u_short *sp = base; - while (cnt--) - *sp++ = pat; -} - -static void -fillw_io(int pat, u_int32_t base, size_t cnt) -{ - while (cnt--) { - writew(base, pat); - base += 2; - } -} - -#endif - -static void -draw_cursor_image(scr_stat *scp) -{ - u_short cursor_image; - vm_offset_t ptr; - u_short prev_image; - - if (ISPIXELSC(scp)) { - sc_bcopy(scp, scp->scr_buf, scp->cursor_pos - scp->scr_buf, - scp->cursor_pos - scp->scr_buf, 1); - return; - } - - ptr = scp->adp->va_window + 2*(scp->cursor_pos - scp->scr_buf); - - /* do we have a destructive cursor ? */ - if (sc_flags & CHAR_CURSOR) { - prev_image = scp->cursor_saveunder; - cursor_image = readw(ptr) & 0x00ff; - if (cursor_image == DEAD_CHAR) - cursor_image = prev_image & 0x00ff; - cursor_image |= *(scp->cursor_pos) & 0xff00; - scp->cursor_saveunder = cursor_image; - /* update the cursor bitmap if the char under the cursor has changed */ - if (prev_image != cursor_image) - set_destructive_cursor(scp); - /* modify cursor_image */ - if (!(sc_flags & BLINK_CURSOR)||((sc_flags & BLINK_CURSOR)&&(blinkrate & 4))){ - /* - * When the mouse pointer is at the same position as the cursor, - * the cursor bitmap needs to be updated even if the char under - * the cursor hasn't changed, because the mouse pionter may - * have moved by a few dots within the cursor cel. - */ - if ((prev_image == cursor_image) - && (cursor_image != *(scp->cursor_pos))) - set_destructive_cursor(scp); - cursor_image &= 0xff00; - cursor_image |= DEAD_CHAR; - } - } else { - cursor_image = (readw(ptr) & 0x00ff) | (*(scp->cursor_pos) & 0xff00); - scp->cursor_saveunder = cursor_image; - if (!(sc_flags & BLINK_CURSOR)||((sc_flags & BLINK_CURSOR)&&(blinkrate & 4))){ - if ((cursor_image & 0x7000) == 0x7000) { - cursor_image &= 0x8fff; - if(!(cursor_image & 0x0700)) - cursor_image |= 0x0700; - } else { - cursor_image |= 0x7000; - if ((cursor_image & 0x0700) == 0x0700) - cursor_image &= 0xf0ff; - } - } - } - writew(ptr, cursor_image); -} - -static void -remove_cursor_image(scr_stat *scp) -{ - if (ISPIXELSC(scp)) - sc_bcopy(scp, scp->scr_buf, scp->cursor_oldpos - scp->scr_buf, - scp->cursor_oldpos - scp->scr_buf, 0); - else - writew(scp->adp->va_window + 2*(scp->cursor_oldpos - scp->scr_buf), - scp->cursor_saveunder); -} - -static void -move_crsr(scr_stat *scp, int x, int y) -{ - if (x < 0) - x = 0; - if (y < 0) - y = 0; - if (x >= scp->xsize) - x = scp->xsize-1; - if (y >= scp->ysize) - y = scp->ysize-1; - scp->xpos = x; - scp->ypos = y; - scp->cursor_pos = scp->scr_buf + scp->ypos * scp->xsize + scp->xpos; -} - int sc_probe_unit(int unit, int flags) { @@ -514,8 +249,6 @@ sc_probe_unit(int unit, int flags) static int scvidprobe(int unit, int flags, int cons) { - video_adapter_t *adp; - /* * Access the video adapter driver through the back door! * Video adapter drivers need to be configured before syscons. @@ -525,17 +258,7 @@ scvidprobe(int unit, int flags, int cons) */ vid_configure(cons ? VIO_PROBE_ONLY : 0); - /* allocate a frame buffer */ - if (adapter < 0) { - adapter = vid_allocate("*", -1, (void *)&adapter); - if (adapter < 0) - return FALSE; - } - adp = vid_get_adapter(adapter); /* shouldn't fail */ - - initial_video_mode = adp->va_initial_mode; - - return TRUE; + return (vid_find_adapter("*", unit) >= 0); } /* probe the keyboard, return TRUE if found */ @@ -545,169 +268,241 @@ sckbdprobe(int unit, int flags, int cons) /* access the keyboard driver through the backdoor! */ kbd_configure(cons ? KB_CONF_PROBE_ONLY : 0); - /* allocate a keyboard and register the keyboard event handler */ - if (keyboard < 0) { - keyboard = kbd_allocate("*", -1, (void *)&keyboard, sckbdevent, NULL); - if (keyboard < 0) - return FALSE; - } - kbd = kbd_get_keyboard(keyboard); /* shouldn't fail */ - - return TRUE; -} + return (kbd_find_keyboard("*", unit) >= 0); +} + +static char +*adapter_name(video_adapter_t *adp) +{ + static struct { + int type; + char *name[2]; + } names[] = { + { KD_MONO, { "MDA", "MDA" } }, + { KD_HERCULES, { "Hercules", "Hercules" } }, + { KD_CGA, { "CGA", "CGA" } }, + { KD_EGA, { "EGA", "EGA (mono)" } }, + { KD_VGA, { "VGA", "VGA (mono)" } }, + { KD_PC98, { "PC-98x1", "PC-98x1" } }, + { KD_TGA, { "TGA", "TGA" } }, + { -1, { "Unknown", "Unknown" } }, + }; + int i; -#if NAPM > 0 -static int -scresume(void *dummy) -{ - if (kbd != NULL) - kbd_clear_state(kbd); - return 0; + for (i = 0; names[i].type != -1; ++i) + if (names[i].type == adp->va_type) + break; + return names[i].name[(adp->va_flags & V_ADP_COLOR) ? 0 : 1]; } -#endif int sc_attach_unit(int unit, int flags) { + sc_softc_t *sc; scr_stat *scp; -#if defined(VESA) +#ifdef SC_PIXEL_MODE video_info_t info; #endif #ifdef DEVFS int vc; #endif - scinit(); - scp = console[0]; - sc_flags = flags; - if (!ISFONTAVAIL(scp->adp->va_flags)) - sc_flags &= ~CHAR_CURSOR; - - /* copy temporary buffer to final buffer */ - scp->scr_buf = NULL; - sc_alloc_scr_buffer(scp, FALSE, FALSE); - bcopy(sc_buffer, scp->scr_buf, scp->xsize*scp->ysize*sizeof(u_short)); - - /* cut buffer is available only when the mouse pointer is used */ - if (ISMOUSEAVAIL(scp->adp->va_flags)) - sc_alloc_cut_buffer(scp, FALSE); - - /* initialize history buffer & pointers */ - sc_alloc_history_buffer(scp, sc_history_size, 0, FALSE); - -#if defined(VESA) - if ((sc_flags & VESA800X600) - && ((*vidsw[scp->ad]->get_info)(scp->adp, M_VESA_800x600, &info) == 0)) { + scmeminit(NULL); /* XXX */ + + flags &= ~SC_KERNEL_CONSOLE; + if (sc_console_unit == unit) + flags |= SC_KERNEL_CONSOLE; + scinit(unit, flags); + sc = sc_get_softc(unit, flags & SC_KERNEL_CONSOLE); + sc->config = flags; + scp = sc->console[0]; + if (sc_console == NULL) /* sc_console_unit < 0 */ + sc_console = scp; + +#ifdef SC_PIXEL_MODE + if ((sc->config & SC_VESA800X600) + && ((*vidsw[sc->adapter]->get_info)(sc->adp, M_VESA_800x600, &info) == 0)) { #if NSPLASH > 0 - splash_term(scp->adp); + if (sc->flags & SC_SPLASH_SCRN) + splash_term(sc->adp); #endif sc_set_graphics_mode(scp, NULL, M_VESA_800x600); sc_set_pixel_mode(scp, NULL, COL, ROW, 16); - initial_video_mode = M_VESA_800x600; + sc->initial_mode = M_VESA_800x600; #if NSPLASH > 0 /* put up the splash again! */ - splash_init(scp->adp, scsplash_callback); + if (sc->flags & SC_SPLASH_SCRN) + splash_init(sc->adp, scsplash_callback, sc); #endif } -#endif /* VESA */ +#endif /* SC_PIXEL_MODE */ - /* initialize cursor stuff */ + /* initialize cursor */ if (!ISGRAPHSC(scp)) - draw_cursor_image(scp); + update_cursor_image(scp); /* get screen update going */ - scrn_timer((void *)TRUE); + scrn_timer(sc); /* set up the keyboard */ - kbd_ioctl(kbd, KDSKBMODE, (caddr_t)&scp->kbd_mode); - update_kbd_state(scp->status, LOCK_MASK); + kbd_ioctl(sc->kbd, KDSKBMODE, (caddr_t)&scp->kbd_mode); + update_kbd_state(scp, scp->status, LOCK_MASK); + printf("sc%d: %s <%d virtual consoles, flags=0x%x>\n", + unit, adapter_name(sc->adp), sc->vtys, sc->config); if (bootverbose) { printf("sc%d:", unit); - if (adapter >= 0) - printf(" fb%d", adapter); - if (keyboard >= 0) - printf(" kbd%d", keyboard); + if (sc->adapter >= 0) + printf(" fb%d", sc->adapter); + if (sc->keyboard >= 0) + printf(" kbd%d", sc->keyboard); printf("\n"); } - printf("sc%d: ", unit); - switch(scp->adp->va_type) { - case KD_VGA: - printf("VGA %s", (scp->adp->va_flags & V_ADP_COLOR) ? "color" : "mono"); - break; - case KD_EGA: - printf("EGA %s", (scp->adp->va_flags & V_ADP_COLOR) ? "color" : "mono"); - break; - case KD_CGA: - printf("CGA"); - break; - case KD_MONO: - case KD_HERCULES: - default: - printf("MDA/Hercules"); - break; - } - printf(" <%d virtual consoles, flags=0x%x>\n", MAXCONS, sc_flags); - -#if NAPM > 0 - scp->r_hook.ah_fun = scresume; - scp->r_hook.ah_arg = NULL; - scp->r_hook.ah_name = "system keyboard"; - scp->r_hook.ah_order = APM_MID_ORDER; - apm_hook_establish(APM_HOOK_RESUME , &scp->r_hook); -#endif - at_shutdown(scshutdown, NULL, SHUTDOWN_PRE_SYNC); + /* register a shutdown callback for the kernel console */ + if (sc_console_unit == unit) + at_shutdown(scshutdown, (void *)unit, SHUTDOWN_PRE_SYNC); - cdevsw_add(&sc_cdevsw); + /* + * syscons's cdevsw must be registered from here. As syscons and + * pcvt share the same major number, their cdevsw cannot be + * registered at module loading/initialization time or by SYSINIT. + */ + cdevsw_add(&sc_cdevsw); /* XXX do this just once... */ #ifdef DEVFS - for (vc = 0; vc < MAXCONS; vc++) - sc_devfs_token[vc] = devfs_add_devswf(&sc_cdevsw, vc, DV_CHR, - UID_ROOT, GID_WHEEL, 0600, "ttyv%r", vc); - sc_mouse_devfs_token = devfs_add_devswf(&sc_cdevsw, SC_MOUSE, DV_CHR, - UID_ROOT, GID_WHEEL, 0600, "sysmouse"); - sc_console_devfs_token = devfs_add_devswf(&sc_cdevsw, SC_CONSOLE, DV_CHR, - UID_ROOT, GID_WHEEL, 0600, "consolectl"); + for (vc = sc->first_vty; vc < sc->first_vty + sc->vtys; vc++) + sc->devfs_token[vc] = devfs_add_devswf(&sc_cdevsw, vc, + DV_CHR, UID_ROOT, GID_WHEEL, + 0600, "ttyv%r", vc); + if (scp == sc_console) { +#ifndef SC_NO_SYSMOUSE + sc_mouse_devfs_token = devfs_add_devswf(&sc_cdevsw, SC_MOUSE, + DV_CHR, UID_ROOT, GID_WHEEL, + 0600, "sysmouse"); +#endif /* SC_NO_SYSMOUSE */ + sc_console_devfs_token = devfs_add_devswf(&sc_cdevsw, SC_CONSOLECTL, + DV_CHR, UID_ROOT, GID_WHEEL, + 0600, "consolectl"); + } +#endif /* DEVFS */ + + return 0; +} + +static void +scmeminit(void *arg) +{ + if (sc_malloc) + return; + sc_malloc = TRUE; + + /* + * As soon as malloc() becomes functional, we had better allocate + * various buffers for the kernel console. + */ + + if (sc_console_unit < 0) + return; + + /* copy the temporary buffer to the final buffer */ + sc_alloc_scr_buffer(sc_console, FALSE, FALSE); + +#ifndef SC_NO_CUTPASTE + /* cut buffer is available only when the mouse pointer is used */ + if (ISMOUSEAVAIL(sc_console->sc->adp->va_flags)) + sc_alloc_cut_buffer(sc_console, FALSE); #endif + +#ifndef SC_NO_HISTORY + /* initialize history buffer & pointers */ + sc_alloc_history_buffer(sc_console, 0, FALSE); +#endif +} + +/* XXX */ +SYSINIT(sc_mem, SI_SUB_KMEM, SI_ORDER_ANY, scmeminit, NULL); + +int +sc_resume_unit(int unit) +{ + /* XXX should be moved to the keyboard driver? */ + sc_softc_t *sc; + + sc = sc_get_softc(unit, (sc_console_unit == unit) ? SC_KERNEL_CONSOLE : 0); + if (sc->kbd != NULL) + kbd_clear_state(sc->kbd); return 0; } struct tty *scdevtotty(dev_t dev) { - int unit = minor(dev); + sc_softc_t *sc; + int vty = SC_VTY(dev); + int unit; if (init_done == COLD) - return(NULL); - if (unit == SC_CONSOLE) + return NULL; + + if (vty == SC_CONSOLECTL) return CONSOLE_TTY; - if (unit == SC_MOUSE) +#ifndef SC_NO_SYSMOUSE + if (vty == SC_MOUSE) return MOUSE_TTY; - if (unit >= MAXCONS || unit < 0) - return(NULL); - return VIRTUAL_TTY(unit); +#endif + + unit = scdevtounit(dev); + sc = sc_get_softc(unit, (sc_console_unit == unit) ? SC_KERNEL_CONSOLE : 0); + if (sc == NULL) + return NULL; + return VIRTUAL_TTY(sc, vty); +} + +static int +scdevtounit(dev_t dev) +{ + int vty = SC_VTY(dev); + + if (vty == SC_CONSOLECTL) + return ((sc_console != NULL) ? sc_console->sc->unit : -1); + else if (vty == SC_MOUSE) + return -1; + else if ((vty < 0) || (vty >= MAXCONS*sc_max_unit())) + return -1; + else + return vty/MAXCONS; } int scopen(dev_t dev, int flag, int mode, struct proc *p) { struct tty *tp = scdevtotty(dev); + int unit = scdevtounit(dev); + sc_softc_t *sc; keyarg_t key; if (!tp) return(ENXIO); - tp->t_oproc = (minor(dev) == SC_MOUSE) ? scmousestart : scstart; + DPRINTF(5, ("scopen: dev:%d, unit:%d, vty:%d\n", + dev, unit, SC_VTY(dev))); + + /* sc == NULL, if SC_VTY(dev) == SC_MOUSE */ + sc = sc_get_softc(unit, (sc_console_unit == unit) ? SC_KERNEL_CONSOLE : 0); + + tp->t_oproc = (SC_VTY(dev) == SC_MOUSE) ? scmousestart : scstart; tp->t_param = scparam; tp->t_dev = dev; if (!(tp->t_state & TS_ISOPEN)) { ttychars(tp); /* Use the current setting of the <-- key as default VERASE. */ /* If the Delete key is preferable, an stty is necessary */ - key.keynum = 0x0e; /* how do we know this magic number... XXX */ - kbd_ioctl(kbd, GIO_KEYMAPENT, (caddr_t)&key); - tp->t_cc[VERASE] = key.key.map[0]; + if (sc != NULL) { + key.keynum = KEYCODE_BS; + kbd_ioctl(sc->kbd, GIO_KEYMAPENT, (caddr_t)&key); + tp->t_cc[VERASE] = key.key.map[0]; + } tp->t_iflag = TTYDEF_IFLAG; tp->t_oflag = TTYDEF_OFLAG; tp->t_cflag = TTYDEF_CFLAG; @@ -715,20 +510,29 @@ scopen(dev_t dev, int flag, int mode, struct proc *p) tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; scparam(tp, &tp->t_termios); (*linesw[tp->t_line].l_modem)(tp, 1); - if (minor(dev) == SC_MOUSE) - mouse_level = 0; /* XXX */ +#ifndef SC_NO_SYSMOUSE + if (SC_VTY(dev) == SC_MOUSE) + sc_mouse_set_level(0); /* XXX */ +#endif } else if (tp->t_state & TS_XCLUDE && suser(p)) return(EBUSY); - if (minor(dev) < MAXCONS && !console[minor(dev)]) { - console[minor(dev)] = alloc_scp(); - if (ISGRAPHSC(console[minor(dev)])) - sc_set_pixel_mode(console[minor(dev)], NULL, COL, ROW, 16); - } - if (minor(dev)<MAXCONS && !tp->t_winsize.ws_col && !tp->t_winsize.ws_row) { - tp->t_winsize.ws_col = console[minor(dev)]->xsize; - tp->t_winsize.ws_row = console[minor(dev)]->ysize; + if ((SC_VTY(dev) != SC_CONSOLECTL) && (SC_VTY(dev) != SC_MOUSE)) { + /* assert(sc != NULL) */ + if (sc->console[SC_VTY(dev) - sc->first_vty] == NULL) { + sc->console[SC_VTY(dev) - sc->first_vty] + = alloc_scp(sc, SC_VTY(dev)); + if (ISGRAPHSC(sc->console[SC_VTY(dev) - sc->first_vty])) + sc_set_pixel_mode(sc->console[SC_VTY(dev) - sc->first_vty], + NULL, COL, ROW, 16); + } + if (!tp->t_winsize.ws_col && !tp->t_winsize.ws_row) { + tp->t_winsize.ws_col + = sc->console[SC_VTY(dev) - sc->first_vty]->xsize; + tp->t_winsize.ws_row + = sc->console[SC_VTY(dev) - sc->first_vty]->ysize; + } } return ((*linesw[tp->t_line].l_open)(dev, tp)); } @@ -738,13 +542,29 @@ scclose(dev_t dev, int flag, int mode, struct proc *p) { struct tty *tp = scdevtotty(dev); struct scr_stat *scp; + int s; if (!tp) return(ENXIO); - if (minor(dev) < MAXCONS) { + if ((SC_VTY(dev) != SC_CONSOLECTL) && (SC_VTY(dev) != SC_MOUSE)) { scp = sc_get_scr_stat(tp->t_dev); - if (scp->status & SWITCH_WAIT_ACQ) - wakeup((caddr_t)&scp->smode); + /* were we in the middle of the VT switching process? */ + DPRINTF(5, ("sc%d: scclose(), ", scp->sc->unit)); + s = spltty(); + if ((scp == scp->sc->cur_scp) && (scp->sc->unit == sc_console_unit)) + cons_unavail = FALSE; + if (scp->status & SWITCH_WAIT_REL) { + /* assert(scp == scp->sc->cur_scp) */ + DPRINTF(5, ("reset WAIT_REL, ")); + scp->status &= ~SWITCH_WAIT_REL; + do_switch_scr(scp->sc, s); + } + if (scp->status & SWITCH_WAIT_ACQ) { + /* assert(scp == scp->sc->cur_scp) */ + DPRINTF(5, ("reset WAIT_ACQ, ")); + scp->status &= ~SWITCH_WAIT_ACQ; + scp->sc->switch_in_progress = 0; + } #if not_yet_done if (scp == &main_console) { scp->pid = 0; @@ -752,22 +572,25 @@ scclose(dev_t dev, int flag, int mode, struct proc *p) scp->smode.mode = VT_AUTO; } else { - free(scp->scr_buf, M_DEVBUF); + sc_vtb_destroy(&scp->vtb); + sc_vtb_destroy(&scp->scr); if (scp->history != NULL) { + /* XXX not quite correct */ + sc_vtb_destroy(scp->history); free(scp->history, M_DEVBUF); - if (scp->history_size / scp->xsize - > imax(sc_history_size, scp->ysize)) - extra_history_size += scp->history_size / scp->xsize - - imax(sc_history_size, scp->ysize); } free(scp, M_DEVBUF); - console[minor(dev)] = NULL; + sc->console[SC_VTY(dev) - sc->first_vty] = NULL; } #else scp->pid = 0; scp->proc = NULL; scp->smode.mode = VT_AUTO; #endif + scp->kbd_mode = K_XLATE; + if (scp == scp->sc->cur_scp) + kbd_ioctl(scp->sc->kbd, KDSKBMODE, (caddr_t)&scp->kbd_mode); + DPRINTF(5, ("done.\n")); } spltty(); (*linesw[tp->t_line].l_close)(tp, flag); @@ -800,19 +623,21 @@ scwrite(dev_t dev, struct uio *uio, int flag) static int sckbdevent(keyboard_t *thiskbd, int event, void *arg) { - static struct tty *cur_tty; + sc_softc_t *sc; + struct tty *cur_tty; int c; size_t len; u_char *cp; - /* assert(thiskbd == kbd) */ + sc = (sc_softc_t *)arg; + /* assert(thiskbd == sc->kbd) */ switch (event) { case KBDIO_KEYINPUT: break; case KBDIO_UNLOADING: - kbd = NULL; - kbd_release(thiskbd, (void *)&keyboard); + sc->kbd = NULL; + kbd_release(thiskbd, (void *)&sc->keyboard); return 0; default: return EINVAL; @@ -823,9 +648,10 @@ sckbdevent(keyboard_t *thiskbd, int event, void *arg) * I don't think this is nessesary, and it doesn't fix * the Xaccel-2.1 keyboard hang, but it can't hurt. XXX */ - while ((c = scgetc(thiskbd, SCGETC_NONBLOCK)) != NOKEY) { + while ((c = scgetc(sc, SCGETC_NONBLOCK)) != NOKEY) { - cur_tty = VIRTUAL_TTY(get_scr_num()); + cur_tty = VIRTUAL_TTY(sc, sc->cur_scp->index); + /* XXX */ if (!(cur_tty->t_state & TS_ISOPEN)) if (!((cur_tty = CONSOLE_TTY)->t_state & TS_ISOPEN)) continue; @@ -853,10 +679,12 @@ sckbdevent(keyboard_t *thiskbd, int event, void *arg) } } - if (cur_console->status & MOUSE_VISIBLE) { - remove_mouse_image(cur_console); - cur_console->status &= ~MOUSE_VISIBLE; +#ifndef SC_NO_CUTPASTE + if (sc->cur_scp->status & MOUSE_VISIBLE) { + sc_remove_mouse_image(sc->cur_scp); + sc->cur_scp->status &= ~MOUSE_VISIBLE; } +#endif /* SC_NO_CUTPASTE */ return 0; } @@ -873,17 +701,16 @@ scparam(struct tty *tp, struct termios *t) int scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) { - u_int delta_ehs; int error; int i; struct tty *tp; + sc_softc_t *sc; scr_stat *scp; int s; tp = scdevtotty(dev); if (!tp) return ENXIO; - scp = sc_get_scr_stat(tp->t_dev); /* If there is a user_ioctl function call that first */ if (sc_user_ioctl) { @@ -896,6 +723,32 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) if (error != ENOIOCTL) return error; +#ifndef SC_NO_HISTORY + error = sc_hist_ioctl(tp, cmd, data, flag, p); + if (error != ENOIOCTL) + return error; +#endif + +#ifndef SC_NO_SYSMOUSE + error = sc_mouse_ioctl(tp, cmd, data, flag, p); + if (error != ENOIOCTL) + return error; + if (SC_VTY(dev) == SC_MOUSE) { + error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p); + if (error != ENOIOCTL) + return error; + error = ttioctl(tp, cmd, data, flag); + if (error != ENOIOCTL) + return error; + return ENOTTY; + } +#endif + + scp = sc_get_scr_stat(tp->t_dev); + /* assert(scp != NULL) */ + /* scp is sc_console, if SC_VTY(dev) == SC_CONSOLECTL. */ + sc = scp->sc; + switch (cmd) { /* process console hardware related ioctl's */ case GIO_ATTR: /* get current attributes */ @@ -903,7 +756,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) return 0; case GIO_COLOR: /* is this a color console ? */ - *(int *)data = (scp->adp->va_flags & V_ADP_COLOR) ? 1 : 0; + *(int *)data = (sc->adp->va_flags & V_ADP_COLOR) ? 1 : 0; return 0; case CONS_BLANKTIME: /* set screen saver timeout (0 = no saver) */ @@ -916,461 +769,44 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) return 0; case CONS_CURSORTYPE: /* set cursor type blink/noblink */ + if (!ISGRAPHSC(sc->cur_scp)) + remove_cursor_image(sc->cur_scp); if ((*(int*)data) & 0x01) - sc_flags |= BLINK_CURSOR; + sc->flags |= SC_BLINK_CURSOR; else - sc_flags &= ~BLINK_CURSOR; + sc->flags &= ~SC_BLINK_CURSOR; if ((*(int*)data) & 0x02) { - if (!ISFONTAVAIL(scp->adp->va_flags)) - return ENXIO; - sc_flags |= CHAR_CURSOR; + sc->flags |= SC_CHAR_CURSOR; } else - sc_flags &= ~CHAR_CURSOR; + sc->flags &= ~SC_CHAR_CURSOR; /* * The cursor shape is global property; all virtual consoles * are affected. Update the cursor in the current console... */ - if (!ISGRAPHSC(cur_console)) { + if (!ISGRAPHSC(sc->cur_scp)) { s = spltty(); - remove_cursor_image(cur_console); - if (sc_flags & CHAR_CURSOR) - set_destructive_cursor(cur_console); - draw_cursor_image(cur_console); + sc_set_cursor_image(sc->cur_scp); + draw_cursor_image(sc->cur_scp); splx(s); } return 0; case CONS_BELLTYPE: /* set bell type sound/visual */ if ((*(int *)data) & 0x01) - sc_flags |= VISUAL_BELL; + sc->flags |= SC_VISUAL_BELL; else - sc_flags &= ~VISUAL_BELL; + sc->flags &= ~SC_VISUAL_BELL; if ((*(int *)data) & 0x02) - sc_flags |= QUIET_BELL; - else - sc_flags &= ~QUIET_BELL; - return 0; - - case CONS_HISTORY: /* set history size */ - if (*(int *)data > 0) { - int lines; /* buffer size to allocate */ - int lines0; /* current buffer size */ - - lines = imax(*(int *)data, scp->ysize); - lines0 = (scp->history != NULL) ? - scp->history_size / scp->xsize : scp->ysize; - if (lines0 > imax(sc_history_size, scp->ysize)) - delta_ehs = lines0 - imax(sc_history_size, scp->ysize); - else - delta_ehs = 0; - /* - * syscons unconditionally allocates buffers upto SC_HISTORY_SIZE - * lines or scp->ysize lines, whichever is larger. A value - * greater than that is allowed, subject to extra_history_size. - */ - if (lines > imax(sc_history_size, scp->ysize)) - if (lines - imax(sc_history_size, scp->ysize) > - extra_history_size + delta_ehs) - return EINVAL; - if (cur_console->status & BUFFER_SAVED) - return EBUSY; - sc_alloc_history_buffer(scp, lines, delta_ehs, TRUE); - return 0; - } + sc->flags |= SC_QUIET_BELL; else - return EINVAL; - - case CONS_MOUSECTL: /* control mouse arrow */ - case OLD_CONS_MOUSECTL: - { - /* MOUSE_BUTTON?DOWN -> MOUSE_MSC_BUTTON?UP */ - static int butmap[8] = { - MOUSE_MSC_BUTTON1UP | MOUSE_MSC_BUTTON2UP | MOUSE_MSC_BUTTON3UP, - MOUSE_MSC_BUTTON2UP | MOUSE_MSC_BUTTON3UP, - MOUSE_MSC_BUTTON1UP | MOUSE_MSC_BUTTON3UP, - MOUSE_MSC_BUTTON3UP, - MOUSE_MSC_BUTTON1UP | MOUSE_MSC_BUTTON2UP, - MOUSE_MSC_BUTTON2UP, - MOUSE_MSC_BUTTON1UP, - 0, - }; - mouse_info_t *mouse = (mouse_info_t*)data; - mouse_info_t buf; - - /* FIXME: */ - if (!ISMOUSEAVAIL(scp->adp->va_flags)) - return ENODEV; - - if (cmd == OLD_CONS_MOUSECTL) { - static u_char swapb[] = { 0, 4, 2, 6, 1, 5, 3, 7 }; - old_mouse_info_t *old_mouse = (old_mouse_info_t *)data; - - mouse = &buf; - mouse->operation = old_mouse->operation; - switch (mouse->operation) { - case MOUSE_MODE: - mouse->u.mode = old_mouse->u.mode; - break; - case MOUSE_SHOW: - case MOUSE_HIDE: - break; - case MOUSE_MOVEABS: - case MOUSE_MOVEREL: - case MOUSE_ACTION: - mouse->u.data.x = old_mouse->u.data.x; - mouse->u.data.y = old_mouse->u.data.y; - mouse->u.data.z = 0; - mouse->u.data.buttons = swapb[old_mouse->u.data.buttons & 0x7]; - break; - case MOUSE_GETINFO: - old_mouse->u.data.x = scp->mouse_xpos; - old_mouse->u.data.y = scp->mouse_ypos; - old_mouse->u.data.buttons = swapb[scp->mouse_buttons & 0x7]; - break; - default: - return EINVAL; - } - } - - switch (mouse->operation) { - case MOUSE_MODE: - if (ISSIGVALID(mouse->u.mode.signal)) { - scp->mouse_signal = mouse->u.mode.signal; - scp->mouse_proc = p; - scp->mouse_pid = p->p_pid; - } - else { - scp->mouse_signal = 0; - scp->mouse_proc = NULL; - scp->mouse_pid = 0; - } - return 0; - - case MOUSE_SHOW: - if (ISTEXTSC(scp) && !(scp->status & MOUSE_ENABLED)) { - scp->status |= (MOUSE_ENABLED | MOUSE_VISIBLE); - scp->mouse_oldpos = scp->mouse_pos; - mark_all(scp); - return 0; - } - else - return EINVAL; - break; - - case MOUSE_HIDE: - if (ISTEXTSC(scp) && (scp->status & MOUSE_ENABLED)) { - scp->status &= ~(MOUSE_ENABLED | MOUSE_VISIBLE); - mark_all(scp); - return 0; - } - else - return EINVAL; - break; - - case MOUSE_MOVEABS: - scp->mouse_xpos = mouse->u.data.x; - scp->mouse_ypos = mouse->u.data.y; - set_mouse_pos(scp); - break; - - case MOUSE_MOVEREL: - scp->mouse_xpos += mouse->u.data.x; - scp->mouse_ypos += mouse->u.data.y; - set_mouse_pos(scp); - break; - - case MOUSE_GETINFO: - mouse->u.data.x = scp->mouse_xpos; - mouse->u.data.y = scp->mouse_ypos; - mouse->u.data.z = 0; - mouse->u.data.buttons = scp->mouse_buttons; - return 0; - - case MOUSE_ACTION: - case MOUSE_MOTION_EVENT: - /* this should maybe only be settable from /dev/consolectl SOS */ - /* send out mouse event on /dev/sysmouse */ - - mouse_status.dx += mouse->u.data.x; - mouse_status.dy += mouse->u.data.y; - mouse_status.dz += mouse->u.data.z; - if (mouse->operation == MOUSE_ACTION) - mouse_status.button = mouse->u.data.buttons; - mouse_status.flags |= - ((mouse->u.data.x || mouse->u.data.y || mouse->u.data.z) ? - MOUSE_POSCHANGED : 0) - | (mouse_status.obutton ^ mouse_status.button); - if (mouse_status.flags == 0) - return 0; - - if (ISTEXTSC(cur_console) && (cur_console->status & MOUSE_ENABLED)) - cur_console->status |= MOUSE_VISIBLE; - - if ((MOUSE_TTY)->t_state & TS_ISOPEN) { - u_char buf[MOUSE_SYS_PACKETSIZE]; - int j; - - /* the first five bytes are compatible with MouseSystems' */ - buf[0] = MOUSE_MSC_SYNC - | butmap[mouse_status.button & MOUSE_STDBUTTONS]; - j = imax(imin(mouse->u.data.x, 255), -256); - buf[1] = j >> 1; - buf[3] = j - buf[1]; - j = -imax(imin(mouse->u.data.y, 255), -256); - buf[2] = j >> 1; - buf[4] = j - buf[2]; - for (j = 0; j < MOUSE_MSC_PACKETSIZE; j++) - (*linesw[(MOUSE_TTY)->t_line].l_rint)(buf[j],MOUSE_TTY); - if (mouse_level >= 1) { /* extended part */ - j = imax(imin(mouse->u.data.z, 127), -128); - buf[5] = (j >> 1) & 0x7f; - buf[6] = (j - (j >> 1)) & 0x7f; - /* buttons 4-10 */ - buf[7] = (~mouse_status.button >> 3) & 0x7f; - for (j = MOUSE_MSC_PACKETSIZE; - j < MOUSE_SYS_PACKETSIZE; j++) - (*linesw[(MOUSE_TTY)->t_line].l_rint)(buf[j],MOUSE_TTY); - } - } - - if (cur_console->mouse_signal) { - cur_console->mouse_buttons = mouse->u.data.buttons; - /* has controlling process died? */ - if (cur_console->mouse_proc && - (cur_console->mouse_proc != pfind(cur_console->mouse_pid))){ - cur_console->mouse_signal = 0; - cur_console->mouse_proc = NULL; - cur_console->mouse_pid = 0; - } - else - psignal(cur_console->mouse_proc, cur_console->mouse_signal); - } - else if (mouse->operation == MOUSE_ACTION && cut_buffer != NULL) { - /* process button presses */ - if ((cur_console->mouse_buttons ^ mouse->u.data.buttons) && - ISTEXTSC(cur_console)) { - cur_console->mouse_buttons = mouse->u.data.buttons; - if (cur_console->mouse_buttons & MOUSE_BUTTON1DOWN) - mouse_cut_start(cur_console); - else - mouse_cut_end(cur_console); - if (cur_console->mouse_buttons & MOUSE_BUTTON2DOWN || - cur_console->mouse_buttons & MOUSE_BUTTON3DOWN) - mouse_paste(cur_console); - } - } - - if (mouse->u.data.x != 0 || mouse->u.data.y != 0) { - cur_console->mouse_xpos += mouse->u.data.x; - cur_console->mouse_ypos += mouse->u.data.y; - set_mouse_pos(cur_console); - } - - break; - - case MOUSE_BUTTON_EVENT: - if ((mouse->u.event.id & MOUSE_BUTTONS) == 0) - return EINVAL; - if (mouse->u.event.value < 0) - return EINVAL; - - if (mouse->u.event.value > 0) { - cur_console->mouse_buttons |= mouse->u.event.id; - mouse_status.button |= mouse->u.event.id; - } else { - cur_console->mouse_buttons &= ~mouse->u.event.id; - mouse_status.button &= ~mouse->u.event.id; - } - mouse_status.flags |= mouse_status.obutton ^ mouse_status.button; - if (mouse_status.flags == 0) - return 0; - - if (ISTEXTSC(cur_console) && (cur_console->status & MOUSE_ENABLED)) - cur_console->status |= MOUSE_VISIBLE; - - if ((MOUSE_TTY)->t_state & TS_ISOPEN) { - u_char buf[8]; - int i; - - buf[0] = MOUSE_MSC_SYNC - | butmap[mouse_status.button & MOUSE_STDBUTTONS]; - buf[7] = (~mouse_status.button >> 3) & 0x7f; - buf[1] = buf[2] = buf[3] = buf[4] = buf[5] = buf[6] = 0; - for (i = 0; - i < ((mouse_level >= 1) ? MOUSE_SYS_PACKETSIZE - : MOUSE_MSC_PACKETSIZE); i++) - (*linesw[(MOUSE_TTY)->t_line].l_rint)(buf[i],MOUSE_TTY); - } - - if (cur_console->mouse_signal) { - if (cur_console->mouse_proc && - (cur_console->mouse_proc != pfind(cur_console->mouse_pid))){ - cur_console->mouse_signal = 0; - cur_console->mouse_proc = NULL; - cur_console->mouse_pid = 0; - } - else - psignal(cur_console->mouse_proc, cur_console->mouse_signal); - break; - } - - if (!ISTEXTSC(cur_console) || (cut_buffer == NULL)) - break; - - switch (mouse->u.event.id) { - case MOUSE_BUTTON1DOWN: - switch (mouse->u.event.value % 4) { - case 0: /* up */ - mouse_cut_end(cur_console); - break; - case 1: - mouse_cut_start(cur_console); - break; - case 2: - mouse_cut_word(cur_console); - break; - case 3: - mouse_cut_line(cur_console); - break; - } - break; - case MOUSE_BUTTON2DOWN: - switch (mouse->u.event.value) { - case 0: /* up */ - break; - default: - mouse_paste(cur_console); - break; - } - break; - case MOUSE_BUTTON3DOWN: - switch (mouse->u.event.value) { - case 0: /* up */ - if (!(cur_console->mouse_buttons & MOUSE_BUTTON1DOWN)) - mouse_cut_end(cur_console); - break; - default: - mouse_cut_extend(cur_console); - break; - } - break; - } - break; - - default: - return EINVAL; - } - /* make screensaver happy */ - sc_touch_scrn_saver(); - return 0; - } - - /* MOUSE_XXX: /dev/sysmouse ioctls */ - case MOUSE_GETHWINFO: /* get device information */ - { - mousehw_t *hw = (mousehw_t *)data; - - if (tp != MOUSE_TTY) - return ENOTTY; - hw->buttons = 10; /* XXX unknown */ - hw->iftype = MOUSE_IF_SYSMOUSE; - hw->type = MOUSE_MOUSE; - hw->model = MOUSE_MODEL_GENERIC; - hw->hwid = 0; + sc->flags &= ~SC_QUIET_BELL; return 0; - } - - case MOUSE_GETMODE: /* get protocol/mode */ - { - mousemode_t *mode = (mousemode_t *)data; - - if (tp != MOUSE_TTY) - return ENOTTY; - mode->level = mouse_level; - switch (mode->level) { - case 0: - /* at this level, sysmouse emulates MouseSystems protocol */ - mode->protocol = MOUSE_PROTO_MSC; - mode->rate = -1; /* unknown */ - mode->resolution = -1; /* unknown */ - mode->accelfactor = 0; /* disabled */ - mode->packetsize = MOUSE_MSC_PACKETSIZE; - mode->syncmask[0] = MOUSE_MSC_SYNCMASK; - mode->syncmask[1] = MOUSE_MSC_SYNC; - break; - - case 1: - /* at this level, sysmouse uses its own protocol */ - mode->protocol = MOUSE_PROTO_SYSMOUSE; - mode->rate = -1; - mode->resolution = -1; - mode->accelfactor = 0; - mode->packetsize = MOUSE_SYS_PACKETSIZE; - mode->syncmask[0] = MOUSE_SYS_SYNCMASK; - mode->syncmask[1] = MOUSE_SYS_SYNC; - break; - } - return 0; - } - - case MOUSE_SETMODE: /* set protocol/mode */ - { - mousemode_t *mode = (mousemode_t *)data; - - if (tp != MOUSE_TTY) - return ENOTTY; - if ((mode->level < 0) || (mode->level > 1)) - return EINVAL; - mouse_level = mode->level; - return 0; - } - - case MOUSE_GETLEVEL: /* get operation level */ - if (tp != MOUSE_TTY) - return ENOTTY; - *(int *)data = mouse_level; - return 0; - - case MOUSE_SETLEVEL: /* set operation level */ - if (tp != MOUSE_TTY) - return ENOTTY; - if ((*(int *)data < 0) || (*(int *)data > 1)) - return EINVAL; - mouse_level = *(int *)data; - return 0; - - case MOUSE_GETSTATUS: /* get accumulated mouse events */ - if (tp != MOUSE_TTY) - return ENOTTY; - s = spltty(); - *(mousestatus_t *)data = mouse_status; - mouse_status.flags = 0; - mouse_status.obutton = mouse_status.button; - mouse_status.dx = 0; - mouse_status.dy = 0; - mouse_status.dz = 0; - splx(s); - return 0; - -#if notyet - case MOUSE_GETVARS: /* get internal mouse variables */ - case MOUSE_SETVARS: /* set internal mouse variables */ - if (tp != MOUSE_TTY) - return ENOTTY; - return ENODEV; -#endif - - case MOUSE_READSTATE: /* read status from the device */ - case MOUSE_READDATA: /* read data from the device */ - if (tp != MOUSE_TTY) - return ENOTTY; - return ENODEV; case CONS_GETINFO: /* get current (virtual) console info */ { vid_info_t *ptr = (vid_info_t*)data; if (ptr->size == sizeof(struct vid_info)) { - ptr->m_num = get_scr_num(); + ptr->m_num = sc->cur_scp->index; ptr->mv_col = scp->xpos; ptr->mv_row = scp->ypos; ptr->mv_csz = scp->xsize; @@ -1382,7 +818,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) ptr->mv_grfc.fore = 0; /* not supported */ ptr->mv_grfc.back = 0; /* not supported */ ptr->mv_ovscan = scp->border; - if (scp == cur_console) + if (scp == sc->cur_scp) save_kbd_state(scp); ptr->mk_keylock = scp->status & LOCK_MASK; return 0; @@ -1404,9 +840,9 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) * graphics mode in the current screen, we should say that the * screen has been idle. */ - *(int *)data = scrn_idle - && (!ISGRAPHSC(cur_console) - || (cur_console->status & SAVER_RUNNING)); + *(int *)data = (sc->flags & SC_SCRN_IDLE) + && (!ISGRAPHSC(sc->cur_scp) + || (sc->cur_scp->status & SAVER_RUNNING)); return 0; case CONS_SAVERMODE: /* set saver mode */ @@ -1416,10 +852,13 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) scsplash_stick(FALSE); saver_mode = *(int *)data; s = spltty(); - if ((error = wait_scrn_saver_stop())) { +#if NSPLASH > 0 + if ((error = wait_scrn_saver_stop(NULL))) { splx(s); return error; } +#endif /* NSPLASH */ + run_scrn_saver = TRUE; scp->status |= SAVER_RUNNING; scsplash_stick(TRUE); splx(s); @@ -1444,7 +883,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) s = spltty(); run_scrn_saver = (*(int *)data != 0); if (run_scrn_saver) - scrn_time_stamp -= scrn_blank_time; + sc->scrn_time_stamp -= scrn_blank_time; splx(s); return 0; @@ -1453,16 +892,51 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) struct vt_mode *mode; mode = (struct vt_mode *)data; - if (ISSIGVALID(mode->relsig) && ISSIGVALID(mode->acqsig) && - ISSIGVALID(mode->frsig)) { - bcopy(data, &scp->smode, sizeof(struct vt_mode)); - if (scp->smode.mode == VT_PROCESS) { - scp->proc = p; - scp->pid = scp->proc->p_pid; + DPRINTF(5, ("sc%d: VT_SETMODE ", sc->unit)); + if (scp->smode.mode == VT_PROCESS) { + if (scp->proc == pfind(scp->pid) && scp->proc != p) { + DPRINTF(5, ("error EPERM\n")); + return EPERM; } - return 0; - } else - return EINVAL; + } + s = spltty(); + if (mode->mode == VT_AUTO) { + scp->smode.mode = VT_AUTO; + scp->proc = NULL; + scp->pid = 0; + DPRINTF(5, ("VT_AUTO, ")); + if ((scp == sc->cur_scp) && (sc->unit == sc_console_unit)) + cons_unavail = FALSE; + /* were we in the middle of the vty switching process? */ + if (scp->status & SWITCH_WAIT_REL) { + /* assert(scp == scp->sc->cur_scp) */ + DPRINTF(5, ("reset WAIT_REL, ")); + scp->status &= ~SWITCH_WAIT_REL; + s = do_switch_scr(sc, s); + } + if (scp->status & SWITCH_WAIT_ACQ) { + /* assert(scp == scp->sc->cur_scp) */ + DPRINTF(5, ("reset WAIT_ACQ, ")); + scp->status &= ~SWITCH_WAIT_ACQ; + sc->switch_in_progress = 0; + } + } else { + if (!ISSIGVALID(mode->relsig) || !ISSIGVALID(mode->acqsig) + || !ISSIGVALID(mode->frsig)) { + splx(s); + DPRINTF(5, ("error EINVAL\n")); + return EINVAL; + } + DPRINTF(5, ("VT_PROCESS %d, ", p->p_pid)); + bcopy(data, &scp->smode, sizeof(struct vt_mode)); + scp->proc = p; + scp->pid = scp->proc->p_pid; + if ((scp == sc->cur_scp) && (sc->unit == sc_console_unit)) + cons_unavail = TRUE; + } + splx(s); + DPRINTF(5, ("\n")); + return 0; } case VT_GETMODE: /* get screen switcher mode */ @@ -1470,45 +944,58 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) return 0; case VT_RELDISP: /* screen switcher ioctl */ + s = spltty(); + /* + * This must be the current vty which is in the VT_PROCESS + * switching mode... + */ + if ((scp != sc->cur_scp) || (scp->smode.mode != VT_PROCESS)) { + splx(s); + return EINVAL; + } + /* ...and this process is controlling it. */ + if (scp->proc != p) { + splx(s); + return EPERM; + } + error = EINVAL; switch(*(int *)data) { case VT_FALSE: /* user refuses to release screen, abort */ - if (scp == old_scp && (scp->status & SWITCH_WAIT_REL)) { - old_scp->status &= ~SWITCH_WAIT_REL; - switch_in_progress = FALSE; - return 0; + if ((scp == sc->old_scp) && (scp->status & SWITCH_WAIT_REL)) { + sc->old_scp->status &= ~SWITCH_WAIT_REL; + sc->switch_in_progress = 0; + DPRINTF(5, ("sc%d: VT_FALSE\n", sc->unit)); + error = 0; } - return EINVAL; + break; case VT_TRUE: /* user has released screen, go on */ - if (scp == old_scp && (scp->status & SWITCH_WAIT_REL)) { + if ((scp == sc->old_scp) && (scp->status & SWITCH_WAIT_REL)) { scp->status &= ~SWITCH_WAIT_REL; - exchange_scr(); - if (new_scp->smode.mode == VT_PROCESS) { - new_scp->status |= SWITCH_WAIT_ACQ; - psignal(new_scp->proc, new_scp->smode.acqsig); - } - else - switch_in_progress = FALSE; - return 0; + s = do_switch_scr(sc, s); + DPRINTF(5, ("sc%d: VT_TRUE\n", sc->unit)); + error = 0; } - return EINVAL; + break; case VT_ACKACQ: /* acquire acknowledged, switch completed */ - if (scp == new_scp && (scp->status & SWITCH_WAIT_ACQ)) { + if ((scp == sc->new_scp) && (scp->status & SWITCH_WAIT_ACQ)) { scp->status &= ~SWITCH_WAIT_ACQ; - switch_in_progress = FALSE; - return 0; + sc->switch_in_progress = 0; + DPRINTF(5, ("sc%d: VT_ACKACQ\n", sc->unit)); + error = 0; } - return EINVAL; + break; default: - return EINVAL; + break; } - /* NOT REACHED */ + splx(s); + return error; case VT_OPENQRY: /* return free virtual console */ - for (i = 0; i < MAXCONS; i++) { - tp = VIRTUAL_TTY(i); + for (i = sc->first_vty; i < sc->first_vty + sc->vtys; i++) { + tp = VIRTUAL_TTY(sc, i); if (!(tp->t_state & TS_ISOPEN)) { *(int *)data = i + 1; return 0; @@ -1518,32 +1005,33 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) case VT_ACTIVATE: /* switch to screen *data */ s = spltty(); - sc_clean_up(cur_console); + sc_clean_up(sc->cur_scp); splx(s); - return switch_scr(scp, *(int *)data - 1); + return switch_scr(sc, *(int *)data - 1); case VT_WAITACTIVE: /* wait for switch to occur */ - if (*(int *)data > MAXCONS || *(int *)data < 0) + if ((*(int *)data >= sc->first_vty + sc->vtys) + || (*(int *)data < sc->first_vty)) return EINVAL; s = spltty(); - error = sc_clean_up(cur_console); + error = sc_clean_up(sc->cur_scp); splx(s); if (error) return error; - if (minor(dev) == *(int *)data - 1) + if (*(int *)data != 0) + scp = sc->console[*(int *)data - 1 - sc->first_vty]; + if (scp == scp->sc->cur_scp) return 0; - if (*(int *)data == 0) { - if (scp == cur_console) - return 0; - } - else - scp = console[*(int *)data - 1]; while ((error=tsleep((caddr_t)&scp->smode, PZERO|PCATCH, "waitvt", 0)) == ERESTART) ; return error; - case VT_GETACTIVE: - *(int *)data = get_scr_num()+1; + case VT_GETACTIVE: /* get active vty # */ + *(int *)data = sc->cur_scp->index + 1; + return 0; + + case VT_GETINDEX: /* get this vty # */ + *(int *)data = scp->index + 1; return 0; case KDENABIO: /* allow io operations */ @@ -1568,18 +1056,18 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) return EINVAL; scp->status &= ~LOCK_MASK; scp->status |= *(int *)data; - if (scp == cur_console) - update_kbd_state(scp->status, LOCK_MASK); + if (scp == sc->cur_scp) + update_kbd_state(scp, scp->status, LOCK_MASK); return 0; case KDGKBSTATE: /* get keyboard state (locks) */ - if (scp == cur_console) + if (scp == sc->cur_scp) save_kbd_state(scp); *(int *)data = scp->status & LOCK_MASK; return 0; case KDSETREPEAT: /* set keyboard repeat & delay rates (new) */ - error = kbd_ioctl(kbd, cmd, data); + error = kbd_ioctl(sc->kbd, cmd, data); if (error == ENOIOCTL) error = ENODEV; return error; @@ -1587,7 +1075,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) case KDSETRAD: /* set keyboard repeat & delay rates (old) */ if (*(int *)data & ~0x7f) return EINVAL; - error = kbd_ioctl(kbd, cmd, data); + error = kbd_ioctl(sc->kbd, cmd, data); if (error == ENOIOCTL) error = ENODEV; return error; @@ -1598,8 +1086,8 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) case K_RAW: /* switch to RAW scancode mode */ case K_CODE: /* switch to CODE mode */ scp->kbd_mode = *(int *)data; - if (scp == cur_console) - kbd_ioctl(kbd, cmd, data); + if (scp == sc->cur_scp) + kbd_ioctl(sc->kbd, cmd, data); return 0; default: return EINVAL; @@ -1611,7 +1099,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) return 0; case KDGKBINFO: - error = kbd_ioctl(kbd, cmd, data); + error = kbd_ioctl(sc->kbd, cmd, data); if (error == ENOIOCTL) error = ENODEV; return error; @@ -1625,33 +1113,16 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) return 0; case KIOCSOUND: /* make tone (*data) hz */ -#ifdef __i386__ - if (scp == cur_console) { - if (*(int*)data) { - int pitch = timer_freq / *(int*)data; - - /* set command for counter 2, 2 byte write */ - if (acquire_timer2(TIMER_16BIT|TIMER_SQWAVE)) - return EBUSY; - - /* set pitch */ - outb(TIMER_CNTR2, pitch); - outb(TIMER_CNTR2, (pitch>>8)); - - /* enable counter 2 output to speaker */ - outb(IO_PPI, inb(IO_PPI) | 3); - } - else { - /* disable counter 2 output to speaker */ - outb(IO_PPI, inb(IO_PPI) & 0xFC); - release_timer2(); - } + if (scp == sc->cur_scp) { + if (*(int *)data) + return sc_tone(*(int *)data); + else + return sc_tone(0); } -#endif /* __i386__ */ return 0; case KDGKBTYPE: /* get keyboard type */ - error = kbd_ioctl(kbd, cmd, data); + error = kbd_ioctl(sc->kbd, cmd, data); if (error == ENOIOCTL) { /* always return something? XXX */ *(int *)data = 0; @@ -1663,12 +1134,12 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) return EINVAL; scp->status &= ~LED_MASK; scp->status |= *(int *)data; - if (scp == cur_console) - update_kbd_leds(scp->status); + if (scp == sc->cur_scp) + update_kbd_leds(scp, scp->status); return 0; case KDGETLED: /* get keyboard LED status */ - if (scp == cur_console) + if (scp == sc->cur_scp) save_kbd_state(scp); *(int *)data = scp->status & LED_MASK; return 0; @@ -1684,19 +1155,21 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) return EINVAL; } error = 0; - if (kbd != newkbd) { + if (sc->kbd != newkbd) { i = kbd_allocate(newkbd->kb_name, newkbd->kb_unit, - (void *)&keyboard, sckbdevent, NULL); + (void *)&sc->keyboard, sckbdevent, sc); /* i == newkbd->kb_index */ if (i >= 0) { - if (kbd != NULL) { - save_kbd_state(cur_console); - kbd_release(kbd, (void *)&keyboard); + if (sc->kbd != NULL) { + save_kbd_state(sc->cur_scp); + kbd_release(sc->kbd, (void *)&sc->keyboard); } - kbd = kbd_get_keyboard(i); /* kbd == newkbd */ - keyboard = i; - kbd_ioctl(kbd, KDSKBMODE, (caddr_t)&cur_console->kbd_mode); - update_kbd_state(cur_console->status, LOCK_MASK); + sc->kbd = kbd_get_keyboard(i); /* sc->kbd == newkbd */ + sc->keyboard = i; + kbd_ioctl(sc->kbd, KDSKBMODE, + (caddr_t)&sc->cur_scp->kbd_mode); + update_kbd_state(sc->cur_scp, sc->cur_scp->status, + LOCK_MASK); } else { error = EPERM; /* XXX */ } @@ -1708,25 +1181,26 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) case CONS_RELKBD: /* release the current keyboard */ s = spltty(); error = 0; - if (kbd != NULL) { - save_kbd_state(cur_console); - error = kbd_release(kbd, (void *)&keyboard); + if (sc->kbd != NULL) { + save_kbd_state(sc->cur_scp); + error = kbd_release(sc->kbd, (void *)&sc->keyboard); if (error == 0) { - kbd = NULL; - keyboard = -1; + sc->kbd = NULL; + sc->keyboard = -1; } } splx(s); return error; case GIO_SCRNMAP: /* get output translation table */ - bcopy(&scr_map, data, sizeof(scr_map)); + bcopy(&sc->scr_map, data, sizeof(sc->scr_map)); return 0; case PIO_SCRNMAP: /* set output translation table */ - bcopy(data, &scr_map, sizeof(scr_map)); - for (i=0; i<sizeof(scr_map); i++) - scr_rmap[scr_map[i]] = i; + bcopy(data, &sc->scr_map, sizeof(sc->scr_map)); + for (i=0; i<sizeof(sc->scr_map); i++) { + sc->scr_rmap[sc->scr_map[i]] = i; + } return 0; case GIO_KEYMAP: /* get keyboard translation table */ @@ -1735,83 +1209,89 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) case PIO_DEADKEYMAP: /* set accent key translation table */ case GETFKEY: /* get function key string */ case SETFKEY: /* set function key string */ - error = kbd_ioctl(kbd, cmd, data); + error = kbd_ioctl(sc->kbd, cmd, data); if (error == ENOIOCTL) error = ENODEV; return error; +#ifndef SC_NO_FONT_LOADING + case PIO_FONT8x8: /* set 8x8 dot font */ - if (!ISFONTAVAIL(scp->adp->va_flags)) + if (!ISFONTAVAIL(sc->adp->va_flags)) return ENXIO; - bcopy(data, font_8, 8*256); - fonts_loaded |= FONT_8; + bcopy(data, sc->font_8, 8*256); + sc->fonts_loaded |= FONT_8; /* * FONT KLUDGE * Always use the font page #0. XXX * Don't load if the current font size is not 8x8. */ - if (ISTEXTSC(cur_console) && (cur_console->font_size < 14)) - copy_font(cur_console, LOAD, 8, font_8); + if (ISTEXTSC(sc->cur_scp) && (sc->cur_scp->font_size < 14)) + copy_font(sc->cur_scp, LOAD, 8, sc->font_8); return 0; case GIO_FONT8x8: /* get 8x8 dot font */ - if (!ISFONTAVAIL(scp->adp->va_flags)) + if (!ISFONTAVAIL(sc->adp->va_flags)) return ENXIO; - if (fonts_loaded & FONT_8) { - bcopy(font_8, data, 8*256); + if (sc->fonts_loaded & FONT_8) { + bcopy(sc->font_8, data, 8*256); return 0; } else return ENXIO; case PIO_FONT8x14: /* set 8x14 dot font */ - if (!ISFONTAVAIL(scp->adp->va_flags)) + if (!ISFONTAVAIL(sc->adp->va_flags)) return ENXIO; - bcopy(data, font_14, 14*256); - fonts_loaded |= FONT_14; + bcopy(data, sc->font_14, 14*256); + sc->fonts_loaded |= FONT_14; /* * FONT KLUDGE * Always use the font page #0. XXX * Don't load if the current font size is not 8x14. */ - if (ISTEXTSC(cur_console) - && (cur_console->font_size >= 14) && (cur_console->font_size < 16)) - copy_font(cur_console, LOAD, 14, font_14); + if (ISTEXTSC(sc->cur_scp) + && (sc->cur_scp->font_size >= 14) + && (sc->cur_scp->font_size < 16)) + copy_font(sc->cur_scp, LOAD, 14, sc->font_14); return 0; case GIO_FONT8x14: /* get 8x14 dot font */ - if (!ISFONTAVAIL(scp->adp->va_flags)) + if (!ISFONTAVAIL(sc->adp->va_flags)) return ENXIO; - if (fonts_loaded & FONT_14) { - bcopy(font_14, data, 14*256); + if (sc->fonts_loaded & FONT_14) { + bcopy(sc->font_14, data, 14*256); return 0; } else return ENXIO; case PIO_FONT8x16: /* set 8x16 dot font */ - if (!ISFONTAVAIL(scp->adp->va_flags)) + if (!ISFONTAVAIL(sc->adp->va_flags)) return ENXIO; - bcopy(data, font_16, 16*256); - fonts_loaded |= FONT_16; + bcopy(data, sc->font_16, 16*256); + sc->fonts_loaded |= FONT_16; /* * FONT KLUDGE * Always use the font page #0. XXX * Don't load if the current font size is not 8x16. */ - if (ISTEXTSC(cur_console) && (cur_console->font_size >= 16)) - copy_font(cur_console, LOAD, 16, font_16); + if (ISTEXTSC(sc->cur_scp) && (sc->cur_scp->font_size >= 16)) + copy_font(sc->cur_scp, LOAD, 16, sc->font_16); return 0; case GIO_FONT8x16: /* get 8x16 dot font */ - if (!ISFONTAVAIL(scp->adp->va_flags)) + if (!ISFONTAVAIL(sc->adp->va_flags)) return ENXIO; - if (fonts_loaded & FONT_16) { - bcopy(font_16, data, 16*256); + if (sc->fonts_loaded & FONT_16) { + bcopy(sc->font_16, data, 16*256); return 0; } else return ENXIO; + +#endif /* SC_NO_FONT_LOADING */ + default: break; } @@ -1833,8 +1313,8 @@ scstart(struct tty *tp) u_char buf[PCBURST]; scr_stat *scp = sc_get_scr_stat(tp->t_dev); - if (scp->status & SLKED || blink_in_progress) - return; /* XXX who repeats the call when the above flags are cleared? */ + if (scp->status & SLKED || scp->sc->blink_in_progress) + return; s = spltty(); if (!(tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP))) { tp->t_state |= TS_BUSY; @@ -1871,105 +1351,141 @@ scmousestart(struct tty *tp) splx(s); } -#if __i386__ - -/* XXX kludge! */ -extern struct isa_driver scdriver; - static void sccnprobe(struct consdev *cp) { -#if 0 - struct isa_device *dvp; +#if __i386__ + int unit; + int flags; - /* - * Take control if we are the highest priority enabled display device. - */ - dvp = find_display(); - if (dvp == NULL || dvp->id_driver != &scdriver) { - cp->cn_pri = CN_DEAD; - return; - } + cp->cn_pri = sc_get_cons_priority(&unit, &flags); - if (!scvidprobe(dvp->id_unit, dvp->id_flags, TRUE)) { - cp->cn_pri = CN_DEAD; - return; - } - sckbdprobe(dvp->id_unit, dvp->id_flags, TRUE); -#else - if (!scvidprobe(0, 0, TRUE)) { + /* a video card is always required */ + if (!scvidprobe(unit, flags, TRUE)) cp->cn_pri = CN_DEAD; + + /* syscons will become console even when there is no keyboard */ + sckbdprobe(unit, flags, TRUE); + + if (cp->cn_pri == CN_DEAD) return; - } - sckbdprobe(0, 0, TRUE); -#endif /* initialize required fields */ - cp->cn_dev = makedev(CDEV_MAJOR, SC_CONSOLE); - cp->cn_pri = CN_INTERNAL; + cp->cn_dev = makedev(CDEV_MAJOR, SC_CONSOLECTL); +#endif /* __i386__ */ + +#if __alpha__ + /* + * alpha use sccnattach() rather than cnprobe()/cninit()/cnterm() + * interface to install the console. Always return CN_DEAD from + * here. + */ + cp->cn_pri = CN_DEAD; +#endif /* __alpha__ */ } static void sccninit(struct consdev *cp) { - scinit(); +#if __i386__ + int unit; + int flags; + + sc_get_cons_priority(&unit, &flags); + scinit(unit, flags | SC_KERNEL_CONSOLE); + sc_console_unit = unit; + sc_console = sc_get_softc(unit, SC_KERNEL_CONSOLE)->console[0]; +#endif /* __i386__ */ + +#if __alpha__ + /* SHOULDN'T REACH HERE */ +#endif /* __alpha__ */ +} + +static void +sccnterm(struct consdev *cp) +{ + /* we are not the kernel console any more, release everything */ + + if (sc_console_unit < 0) + return; /* shouldn't happen */ + +#if __i386__ +#if 0 /* XXX */ + sc_clear_screen(sc_console); + sccnupdate(sc_console); +#endif + scterm(sc_console_unit, SC_KERNEL_CONSOLE); + sc_console_unit = -1; + sc_console = NULL; +#endif /* __i386__ */ + +#if __alpha__ + /* do nothing XXX */ +#endif /* __alpha__ */ } -#else /* !__i386__ */ +#ifdef __alpha__ extern struct consdev *cn_tab; void sccnattach(void) { - if (!scvidprobe(0, 0, TRUE) || !sckbdprobe(0, 0, TRUE)) { + static struct consdev consdev; + int unit; + int flags; + + bcopy(&sc_consdev, &consdev, sizeof(sc_consdev)); + consdev.cn_pri = sc_get_cons_priority(&unit, &flags); + + /* a video card is always required */ + if (!scvidprobe(unit, flags, TRUE)) + consdev.cn_pri = CN_DEAD; + + /* alpha doesn't allow the console being without a keyboard... Why? */ + if (!sckbdprobe(unit, flags, TRUE)) + consdev.cn_pri = CN_DEAD; + + if (consdev.cn_pri == CN_DEAD) return; - } - scinit(); - sc_cons.cn_dev = makedev(CDEV_MAJOR, 0); - cn_tab = &sc_cons; + scinit(unit, flags | SC_KERNEL_CONSOLE); + sc_console_unit = unit; + sc_console = sc_get_softc(unit, SC_KERNEL_CONSOLE)->console[0]; + consdev.cn_dev = makedev(CDEV_MAJOR, 0); + cn_tab = &consdev; } -#endif /* __i386__ */ +#endif /* __alpha__ */ static void sccnputc(dev_t dev, int c) { u_char buf[1]; - scr_stat *scp = console[0]; + scr_stat *scp = sc_console; term_stat save = scp->term; - u_short *p; int s; - int i; - if (scp == cur_console && scp->status & SLKED) { + /* assert(sc_console != NULL) */ + +#ifndef SC_NO_HISTORY + if (scp == scp->sc->cur_scp && scp->status & SLKED) { scp->status &= ~SLKED; - update_kbd_state(scp->status, SLKED); - if (cur_console->status & BUFFER_SAVED) { - p = cur_console->history_save; - for (i = 0; i < cur_console->ysize; ++i) { - bcopy(p, cur_console->scr_buf + (cur_console->xsize*i), - cur_console->xsize*sizeof(u_short)); - p += cur_console->xsize; - if (p + cur_console->xsize - > cur_console->history + cur_console->history_size) - p = cur_console->history; - } - cur_console->status &= ~BUFFER_SAVED; - cur_console->history_head = cur_console->history_save; - cur_console->status |= CURSOR_ENABLED; - mark_all(cur_console); + update_kbd_state(scp, scp->status, SLKED); + if (scp->status & BUFFER_SAVED) { + if (!sc_hist_restore(scp)) + sc_remove_cutmarking(scp); + scp->status &= ~BUFFER_SAVED; + scp->status |= CURSOR_ENABLED; + draw_cursor_image(scp); } -#if 1 /* XXX */ - scstart(VIRTUAL_TTY(get_scr_num())); -#endif + scstart(VIRTUAL_TTY(scp->sc, scp->index)); } +#endif /* !SC_NO_HISTORY */ scp->term = kernel_console; current_default = &kernel_default; - if (scp == cur_console && !ISGRAPHSC(scp)) - remove_cursor_image(scp); buf[0] = c; ansi_put(scp, buf, 1); kernel_console = scp->term; @@ -1996,18 +1512,30 @@ sccncheckc(dev_t dev) static int sccngetch(int flags) { + static struct fkeytab fkey; + static int fkeycp; + scr_stat *scp; + u_char *p; int cur_mode; int s = spltty(); /* block sckbdevent and scrn_timer while we poll */ int c; + /* assert(sc_console != NULL) */ + /* * Stop the screen saver and update the screen if necessary. * What if we have been running in the screen saver code... XXX */ sc_touch_scrn_saver(); - sccnupdate(cur_console); + scp = sc_console->sc->cur_scp; /* XXX */ + sccnupdate(scp); + + if (fkeycp < fkey.len) { + splx(s); + return fkey.str[fkeycp++]; + } - if (kbd == NULL) { + if (scp->sc->kbd == NULL) { splx(s); return -1; } @@ -2016,26 +1544,33 @@ sccngetch(int flags) * Make sure the keyboard is accessible even when the kbd device * driver is disabled. */ - kbd_enable(kbd); + kbd_enable(scp->sc->kbd); /* we shall always use the keyboard in the XLATE mode here */ - cur_mode = cur_console->kbd_mode; - cur_console->kbd_mode = K_XLATE; - kbd_ioctl(kbd, KDSKBMODE, (caddr_t)&cur_console->kbd_mode); + cur_mode = scp->kbd_mode; + scp->kbd_mode = K_XLATE; + kbd_ioctl(scp->sc->kbd, KDSKBMODE, (caddr_t)&scp->kbd_mode); - kbd_poll(kbd, TRUE); - c = scgetc(kbd, SCGETC_CN | flags); - kbd_poll(kbd, FALSE); + kbd_poll(scp->sc->kbd, TRUE); + c = scgetc(scp->sc, SCGETC_CN | flags); + kbd_poll(scp->sc->kbd, FALSE); - cur_console->kbd_mode = cur_mode; - kbd_ioctl(kbd, KDSKBMODE, (caddr_t)&cur_console->kbd_mode); - kbd_disable(kbd); + scp->kbd_mode = cur_mode; + kbd_ioctl(scp->sc->kbd, KDSKBMODE, (caddr_t)&scp->kbd_mode); + kbd_disable(scp->sc->kbd); splx(s); switch (KEYFLAGS(c)) { case 0: /* normal char */ return KEYCHAR(c); case FKEY: /* function key */ + p = kbd_get_fkeystr(scp->sc->kbd, KEYCHAR(c), (size_t *)&fkeycp); + fkey.len = fkeycp; + if ((p != NULL) && (fkey.len > 0)) { + bcopy(p, fkey.str, fkey.len); + fkeycp = 1; + return fkey.str[0]; + } return c; /* XXX */ case NOKEY: case ERRKEY: @@ -2050,23 +1585,30 @@ sccnupdate(scr_stat *scp) { /* this is a cut-down version of scrn_timer()... */ - if (font_loading_in_progress) + if (scp->sc->font_loading_in_progress || scp->sc->videoio_in_progress) return; - if (panicstr || shutdown_in_progress) { + if (debugger || panicstr || shutdown_in_progress) { sc_touch_scrn_saver(); - } else if (scp != cur_console) { + } else if (scp != scp->sc->cur_scp) { return; } if (!run_scrn_saver) - scrn_idle = FALSE; - if ((saver_mode != CONS_LKM_SAVER) || !scrn_idle) - if (scrn_blanked) - stop_scrn_saver(current_saver); + scp->sc->flags &= ~SC_SCRN_IDLE; +#if NSPLASH > 0 + if ((saver_mode != CONS_LKM_SAVER) || !(scp->sc->flags & SC_SCRN_IDLE)) + if (scp->sc->flags & SC_SCRN_BLANKED) + stop_scrn_saver(scp->sc, current_saver); +#endif /* NSPLASH */ - if (scp != cur_console || blink_in_progress || switch_in_progress) + if (scp != scp->sc->cur_scp || scp->sc->blink_in_progress + || scp->sc->switch_in_progress) return; + /* + * FIXME: unlike scrn_timer(), we call scrn_update() from here even + * when write_in_progress is non-zero. XXX + */ if (!ISGRAPHSC(scp) && !(scp->status & SAVER_RUNNING)) scrn_update(scp, TRUE); @@ -2075,23 +1617,22 @@ sccnupdate(scr_stat *scp) scr_stat *sc_get_scr_stat(dev_t dev) { - int unit = minor(dev); + sc_softc_t *sc; + int vty = SC_VTY(dev); + int unit; - if (unit == SC_CONSOLE) - return console[0]; - if (unit >= MAXCONS || unit < 0) - return(NULL); - return console[unit]; -} - -static int -get_scr_num() -{ - int i = 0; + if (vty < 0) + return NULL; + if (vty == SC_CONSOLECTL) + return sc_console; - while ((i < MAXCONS) && (cur_console != console[i])) - i++; - return i < MAXCONS ? i : 0; + unit = scdevtounit(dev); + sc = sc_get_softc(unit, (sc_console_unit == unit) ? SC_KERNEL_CONSOLE : 0); + if (sc == NULL) + return NULL; + if ((sc->first_vty <= vty) && (vty < sc->first_vty + sc->vtys)) + return sc->console[vty - sc->first_vty]; + return NULL; } static void @@ -2099,113 +1640,187 @@ scrn_timer(void *arg) { static int kbd_interval = 0; struct timeval tv; + sc_softc_t *sc; scr_stat *scp; + int again; int s; - /* don't do anything when we are touching font */ - if (font_loading_in_progress) { - if (arg) - timeout(scrn_timer, (void *)TRUE, hz / 10); + again = (arg != NULL); + if (arg != NULL) + sc = (sc_softc_t *)arg; + else if (sc_console != NULL) + sc = sc_console->sc; + else + return; + + /* don't do anything when we are performing some I/O operations */ + if (sc->font_loading_in_progress || sc->videoio_in_progress) { + if (again) + timeout(scrn_timer, sc, hz / 10); return; } s = spltty(); - if ((kbd == NULL) && (sc_flags & AUTODETECT_KBD)) { + if ((sc->kbd == NULL) && (sc->config & SC_AUTODETECT_KBD)) { /* try to allocate a keyboard automatically */ if (++kbd_interval >= 25) { - keyboard = kbd_allocate("*", -1, (void *)&keyboard, - sckbdevent, NULL); - if (keyboard >= 0) { - kbd = kbd_get_keyboard(keyboard); - kbd_ioctl(kbd, KDSKBMODE, (caddr_t)&cur_console->kbd_mode); - update_kbd_state(cur_console->status, LOCK_MASK); + sc->keyboard = kbd_allocate("*", -1, (void *)&sc->keyboard, + sckbdevent, sc); + if (sc->keyboard >= 0) { + sc->kbd = kbd_get_keyboard(sc->keyboard); + kbd_ioctl(sc->kbd, KDSKBMODE, + (caddr_t)&sc->cur_scp->kbd_mode); + update_kbd_state(sc->cur_scp, sc->cur_scp->status, + LOCK_MASK); } kbd_interval = 0; } } + /* find the vty to update */ + scp = sc->cur_scp; + /* should we stop the screen saver? */ getmicrouptime(&tv); - if (panicstr || shutdown_in_progress) + if (debugger || panicstr || shutdown_in_progress) sc_touch_scrn_saver(); if (run_scrn_saver) { - scrn_idle = (tv.tv_sec > scrn_time_stamp + scrn_blank_time); + if (tv.tv_sec > sc->scrn_time_stamp + scrn_blank_time) + sc->flags |= SC_SCRN_IDLE; + else + sc->flags &= ~SC_SCRN_IDLE; } else { - scrn_time_stamp = tv.tv_sec; - scrn_idle = FALSE; + sc->scrn_time_stamp = tv.tv_sec; + sc->flags &= ~SC_SCRN_IDLE; if (scrn_blank_time > 0) run_scrn_saver = TRUE; } - if ((saver_mode != CONS_LKM_SAVER) || !scrn_idle) - if (scrn_blanked) - stop_scrn_saver(current_saver); +#if NSPLASH > 0 + if ((saver_mode != CONS_LKM_SAVER) || !(sc->flags & SC_SCRN_IDLE)) + if (sc->flags & SC_SCRN_BLANKED) + stop_scrn_saver(sc, current_saver); +#endif /* NSPLASH */ /* should we just return ? */ - if (blink_in_progress || switch_in_progress) { - if (arg) - timeout(scrn_timer, (void *)TRUE, hz / 10); + if (sc->blink_in_progress || sc->switch_in_progress + || sc->write_in_progress) { + if (again) + timeout(scrn_timer, sc, hz / 10); splx(s); return; } /* Update the screen */ - scp = cur_console; + scp = sc->cur_scp; /* cur_scp may have changed... */ if (!ISGRAPHSC(scp) && !(scp->status & SAVER_RUNNING)) scrn_update(scp, TRUE); +#if NSPLASH > 0 /* should we activate the screen saver? */ - if ((saver_mode == CONS_LKM_SAVER) && scrn_idle) - if (!ISGRAPHSC(scp) || scrn_blanked) - (*current_saver)(TRUE); + if ((saver_mode == CONS_LKM_SAVER) && (sc->flags & SC_SCRN_IDLE)) + if (!ISGRAPHSC(scp) || (sc->flags & SC_SCRN_BLANKED)) + (*current_saver)(sc, TRUE); +#endif /* NSPLASH */ - if (arg) - timeout(scrn_timer, (void *)TRUE, hz / 25); + if (again) + timeout(scrn_timer, sc, hz / 25); splx(s); } +static int +and_region(int *s1, int *e1, int s2, int e2) +{ + if (*e1 < s2 || e2 < *s1) + return FALSE; + *s1 = imax(*s1, s2); + *e1 = imin(*e1, e2); + return TRUE; +} + static void scrn_update(scr_stat *scp, int show_cursor) { + int start; + int end; + int s; + int e; + + /* assert(scp == scp->sc->cur_scp) */ + + ++scp->sc->videoio_in_progress; + +#ifndef SC_NO_CUTPASTE + /* remove the previous mouse pointer image if necessary */ + if ((scp->status & (MOUSE_VISIBLE | MOUSE_MOVED)) + == (MOUSE_VISIBLE | MOUSE_MOVED)) { + /* FIXME: I don't like this... XXX */ + sc_remove_mouse_image(scp); + if (scp->end >= scp->xsize*scp->ysize) + scp->end = scp->xsize*scp->ysize - 1; + } +#endif /* !SC_NO_CUTPASTE */ + +#if 1 + /* debug: XXX */ + if (scp->end >= scp->xsize*scp->ysize) { + printf("scrn_update(): scp->end %d > size_of_screen!!\n", scp->end); + scp->end = scp->xsize*scp->ysize - 1; + } + if (scp->start < 0) { + printf("scrn_update(): scp->start %d < 0\n", scp->start); + scp->start = 0; + } +#endif + /* update screen image */ - if (scp->start <= scp->end) - sc_bcopy(scp, scp->scr_buf, scp->start, scp->end, 0); + if (scp->start <= scp->end) { + if (scp->mouse_cut_end >= 0) { + /* there is a marked region for cut & paste */ + if (scp->mouse_cut_start <= scp->mouse_cut_end) { + start = scp->mouse_cut_start; + end = scp->mouse_cut_end; + } else { + start = scp->mouse_cut_end; + end = scp->mouse_cut_start - 1; + } + s = start; + e = end; + /* does the cut-mark region overlap with the update region? */ + if (and_region(&s, &e, scp->start, scp->end)) { + (*scp->rndr->draw)(scp, s, e - s + 1, TRUE); + s = 0; + e = start - 1; + if (and_region(&s, &e, scp->start, scp->end)) + (*scp->rndr->draw)(scp, s, e - s + 1, FALSE); + s = end + 1; + e = scp->xsize*scp->ysize - 1; + if (and_region(&s, &e, scp->start, scp->end)) + (*scp->rndr->draw)(scp, s, e - s + 1, FALSE); + } else { + (*scp->rndr->draw)(scp, scp->start, + scp->end - scp->start + 1, FALSE); + } + } else { + (*scp->rndr->draw)(scp, scp->start, + scp->end - scp->start + 1, FALSE); + } + } /* we are not to show the cursor and the mouse pointer... */ if (!show_cursor) { scp->end = 0; scp->start = scp->xsize*scp->ysize - 1; + --scp->sc->videoio_in_progress; return; } - /* update "pseudo" mouse pointer image */ - if (scp->status & MOUSE_VISIBLE) { - /* did mouse move since last time ? */ - if (scp->status & MOUSE_MOVED) { - /* do we need to remove old mouse pointer image ? */ - if (scp->mouse_cut_start != NULL || - (scp->mouse_pos-scp->scr_buf) <= scp->start || - (scp->mouse_pos+scp->xsize + 1 - scp->scr_buf) >= scp->end) { - remove_mouse_image(scp); - } - scp->status &= ~MOUSE_MOVED; - draw_mouse_image(scp); - } - else { - /* mouse didn't move, has it been overwritten ? */ - if ((scp->mouse_pos+scp->xsize + 1 - scp->scr_buf) >= scp->start && - (scp->mouse_pos - scp->scr_buf) <= scp->end) { - draw_mouse_image(scp); - } - } - } - /* update cursor image */ if (scp->status & CURSOR_ENABLED) { /* did cursor move since last time ? */ if (scp->cursor_pos != scp->cursor_oldpos) { /* do we need to remove old cursor image ? */ - if ((scp->cursor_oldpos - scp->scr_buf) < scp->start || - ((scp->cursor_oldpos - scp->scr_buf) > scp->end)) { + if (scp->cursor_oldpos < scp->start || + scp->cursor_oldpos > scp->end) { remove_cursor_image(scp); } scp->cursor_oldpos = scp->cursor_pos; @@ -2213,40 +1828,64 @@ scrn_update(scr_stat *scp, int show_cursor) } else { /* cursor didn't move, has it been overwritten ? */ - if (scp->cursor_pos - scp->scr_buf >= scp->start && - scp->cursor_pos - scp->scr_buf <= scp->end) { + if (scp->cursor_pos >= scp->start && scp->cursor_pos <= scp->end) { draw_cursor_image(scp); } else { /* if its a blinking cursor, we may have to update it */ - if (sc_flags & BLINK_CURSOR) - draw_cursor_image(scp); + if (scp->sc->flags & SC_BLINK_CURSOR) + (*scp->rndr->blink_cursor)(scp, scp->cursor_pos, + sc_inside_cutmark(scp, + scp->cursor_pos)); } } - blinkrate++; } - if (scp->mouse_cut_start != NULL) - draw_cutmarking(scp); +#ifndef SC_NO_CUTPASTE + /* update "pseudo" mouse pointer image */ + if (scp->status & MOUSE_VISIBLE) { + /* did mouse move since last time ? */ + if (scp->status & MOUSE_MOVED) { + /* the previous pointer image has been removed, see above */ + scp->status &= ~MOUSE_MOVED; + sc_draw_mouse_image(scp); + } else { + /* mouse didn't move, has it been overwritten ? */ + if (scp->mouse_pos + scp->xsize + 1 >= scp->start && + scp->mouse_pos <= scp->end) { + sc_draw_mouse_image(scp); + } else if (scp->cursor_pos == scp->mouse_pos || + scp->cursor_pos == scp->mouse_pos + 1 || + scp->cursor_pos == scp->mouse_pos + scp->xsize || + scp->cursor_pos == scp->mouse_pos + scp->xsize + 1) { + sc_draw_mouse_image(scp); + } + } + } +#endif /* SC_NO_CUTPASTE */ scp->end = 0; scp->start = scp->xsize*scp->ysize - 1; + + --scp->sc->videoio_in_progress; } #if NSPLASH > 0 - static int -scsplash_callback(int event) +scsplash_callback(int event, void *arg) { + sc_softc_t *sc; int error; + sc = (sc_softc_t *)arg; + switch (event) { case SPLASH_INIT: - scrn_saver_failed = FALSE; if (add_scrn_saver(scsplash_saver) == 0) { + sc->flags &= ~SC_SAVER_FAILED; run_scrn_saver = TRUE; if (cold && !(boothowto & (RB_VERBOSE | RB_CONFIG))) { scsplash_stick(TRUE); - (*current_saver)(TRUE); + (*current_saver)(sc, TRUE); } } return 0; @@ -2266,7 +1905,7 @@ scsplash_callback(int event) } static void -scsplash_saver(int show) +scsplash_saver(sc_softc_t *sc, int show) { static int busy = FALSE; scr_stat *scp; @@ -2275,38 +1914,37 @@ scsplash_saver(int show) return; busy = TRUE; - scp = cur_console; + scp = sc->cur_scp; if (show) { - if (!scrn_saver_failed) { - if (!scrn_blanked) + if (!(sc->flags & SC_SAVER_FAILED)) { + if (!(sc->flags & SC_SCRN_BLANKED)) set_scrn_saver_mode(scp, -1, NULL, 0); - switch (splash(scp->adp, TRUE)) { + switch (splash(sc->adp, TRUE)) { case 0: /* succeeded */ - scrn_blanked = TRUE; break; case EAGAIN: /* try later */ restore_scrn_saver_mode(scp, FALSE); + sc_touch_scrn_saver(); /* XXX */ break; default: - scrn_saver_failed = TRUE; + sc->flags |= SC_SAVER_FAILED; scsplash_stick(FALSE); - printf("scsplash_saver(): failed to put up the image\n"); restore_scrn_saver_mode(scp, TRUE); + printf("scsplash_saver(): failed to put up the image\n"); break; } } } else if (!sticky_splash) { - if (scrn_blanked && (splash(scp->adp, FALSE) == 0)) { + if ((sc->flags & SC_SCRN_BLANKED) && (splash(sc->adp, FALSE) == 0)) restore_scrn_saver_mode(scp, TRUE); - scrn_blanked = FALSE; - } } busy = FALSE; } static int -add_scrn_saver(void (*this_saver)(int)) +add_scrn_saver(void (*this_saver)(sc_softc_t *, int)) { +#if 0 int error; if (current_saver != none_saver) { @@ -2314,6 +1952,9 @@ add_scrn_saver(void (*this_saver)(int)) if (error) return error; } +#endif + if (current_saver != none_saver) + return EBUSY; run_scrn_saver = FALSE; saver_mode = CONS_LKM_SAVER; @@ -2322,11 +1963,12 @@ add_scrn_saver(void (*this_saver)(int)) } static int -remove_scrn_saver(void (*this_saver)(int)) +remove_scrn_saver(void (*this_saver)(sc_softc_t *, int)) { if (current_saver != this_saver) return EINVAL; +#if 0 /* * In order to prevent `current_saver' from being called by * the timeout routine `scrn_timer()' while we manipulate @@ -2336,8 +1978,15 @@ remove_scrn_saver(void (*this_saver)(int)) current_saver = none_saver; if (scrn_blanked) stop_scrn_saver(this_saver); +#endif + + /* unblank all blanked screens */ + wait_scrn_saver_stop(NULL); + if (scrn_blanked) + return EBUSY; - return (scrn_blanked ? EBUSY : 0); + current_saver = none_saver; + return 0; } static int @@ -2345,21 +1994,27 @@ set_scrn_saver_mode(scr_stat *scp, int mode, u_char *pal, int border) { int s; - /* assert(scp == cur_console) */ + /* assert(scp == scp->sc->cur_scp) */ s = spltty(); + if (!ISGRAPHSC(scp)) + remove_cursor_image(scp); scp->splash_save_mode = scp->mode; scp->splash_save_status = scp->status & (GRAPHICS_MODE | PIXEL_MODE); scp->status &= ~(GRAPHICS_MODE | PIXEL_MODE); scp->status |= (UNKNOWN_MODE | SAVER_RUNNING); + scp->sc->flags |= SC_SCRN_BLANKED; + ++scrn_blanked; splx(s); if (mode < 0) return 0; scp->mode = mode; if (set_mode(scp) == 0) { - if (scp->adp->va_info.vi_flags & V_INFO_GRAPHICS) + if (scp->sc->adp->va_info.vi_flags & V_INFO_GRAPHICS) scp->status |= GRAPHICS_MODE; +#ifndef SC_NO_PALETTE_LOADING if (pal != NULL) - load_palette(scp->adp, pal); + load_palette(scp->sc->adp, pal); +#endif set_border(scp, border); return 0; } else { @@ -2379,19 +2034,26 @@ restore_scrn_saver_mode(scr_stat *scp, int changemode) int status; int s; - /* assert(scp == cur_console) */ + /* assert(scp == scp->sc->cur_scp) */ s = spltty(); mode = scp->mode; status = scp->status; scp->mode = scp->splash_save_mode; scp->status &= ~(UNKNOWN_MODE | SAVER_RUNNING); scp->status |= scp->splash_save_status; + scp->sc->flags &= ~SC_SCRN_BLANKED; if (!changemode) { + if (!ISGRAPHSC(scp)) + draw_cursor_image(scp); + --scrn_blanked; splx(s); return 0; } if (set_mode(scp) == 0) { - load_palette(scp->adp, palette); +#ifndef SC_NO_PALETTE_LOADING + load_palette(scp->sc->adp, scp->sc->palette); +#endif + --scrn_blanked; splx(s); return 0; } else { @@ -2403,35 +2065,38 @@ restore_scrn_saver_mode(scr_stat *scp, int changemode) } static void -stop_scrn_saver(void (*saver)(int)) +stop_scrn_saver(sc_softc_t *sc, void (*saver)(sc_softc_t *, int)) { - (*saver)(FALSE); + (*saver)(sc, FALSE); run_scrn_saver = FALSE; /* the screen saver may have chosen not to stop after all... */ - if (scrn_blanked) + if (sc->flags & SC_SCRN_BLANKED) return; - mark_all(cur_console); - if (delayed_next_scr) - switch_scr(cur_console, delayed_next_scr - 1); + mark_all(sc->cur_scp); + if (sc->delayed_next_scr) + switch_scr(sc, sc->delayed_next_scr - 1); wakeup((caddr_t)&scrn_blanked); } static int -wait_scrn_saver_stop(void) +wait_scrn_saver_stop(sc_softc_t *sc) { int error = 0; - while (scrn_blanked) { + while (scrn_blanked > 0) { run_scrn_saver = FALSE; + if (sc && !(sc->flags & SC_SCRN_BLANKED)) { + error = 0; + break; + } error = tsleep((caddr_t)&scrn_blanked, PZERO | PCATCH, "scrsav", 0); - run_scrn_saver = FALSE; - if (error != ERESTART) + if ((error != 0) && (error != ERESTART)) break; } + run_scrn_saver = FALSE; return error; } - #endif /* NSPLASH */ void @@ -2446,99 +2111,297 @@ sc_clear_screen(scr_stat *scp) { move_crsr(scp, 0, 0); scp->cursor_oldpos = scp->cursor_pos; - fillw(scp->term.cur_color | scr_map[0x20], scp->scr_buf, - scp->xsize * scp->ysize); + sc_vtb_clear(&scp->vtb, scp->sc->scr_map[0x20], scp->term.cur_color); mark_all(scp); - remove_cutmarking(scp); + sc_remove_cutmarking(scp); } static int -switch_scr(scr_stat *scp, u_int next_scr) +switch_scr(sc_softc_t *sc, u_int next_scr) { - /* delay switch if actively updating screen */ - if (scrn_blanked || write_in_progress || blink_in_progress) { - delayed_next_scr = next_scr+1; + struct tty *tp; + int s; + + DPRINTF(5, ("sc0: switch_scr() %d ", next_scr + 1)); + + /* delay switch if the screen is blanked or being updated */ + if ((sc->flags & SC_SCRN_BLANKED) || sc->write_in_progress + || sc->blink_in_progress || sc->videoio_in_progress) { + sc->delayed_next_scr = next_scr + 1; sc_touch_scrn_saver(); + DPRINTF(5, ("switch delayed\n")); return 0; } - if (switch_in_progress && (cur_console->proc != pfind(cur_console->pid))) - switch_in_progress = FALSE; + s = spltty(); - if (next_scr >= MAXCONS || switch_in_progress || - (cur_console->smode.mode == VT_AUTO && ISGRAPHSC(cur_console))) { - do_bell(scp, BELL_PITCH, BELL_DURATION); + /* we are in the middle of the vty switching process... */ + if (sc->switch_in_progress + && (sc->cur_scp->smode.mode == VT_PROCESS) + && sc->cur_scp->proc) { + if (sc->cur_scp->proc != pfind(sc->cur_scp->pid)) { + /* + * The controlling process has died!!. Do some clean up. + * NOTE:`cur_scp->proc' and `cur_scp->smode.mode' + * are not reset here yet; they will be cleared later. + */ + DPRINTF(5, ("cur_scp controlling process %d died, ", + sc->cur_scp->pid)); + if (sc->cur_scp->status & SWITCH_WAIT_REL) { + /* + * Force the previous switch to finish, but return now + * with error. + */ + DPRINTF(5, ("reset WAIT_REL, ")); + sc->cur_scp->status &= ~SWITCH_WAIT_REL; + s = do_switch_scr(sc, s); + splx(s); + DPRINTF(5, ("finishing previous switch\n")); + return EINVAL; + } else if (sc->cur_scp->status & SWITCH_WAIT_ACQ) { + /* let's assume screen switch has been completed. */ + DPRINTF(5, ("reset WAIT_ACQ, ")); + sc->cur_scp->status &= ~SWITCH_WAIT_ACQ; + sc->switch_in_progress = 0; + } else { + /* + * We are in between screen release and acquisition, and + * reached here via scgetc() or scrn_timer() which has + * interrupted exchange_scr(). Don't do anything stupid. + */ + DPRINTF(5, ("waiting nothing, ")); + } + } else { + /* + * The controlling process is alive, but not responding... + * It is either buggy or it may be just taking time. + * The following code is a gross kludge to cope with this + * problem for which there is no clean solution. XXX + */ + if (sc->cur_scp->status & SWITCH_WAIT_REL) { + switch (sc->switch_in_progress++) { + case 1: + break; + case 2: + DPRINTF(5, ("sending relsig again, ")); + signal_vt_rel(sc->cur_scp); + break; + case 3: + break; + case 4: + default: + /* + * Clear the flag and force the previous switch to finish, + * but return now with error. + */ + DPRINTF(5, ("force reset WAIT_REL, ")); + sc->cur_scp->status &= ~SWITCH_WAIT_REL; + s = do_switch_scr(sc, s); + splx(s); + DPRINTF(5, ("force finishing previous switch\n")); + return EINVAL; + } + } else if (sc->cur_scp->status & SWITCH_WAIT_ACQ) { + switch (sc->switch_in_progress++) { + case 1: + break; + case 2: + DPRINTF(5, ("sending acqsig again, ")); + signal_vt_acq(sc->cur_scp); + break; + case 3: + break; + case 4: + default: + /* clear the flag and finish the previous switch */ + DPRINTF(5, ("force reset WAIT_ACQ, ")); + sc->cur_scp->status &= ~SWITCH_WAIT_ACQ; + sc->switch_in_progress = 0; + break; + } + } + } + } + + /* + * Return error if an invalid argument is given, or vty switch + * is still in progress. + */ + if ((next_scr < sc->first_vty) || (next_scr >= sc->first_vty + sc->vtys) + || sc->switch_in_progress) { + splx(s); + do_bell(sc->cur_scp, bios_value.bell_pitch, BELL_DURATION); + DPRINTF(5, ("error 1\n")); + return EINVAL; + } + + /* + * Don't allow switching away from the graphics mode vty + * if the switch mode is VT_AUTO, unless the next vty is the same + * as the current or the current vty has been closed (but showing). + */ + tp = VIRTUAL_TTY(sc, sc->cur_scp->index); + if ((sc->cur_scp->index != next_scr) + && (tp->t_state & TS_ISOPEN) + && (sc->cur_scp->smode.mode == VT_AUTO) + && ISGRAPHSC(sc->cur_scp)) { + splx(s); + do_bell(sc->cur_scp, bios_value.bell_pitch, BELL_DURATION); + DPRINTF(5, ("error, graphics mode\n")); return EINVAL; } - /* is the wanted virtual console open ? */ - if (next_scr) { - struct tty *tp = VIRTUAL_TTY(next_scr); + /* + * Is the wanted vty open? Don't allow switching to a closed vty. + * Note that we always allow the user to switch to the kernel + * console even if it is closed. + */ + if ((sc_console == NULL) || (next_scr != sc_console->index)) { + tp = VIRTUAL_TTY(sc, next_scr); if (!(tp->t_state & TS_ISOPEN)) { - do_bell(scp, BELL_PITCH, BELL_DURATION); + splx(s); + do_bell(sc->cur_scp, bios_value.bell_pitch, BELL_DURATION); + DPRINTF(5, ("error 2, requested vty isn't open!\n")); return EINVAL; } } - switch_in_progress = TRUE; - old_scp = cur_console; - new_scp = console[next_scr]; - wakeup((caddr_t)&new_scp->smode); - if (new_scp == old_scp) { - switch_in_progress = FALSE; - delayed_next_scr = FALSE; + /* this is the start of vty switching process... */ + ++sc->switch_in_progress; + sc->delayed_next_scr = 0; + sc->old_scp = sc->cur_scp; + sc->new_scp = sc->console[next_scr - sc->first_vty]; + if (sc->new_scp == sc->old_scp) { + sc->switch_in_progress = 0; + wakeup((caddr_t)&sc->new_scp->smode); + splx(s); + DPRINTF(5, ("switch done (new == old)\n")); return 0; } /* has controlling process died? */ - if (old_scp->proc && (old_scp->proc != pfind(old_scp->pid))) - old_scp->smode.mode = VT_AUTO; - if (new_scp->proc && (new_scp->proc != pfind(new_scp->pid))) - new_scp->smode.mode = VT_AUTO; - - /* check the modes and switch appropriately */ - if (old_scp->smode.mode == VT_PROCESS) { - old_scp->status |= SWITCH_WAIT_REL; - psignal(old_scp->proc, old_scp->smode.relsig); + vt_proc_alive(sc->old_scp); + vt_proc_alive(sc->new_scp); + + /* wait for the controlling process to release the screen, if necessary */ + if (signal_vt_rel(sc->old_scp)) { + splx(s); + return 0; } - else { - exchange_scr(); - if (new_scp->smode.mode == VT_PROCESS) { - new_scp->status |= SWITCH_WAIT_ACQ; - psignal(new_scp->proc, new_scp->smode.acqsig); - } - else - switch_in_progress = FALSE; + + /* go set up the new vty screen */ + splx(s); + exchange_scr(sc); + s = spltty(); + + /* wake up processes waiting for this vty */ + wakeup((caddr_t)&sc->cur_scp->smode); + + /* wait for the controlling process to acknowledge, if necessary */ + if (signal_vt_acq(sc->cur_scp)) { + splx(s); + return 0; } + + sc->switch_in_progress = 0; + if (sc->unit == sc_console_unit) + cons_unavail = FALSE; + splx(s); + DPRINTF(5, ("switch done\n")); + return 0; } +static int +do_switch_scr(sc_softc_t *sc, int s) +{ + vt_proc_alive(sc->new_scp); + + splx(s); + exchange_scr(sc); + s = spltty(); + /* sc->cur_scp == sc->new_scp */ + wakeup((caddr_t)&sc->cur_scp->smode); + + /* wait for the controlling process to acknowledge, if necessary */ + if (!signal_vt_acq(sc->cur_scp)) { + sc->switch_in_progress = 0; + if (sc->unit == sc_console_unit) + cons_unavail = FALSE; + } + + return s; +} + +static int +vt_proc_alive(scr_stat *scp) +{ + if (scp->proc) { + if (scp->proc == pfind(scp->pid)) + return TRUE; + scp->proc = NULL; + scp->smode.mode = VT_AUTO; + DPRINTF(5, ("vt controlling process %d died\n", scp->pid)); + } + return FALSE; +} + +static int +signal_vt_rel(scr_stat *scp) +{ + if (scp->smode.mode != VT_PROCESS) + return FALSE; + scp->status |= SWITCH_WAIT_REL; + psignal(scp->proc, scp->smode.relsig); + DPRINTF(5, ("sending relsig to %d\n", scp->pid)); + return TRUE; +} + +static int +signal_vt_acq(scr_stat *scp) +{ + if (scp->smode.mode != VT_PROCESS) + return FALSE; + if (scp->sc->unit == sc_console_unit) + cons_unavail = TRUE; + scp->status |= SWITCH_WAIT_ACQ; + psignal(scp->proc, scp->smode.acqsig); + DPRINTF(5, ("sending acqsig to %d\n", scp->pid)); + return TRUE; +} + static void -exchange_scr(void) +exchange_scr(sc_softc_t *sc) { + scr_stat *scp; + /* save the current state of video and keyboard */ - move_crsr(old_scp, old_scp->xpos, old_scp->ypos); - if (old_scp->kbd_mode == K_XLATE) - save_kbd_state(old_scp); + move_crsr(sc->old_scp, sc->old_scp->xpos, sc->old_scp->ypos); + if (sc->old_scp->kbd_mode == K_XLATE) + save_kbd_state(sc->old_scp); /* set up the video for the new screen */ - cur_console = new_scp; - if (old_scp->mode != new_scp->mode || ISUNKNOWNSC(old_scp)) - set_mode(new_scp); - move_crsr(new_scp, new_scp->xpos, new_scp->ypos); - if (ISTEXTSC(new_scp) && (sc_flags & CHAR_CURSOR)) - set_destructive_cursor(new_scp); - if (ISGRAPHSC(old_scp)) - load_palette(new_scp->adp, palette); - set_border(new_scp, new_scp->border); + scp = sc->cur_scp = sc->new_scp; + if (sc->old_scp->mode != scp->mode || ISUNKNOWNSC(sc->old_scp)) + set_mode(scp); + else + sc_vtb_init(&scp->scr, VTB_FRAMEBUFFER, scp->xsize, scp->ysize, + (void *)sc->adp->va_window, FALSE); + move_crsr(scp, scp->xpos, scp->ypos); + if (!ISGRAPHSC(scp)) + sc_set_cursor_image(scp); +#ifndef SC_NO_PALETTE_LOADING + if (ISGRAPHSC(sc->old_scp)) + load_palette(sc->adp, sc->palette); +#endif + set_border(scp, scp->border); /* set up the keyboard for the new screen */ - if (old_scp->kbd_mode != new_scp->kbd_mode) - kbd_ioctl(kbd, KDSKBMODE, (caddr_t)&new_scp->kbd_mode); - update_kbd_state(new_scp->status, LOCK_MASK); + if (sc->old_scp->kbd_mode != scp->kbd_mode) + kbd_ioctl(sc->kbd, KDSKBMODE, (caddr_t)&scp->kbd_mode); + update_kbd_state(scp, scp->status, LOCK_MASK); - delayed_next_scr = FALSE; - mark_all(new_scp); + mark_all(scp); } static void @@ -2546,9 +2409,11 @@ scan_esc(scr_stat *scp, u_char c) { static u_char ansi_col[16] = {0, 4, 2, 6, 1, 5, 3, 7, 8, 12, 10, 14, 9, 13, 11, 15}; + sc_softc_t *sc; int i, n; - u_short *src, *dst, count; + int count; + sc = scp->sc; if (scp->term.esc == 1) { /* seen ESC */ switch (c) { @@ -2574,10 +2439,8 @@ scan_esc(scr_stat *scp, u_char c) if (scp->ypos > 0) move_crsr(scp, scp->xpos, scp->ypos - 1); else { - bcopy(scp->scr_buf, scp->scr_buf + scp->xsize, - (scp->ysize - 1) * scp->xsize * sizeof(u_short)); - fillw(scp->term.cur_color | scr_map[0x20], - scp->scr_buf, scp->xsize); + sc_vtb_ins(&scp->vtb, 0, scp->xsize, + sc->scr_map[0x20], scp->term.cur_color); mark_all(scp); } break; @@ -2669,26 +2532,24 @@ scan_esc(scr_stat *scp, u_char c) n = scp->term.param[0]; switch (n) { case 0: /* clear form cursor to end of display */ - fillw(scp->term.cur_color | scr_map[0x20], - scp->cursor_pos, - scp->scr_buf + scp->xsize * scp->ysize - scp->cursor_pos); - mark_for_update(scp, scp->cursor_pos - scp->scr_buf); + sc_vtb_erase(&scp->vtb, scp->cursor_pos, + scp->xsize * scp->ysize - scp->cursor_pos, + sc->scr_map[0x20], scp->term.cur_color); + mark_for_update(scp, scp->cursor_pos); mark_for_update(scp, scp->xsize * scp->ysize - 1); - remove_cutmarking(scp); + sc_remove_cutmarking(scp); break; case 1: /* clear from beginning of display to cursor */ - fillw(scp->term.cur_color | scr_map[0x20], - scp->scr_buf, - scp->cursor_pos - scp->scr_buf); - mark_for_update(scp, 0); - mark_for_update(scp, scp->cursor_pos - scp->scr_buf); - remove_cutmarking(scp); + sc_vtb_erase(&scp->vtb, 0, scp->cursor_pos, + sc->scr_map[0x20], scp->term.cur_color); + mark_for_update(scp, 0); + mark_for_update(scp, scp->cursor_pos); + sc_remove_cutmarking(scp); break; case 2: /* clear entire display */ - fillw(scp->term.cur_color | scr_map[0x20], scp->scr_buf, - scp->xsize * scp->ysize); + sc_vtb_clear(&scp->vtb, sc->scr_map[0x20], scp->term.cur_color); mark_all(scp); - remove_cutmarking(scp); + sc_remove_cutmarking(scp); break; } break; @@ -2700,24 +2561,24 @@ scan_esc(scr_stat *scp, u_char c) n = scp->term.param[0]; switch (n) { case 0: /* clear form cursor to end of line */ - fillw(scp->term.cur_color | scr_map[0x20], - scp->cursor_pos, - scp->xsize - scp->xpos); - mark_for_update(scp, scp->cursor_pos - scp->scr_buf); - mark_for_update(scp, scp->cursor_pos - scp->scr_buf + + sc_vtb_erase(&scp->vtb, scp->cursor_pos, + scp->xsize - scp->xpos, + sc->scr_map[0x20], scp->term.cur_color); + mark_for_update(scp, scp->cursor_pos); + mark_for_update(scp, scp->cursor_pos + scp->xsize - 1 - scp->xpos); break; case 1: /* clear from beginning of line to cursor */ - fillw(scp->term.cur_color | scr_map[0x20], - scp->cursor_pos - scp->xpos, - scp->xpos + 1); + sc_vtb_erase(&scp->vtb, scp->cursor_pos - scp->xpos, + scp->xpos + 1, + sc->scr_map[0x20], scp->term.cur_color); mark_for_update(scp, scp->ypos * scp->xsize); - mark_for_update(scp, scp->cursor_pos - scp->scr_buf); + mark_for_update(scp, scp->cursor_pos); break; case 2: /* clear entire line */ - fillw(scp->term.cur_color | scr_map[0x20], - scp->cursor_pos - scp->xpos, - scp->xsize); + sc_vtb_erase(&scp->vtb, scp->cursor_pos - scp->xpos, + scp->xsize, + sc->scr_map[0x20], scp->term.cur_color); mark_for_update(scp, scp->ypos * scp->xsize); mark_for_update(scp, (scp->ypos + 1) * scp->xsize - 1); break; @@ -2728,12 +2589,8 @@ scan_esc(scr_stat *scp, u_char c) n = scp->term.param[0]; if (n < 1) n = 1; if (n > scp->ysize - scp->ypos) n = scp->ysize - scp->ypos; - src = scp->scr_buf + scp->ypos * scp->xsize; - dst = src + n * scp->xsize; - count = scp->ysize - (scp->ypos + n); - bcopy(src, dst, count * scp->xsize * sizeof(u_short)); - fillw(scp->term.cur_color | scr_map[0x20], src, - n * scp->xsize); + sc_vtb_ins(&scp->vtb, scp->ypos * scp->xsize, n * scp->xsize, + sc->scr_map[0x20], scp->term.cur_color); mark_for_update(scp, scp->ypos * scp->xsize); mark_for_update(scp, scp->xsize * scp->ysize - 1); break; @@ -2742,13 +2599,8 @@ scan_esc(scr_stat *scp, u_char c) n = scp->term.param[0]; if (n < 1) n = 1; if (n > scp->ysize - scp->ypos) n = scp->ysize - scp->ypos; - dst = scp->scr_buf + scp->ypos * scp->xsize; - src = dst + n * scp->xsize; - count = scp->ysize - (scp->ypos + n); - bcopy(src, dst, count * scp->xsize * sizeof(u_short)); - src = dst + count * scp->xsize; - fillw(scp->term.cur_color | scr_map[0x20], src, - n * scp->xsize); + sc_vtb_delete(&scp->vtb, scp->ypos * scp->xsize, n * scp->xsize, + sc->scr_map[0x20], scp->term.cur_color); mark_for_update(scp, scp->ypos * scp->xsize); mark_for_update(scp, scp->xsize * scp->ysize - 1); break; @@ -2757,39 +2609,30 @@ scan_esc(scr_stat *scp, u_char c) n = scp->term.param[0]; if (n < 1) n = 1; if (n > scp->xsize - scp->xpos) n = scp->xsize - scp->xpos; - dst = scp->cursor_pos; - src = dst + n; count = scp->xsize - (scp->xpos + n); - bcopy(src, dst, count * sizeof(u_short)); - src = dst + count; - fillw(scp->term.cur_color | scr_map[0x20], src, n); - mark_for_update(scp, scp->cursor_pos - scp->scr_buf); - mark_for_update(scp, scp->cursor_pos - scp->scr_buf + n + count - 1); + sc_vtb_delete(&scp->vtb, scp->cursor_pos, n, + sc->scr_map[0x20], scp->term.cur_color); + mark_for_update(scp, scp->cursor_pos); + mark_for_update(scp, scp->cursor_pos + n + count - 1); break; case '@': /* Insert n chars */ n = scp->term.param[0]; if (n < 1) n = 1; if (n > scp->xsize - scp->xpos) n = scp->xsize - scp->xpos; - src = scp->cursor_pos; - dst = src + n; count = scp->xsize - (scp->xpos + n); - bcopy(src, dst, count * sizeof(u_short)); - fillw(scp->term.cur_color | scr_map[0x20], src, n); - mark_for_update(scp, scp->cursor_pos - scp->scr_buf); - mark_for_update(scp, scp->cursor_pos - scp->scr_buf + n + count - 1); + sc_vtb_ins(&scp->vtb, scp->cursor_pos, n, + sc->scr_map[0x20], scp->term.cur_color); + mark_for_update(scp, scp->cursor_pos); + mark_for_update(scp, scp->cursor_pos + n + count - 1); break; case 'S': /* scroll up n lines */ n = scp->term.param[0]; if (n < 1) n = 1; if (n > scp->ysize) n = scp->ysize; - bcopy(scp->scr_buf + (scp->xsize * n), - scp->scr_buf, - scp->xsize * (scp->ysize - n) * sizeof(u_short)); - fillw(scp->term.cur_color | scr_map[0x20], - scp->scr_buf + scp->xsize * (scp->ysize - n), - scp->xsize * n); + sc_vtb_delete(&scp->vtb, 0, n * scp->xsize, + sc->scr_map[0x20], scp->term.cur_color); mark_all(scp); break; @@ -2797,12 +2640,8 @@ scan_esc(scr_stat *scp, u_char c) n = scp->term.param[0]; if (n < 1) n = 1; if (n > scp->ysize) n = scp->ysize; - bcopy(scp->scr_buf, - scp->scr_buf + (scp->xsize * n), - scp->xsize * (scp->ysize - n) * - sizeof(u_short)); - fillw(scp->term.cur_color | scr_map[0x20], - scp->scr_buf, scp->xsize * n); + sc_vtb_ins(&scp->vtb, 0, n * scp->xsize, + sc->scr_map[0x20], scp->term.cur_color); mark_all(scp); break; @@ -2810,10 +2649,10 @@ scan_esc(scr_stat *scp, u_char c) n = scp->term.param[0]; if (n < 1) n = 1; if (n > scp->xsize - scp->xpos) n = scp->xsize - scp->xpos; - fillw(scp->term.cur_color | scr_map[0x20], - scp->cursor_pos, n); - mark_for_update(scp, scp->cursor_pos - scp->scr_buf); - mark_for_update(scp, scp->cursor_pos - scp->scr_buf + n - 1); + sc_vtb_erase(&scp->vtb, scp->cursor_pos, n, + sc->scr_map[0x20], scp->term.cur_color); + mark_for_update(scp, scp->cursor_pos); + mark_for_update(scp, scp->cursor_pos + n - 1); break; case 'Z': /* move n tabs backwards */ @@ -2962,7 +2801,7 @@ scan_esc(scr_stat *scp, u_char c) case 'z': /* switch to (virtual) console n */ if (scp->term.num_param == 1) - switch_scr(scp, scp->term.param[0]); + switch_scr(sc, scp->term.param[0]); break; } } @@ -2990,8 +2829,8 @@ scan_esc(scr_stat *scp, u_char c) case 'A': /* set display border color */ if (scp->term.num_param == 1) { scp->border=scp->term.param[0] & 0xff; - if (scp == cur_console) - set_border(cur_console, scp->border); + if (scp == sc->cur_scp) + set_border(scp, scp->border); } break; @@ -3003,31 +2842,32 @@ scan_esc(scr_stat *scp, u_char c) break; case 'C': /* set cursor type & shape */ + if (!ISGRAPHSC(sc->cur_scp)) + remove_cursor_image(sc->cur_scp); if (scp->term.num_param == 1) { if (scp->term.param[0] & 0x01) - sc_flags |= BLINK_CURSOR; + sc->flags |= SC_BLINK_CURSOR; else - sc_flags &= ~BLINK_CURSOR; - if ((scp->term.param[0] & 0x02) - && ISFONTAVAIL(scp->adp->va_flags)) - sc_flags |= CHAR_CURSOR; + sc->flags &= ~SC_BLINK_CURSOR; + if (scp->term.param[0] & 0x02) + sc->flags |= SC_CHAR_CURSOR; else - sc_flags &= ~CHAR_CURSOR; + sc->flags &= ~SC_CHAR_CURSOR; } else if (scp->term.num_param == 2) { - scp->cursor_start = scp->term.param[0] & 0x1F; - scp->cursor_end = scp->term.param[1] & 0x1F; + sc->cursor_base = scp->font_size + - (scp->term.param[1] & 0x1F) - 1; + sc->cursor_height = (scp->term.param[1] & 0x1F) + - (scp->term.param[0] & 0x1F) + 1; } /* * The cursor shape is global property; all virtual consoles * are affected. Update the cursor in the current console... */ - if (!ISGRAPHSC(cur_console)) { + if (!ISGRAPHSC(sc->cur_scp)) { i = spltty(); - remove_cursor_image(cur_console); - if (sc_flags & CHAR_CURSOR) - set_destructive_cursor(cur_console); - draw_cursor_image(cur_console); + sc_set_cursor_image(sc->cur_scp); + draw_cursor_image(sc->cur_scp); splx(i); } break; @@ -3094,19 +2934,28 @@ ansi_put(scr_stat *scp, u_char *buf, int len) u_char *ptr = buf; /* make screensaver happy */ - if (!sticky_splash && scp == cur_console) + if (!sticky_splash && scp == scp->sc->cur_scp) run_scrn_saver = FALSE; - write_in_progress++; outloop: + scp->sc->write_in_progress++; if (scp->term.esc) { scan_esc(scp, *ptr++); len--; } else if (PRINTABLE(*ptr)) { /* Print only printables */ - int cnt = len <= (scp->xsize-scp->xpos) ? len : (scp->xsize-scp->xpos); - u_short cur_attr = scp->term.cur_attr; - u_short *cursor_pos = scp->cursor_pos; + vm_offset_t p; + u_char *map; + int cnt; + int attr; + int i; + + p = sc_vtb_pointer(&scp->vtb, scp->cursor_pos); + map = scp->sc->scr_map; + attr = scp->term.cur_attr; + + cnt = (len <= scp->xsize - scp->xpos) ? len : (scp->xsize - scp->xpos); + i = cnt; do { /* * gcc-2.6.3 generates poor (un)sign extension code. Casting the @@ -3115,15 +2964,17 @@ outloop: * (+ cache misses) on i486's. */ #define UCVP(ucp) ((u_char volatile *)(ucp)) - *cursor_pos++ = UCVP(scr_map)[*UCVP(ptr)] | cur_attr; - ptr++; - cnt--; - } while (cnt && PRINTABLE(*ptr)); - len -= (cursor_pos - scp->cursor_pos); - scp->xpos += (cursor_pos - scp->cursor_pos); - mark_for_update(scp, scp->cursor_pos - scp->scr_buf); - mark_for_update(scp, cursor_pos - scp->scr_buf); - scp->cursor_pos = cursor_pos; + p = sc_vtb_putchar(&scp->vtb, p, UCVP(map)[*UCVP(ptr)], attr); + ++ptr; + --i; + } while (i > 0 && PRINTABLE(*ptr)); + + len -= cnt - i; + mark_for_update(scp, scp->cursor_pos); + scp->cursor_pos += cnt - i; + mark_for_update(scp, scp->cursor_pos - 1); + scp->xpos += cnt - i; + if (scp->xpos >= scp->xsize) { scp->xpos = 0; scp->ypos++; @@ -3136,10 +2987,10 @@ outloop: break; case 0x08: /* non-destructive backspace */ - if (scp->cursor_pos > scp->scr_buf) { - mark_for_update(scp, scp->cursor_pos - scp->scr_buf); + if (scp->cursor_pos > 0) { + mark_for_update(scp, scp->cursor_pos); scp->cursor_pos--; - mark_for_update(scp, scp->cursor_pos - scp->scr_buf); + mark_for_update(scp, scp->cursor_pos); if (scp->xpos > 0) scp->xpos--; else { @@ -3150,9 +3001,9 @@ outloop: break; case 0x09: /* non-destructive tab */ - mark_for_update(scp, scp->cursor_pos - scp->scr_buf); + mark_for_update(scp, scp->cursor_pos); scp->cursor_pos += (8 - scp->xpos % 8u); - mark_for_update(scp, scp->cursor_pos - scp->scr_buf); + mark_for_update(scp, scp->cursor_pos); if ((scp->xpos += (8 - scp->xpos % 8u)) >= scp->xsize) { scp->xpos = 0; scp->ypos++; @@ -3160,9 +3011,9 @@ outloop: break; case 0x0a: /* newline, same pos */ - mark_for_update(scp, scp->cursor_pos - scp->scr_buf); + mark_for_update(scp, scp->cursor_pos); scp->cursor_pos += scp->xsize; - mark_for_update(scp, scp->cursor_pos - scp->scr_buf); + mark_for_update(scp, scp->cursor_pos); scp->ypos++; break; @@ -3171,9 +3022,9 @@ outloop: break; case 0x0d: /* return, return to pos 0 */ - mark_for_update(scp, scp->cursor_pos - scp->scr_buf); + mark_for_update(scp, scp->cursor_pos); scp->cursor_pos -= scp->xpos; - mark_for_update(scp, scp->cursor_pos - scp->scr_buf); + mark_for_update(scp, scp->cursor_pos); scp->xpos = 0; break; @@ -3185,117 +3036,379 @@ outloop: ptr++; len--; } /* do we have to scroll ?? */ - if (scp->cursor_pos >= scp->scr_buf + scp->ysize * scp->xsize) { - remove_cutmarking(scp); - if (scp->history != NULL) { - bcopy(scp->scr_buf, scp->history_head, - scp->xsize * sizeof(u_short)); - scp->history_head += scp->xsize; - if (scp->history_head + scp->xsize > - scp->history + scp->history_size) - scp->history_head = scp->history; - } - bcopy(scp->scr_buf + scp->xsize, scp->scr_buf, - scp->xsize * (scp->ysize - 1) * sizeof(u_short)); - fillw(scp->term.cur_color | scr_map[0x20], - scp->scr_buf + scp->xsize * (scp->ysize - 1), - scp->xsize); + if (scp->cursor_pos >= scp->ysize * scp->xsize) { + sc_remove_cutmarking(scp); +#ifndef SC_NO_HISTORY + if (scp->history != NULL) + sc_hist_save_one_line(scp, 0); +#endif + sc_vtb_delete(&scp->vtb, 0, scp->xsize, + scp->sc->scr_map[0x20], scp->term.cur_color); scp->cursor_pos -= scp->xsize; scp->ypos--; mark_all(scp); } + scp->sc->write_in_progress--; if (len) goto outloop; - write_in_progress--; - if (delayed_next_scr) - switch_scr(scp, delayed_next_scr - 1); + if (scp->sc->delayed_next_scr) + switch_scr(scp->sc, scp->sc->delayed_next_scr - 1); } static void -scinit(void) +draw_cursor_image(scr_stat *scp) +{ + /* assert(scp == scp->sc->cur_scp); */ + ++scp->sc->videoio_in_progress; + (*scp->rndr->draw_cursor)(scp, scp->cursor_pos, + scp->sc->flags & SC_BLINK_CURSOR, TRUE, + sc_inside_cutmark(scp, scp->cursor_pos)); + --scp->sc->videoio_in_progress; +} + +static void +remove_cursor_image(scr_stat *scp) +{ + /* assert(scp == scp->sc->cur_scp); */ + ++scp->sc->videoio_in_progress; + (*scp->rndr->draw_cursor)(scp, scp->cursor_oldpos, + scp->sc->flags & SC_BLINK_CURSOR, FALSE, + sc_inside_cutmark(scp, scp->cursor_oldpos)); + --scp->sc->videoio_in_progress; +} + +static void +update_cursor_image(scr_stat *scp) { + int blink; + + if (scp->sc->flags & SC_CHAR_CURSOR) { + scp->cursor_base = scp->sc->cursor_base; + scp->cursor_height = imin(scp->sc->cursor_height, scp->font_size); + } else { + scp->cursor_base = 0; + scp->cursor_height = scp->font_size; + } + blink = scp->sc->flags & SC_BLINK_CURSOR; + + /* assert(scp == scp->sc->cur_scp); */ + ++scp->sc->videoio_in_progress; + (*scp->rndr->draw_cursor)(scp, scp->cursor_oldpos, blink, FALSE, + sc_inside_cutmark(scp, scp->cursor_pos)); + (*scp->rndr->set_cursor)(scp, scp->cursor_base, scp->cursor_height, blink); + (*scp->rndr->draw_cursor)(scp, scp->cursor_pos, blink, TRUE, + sc_inside_cutmark(scp, scp->cursor_pos)); + --scp->sc->videoio_in_progress; +} + +void +sc_set_cursor_image(scr_stat *scp) +{ + if (scp->sc->flags & SC_CHAR_CURSOR) { + scp->cursor_base = scp->sc->cursor_base; + scp->cursor_height = imin(scp->sc->cursor_height, scp->font_size); + } else { + scp->cursor_base = 0; + scp->cursor_height = scp->font_size; + } + + /* assert(scp == scp->sc->cur_scp); */ + ++scp->sc->videoio_in_progress; + (*scp->rndr->set_cursor)(scp, scp->cursor_base, scp->cursor_height, + scp->sc->flags & SC_BLINK_CURSOR); + --scp->sc->videoio_in_progress; +} + +static void +move_crsr(scr_stat *scp, int x, int y) +{ + if (x < 0) + x = 0; + if (y < 0) + y = 0; + if (x >= scp->xsize) + x = scp->xsize-1; + if (y >= scp->ysize) + y = scp->ysize-1; + scp->xpos = x; + scp->ypos = y; + scp->cursor_pos = scp->ypos * scp->xsize + scp->xpos; +} + +static void +scinit(int unit, int flags) +{ + /* + * When syscons is being initialized as the kernel console, malloc() + * is not yet functional, because various kernel structures has not been + * fully initialized yet. Therefore, we need to declare the following + * static buffers for the console. This is less than ideal, + * but is necessry evil for the time being. XXX + */ + static scr_stat main_console; + static scr_stat *main_vtys[MAXCONS]; + static struct tty main_tty[MAXCONS]; + static u_short sc_buffer[ROW*COL]; /* XXX */ +#ifdef DEVFS + static void *main_devfs_token[MAXCONS]; +#endif +#ifndef SC_NO_FONT_LOADING + static u_char font_8[256*8]; + static u_char font_14[256*14]; + static u_char font_16[256*16]; +#endif + + sc_softc_t *sc; + scr_stat *scp; video_adapter_t *adp; int col; int row; - u_int i; + int i; - if (init_done != COLD) - return; + /* one time initialization */ + if (init_done == COLD) { + sc_get_bios_values(&bios_value); + current_default = &user_default; + /* kernel console attributes */ + kernel_console.esc = 0; + kernel_console.attr_mask = NORMAL_ATTR; + kernel_console.cur_attr = + kernel_console.cur_color = kernel_console.std_color = + kernel_default.std_color; + kernel_console.rev_color = kernel_default.rev_color; + } init_done = WARM; - get_bios_values(); + /* + * Allocate resources. Even if we are being called for the second + * time, we must allocate them again, because they might have + * disappeared... + */ + sc = sc_get_softc(unit, flags & SC_KERNEL_CONSOLE); + adp = NULL; + if (sc->adapter >= 0) { + vid_release(sc->adp, (void *)&sc->adapter); + adp = sc->adp; + sc->adp = NULL; + } + if (sc->keyboard >= 0) { + DPRINTF(5, ("sc%d: releasing kbd%d\n", unit, sc->keyboard)); + i = kbd_release(sc->kbd, (void *)&sc->keyboard); + DPRINTF(5, ("sc%d: kbd_release returned %d\n", unit, i)); + if (sc->kbd != NULL) { + DPRINTF(5, ("sc%d: kbd != NULL!, index:%d, minor:%d, flags:0x%x\n", + unit, sc->kbd->kb_index, sc->kbd->kb_minor, sc->kbd->kb_flags)); + } + sc->kbd = NULL; + } + sc->adapter = vid_allocate("*", unit, (void *)&sc->adapter); + sc->adp = vid_get_adapter(sc->adapter); + /* assert((sc->adapter >= 0) && (sc->adp != NULL)) */ + sc->keyboard = kbd_allocate("*", unit, (void *)&sc->keyboard, + sckbdevent, sc); + DPRINTF(1, ("sc%d: keyboard %d\n", unit, sc->keyboard)); + sc->kbd = kbd_get_keyboard(sc->keyboard); + if (sc->kbd != NULL) { + DPRINTF(1, ("sc%d: kbd index:%d, minor:%d, flags:0x%x\n", + unit, sc->kbd->kb_index, sc->kbd->kb_minor, sc->kbd->kb_flags)); + } + + if (!(sc->flags & SC_INIT_DONE) || (adp != sc->adp)) { + + sc->initial_mode = sc->adp->va_initial_mode; + +#ifndef SC_NO_FONT_LOADING + if (flags & SC_KERNEL_CONSOLE) { + sc->font_8 = font_8; + sc->font_14 = font_14; + sc->font_16 = font_16; + } else if (sc->font_8 == NULL) { + /* assert(sc_malloc) */ + sc->font_8 = malloc(sizeof(font_8), M_DEVBUF, M_WAITOK); + sc->font_14 = malloc(sizeof(font_14), M_DEVBUF, M_WAITOK); + sc->font_16 = malloc(sizeof(font_16), M_DEVBUF, M_WAITOK); + } +#endif - /* extract the hardware cursor location and hide the cursor for now */ - adp = vid_get_adapter(adapter); - (*vidsw[adapter]->read_hw_cursor)(adp, &col, &row); - (*vidsw[adapter]->set_hw_cursor)(adp, -1, -1); + /* extract the hardware cursor location and hide the cursor for now */ + (*vidsw[sc->adapter]->read_hw_cursor)(sc->adp, &col, &row); + (*vidsw[sc->adapter]->set_hw_cursor)(sc->adp, -1, -1); - /* set up the first console */ - current_default = &user_default; - console[0] = &main_console; - init_scp(console[0]); - cur_console = console[0]; - - /* copy screen to temporary buffer */ - if (ISTEXTSC(console[0])) - bcopy_fromio(console[0]->adp->va_window, sc_buffer, - console[0]->xsize * console[0]->ysize * sizeof(u_short)); - - console[0]->scr_buf = console[0]->mouse_pos = console[0]->mouse_oldpos - = sc_buffer; - if (col >= console[0]->xsize) - col = 0; - if (row >= console[0]->ysize) - row = console[0]->ysize - 1; - console[0]->xpos = col; - console[0]->ypos = row; - console[0]->cursor_pos = console[0]->cursor_oldpos = - sc_buffer + row*console[0]->xsize + col; - console[0]->cursor_saveunder = *console[0]->cursor_pos; - for (i=1; i<MAXCONS; i++) - console[i] = NULL; - kernel_console.esc = 0; - kernel_console.attr_mask = NORMAL_ATTR; - kernel_console.cur_attr = - kernel_console.cur_color = kernel_console.std_color = - kernel_default.std_color; - kernel_console.rev_color = kernel_default.rev_color; + /* set up the first console */ + sc->first_vty = unit*MAXCONS; + if (flags & SC_KERNEL_CONSOLE) { + sc->vtys = sizeof(main_vtys)/sizeof(main_vtys[0]); + sc->tty = main_tty; +#ifdef DEVFS + sc->devfs_token = main_devfs_token; +#endif + sc->console = main_vtys; + scp = main_vtys[0] = &main_console; + init_scp(sc, sc->first_vty, scp); + sc_vtb_init(&scp->vtb, VTB_MEMORY, scp->xsize, scp->ysize, + (void *)sc_buffer, FALSE); + } else { + /* assert(sc_malloc) */ + sc->vtys = MAXCONS; + sc->tty = malloc(sizeof(struct tty)*MAXCONS, M_DEVBUF, M_WAITOK); + bzero(sc->tty, sizeof(struct tty)*MAXCONS); +#ifdef DEVFS + sc->devfs_token = malloc(sizeof(void *)*MAXCONS, + M_DEVBUF, M_WAITOK); +#endif + sc->console = malloc(sizeof(struct scr_stat *)*MAXCONS, + M_DEVBUF, M_WAITOK); + scp = sc->console[0] = alloc_scp(sc, sc->first_vty); + } + sc->cur_scp = scp; + + /* copy screen to temporary buffer */ + sc_vtb_init(&scp->scr, VTB_FRAMEBUFFER, scp->xsize, scp->ysize, + (void *)scp->sc->adp->va_window, FALSE); + if (ISTEXTSC(scp)) + sc_vtb_copy(&scp->scr, 0, &scp->vtb, 0, scp->xsize*scp->ysize); + + /* move cursors to the initial positions */ + scp->mouse_pos = scp->mouse_oldpos = 0; + if (col >= scp->xsize) + col = 0; + if (row >= scp->ysize) + row = scp->ysize - 1; + scp->xpos = col; + scp->ypos = row; + scp->cursor_pos = scp->cursor_oldpos = row*scp->xsize + col; + if (bios_value.cursor_end < scp->font_size) + sc->cursor_base = scp->font_size - bios_value.cursor_end - 1; + else + sc->cursor_base = 0; + i = bios_value.cursor_end - bios_value.cursor_start + 1; + sc->cursor_height = imin(i, scp->font_size); + if (!ISGRAPHSC(scp)) { + sc_set_cursor_image(scp); + draw_cursor_image(scp); + } - /* initialize mapscrn arrays to a one to one map */ - for (i=0; i<sizeof(scr_map); i++) { - scr_map[i] = scr_rmap[i] = i; - } + /* save font and palette */ +#ifndef SC_NO_FONT_LOADING + sc->fonts_loaded = 0; + if (ISFONTAVAIL(sc->adp->va_flags)) { +#ifdef SC_DFLT_FONT + bcopy(dflt_font_8, sc->font_8, sizeof(dflt_font_8)); + bcopy(dflt_font_14, sc->font_14, sizeof(dflt_font_14)); + bcopy(dflt_font_16, sc->font_16, sizeof(dflt_font_16)); + sc->fonts_loaded = FONT_16 | FONT_14 | FONT_8; + if (scp->font_size < 14) { + copy_font(scp, LOAD, 8, sc->font_8); + sc->fonts_loaded = FONT_8; + } else if (scp->font_size >= 16) { + copy_font(scp, LOAD, 16, sc->font_16); + sc->fonts_loaded = FONT_16; + } else { + copy_font(scp, LOAD, 14, sc->font_14); + sc->fonts_loaded = FONT_14; + } +#else /* !SC_DFLT_FONT */ + if (scp->font_size < 14) { + copy_font(scp, SAVE, 8, sc->font_8); + sc->fonts_loaded = FONT_8; + } else if (scp->font_size >= 16) { + copy_font(scp, SAVE, 16, sc->font_16); + sc->fonts_loaded = FONT_16; + } else { + copy_font(scp, SAVE, 14, sc->font_14); + sc->fonts_loaded = FONT_14; + } +#endif /* SC_DFLT_FONT */ + /* FONT KLUDGE: always use the font page #0. XXX */ + (*vidsw[sc->adapter]->show_font)(sc->adp, 0); + } +#endif /* !SC_NO_FONT_LOADING */ - /* Save font and palette */ - if (ISFONTAVAIL(cur_console->adp->va_flags)) { - if (fonts_loaded & FONT_16) { - copy_font(cur_console, LOAD, 16, font_16); - } else { - copy_font(cur_console, SAVE, 16, font_16); - fonts_loaded = FONT_16; - set_destructive_cursor(cur_console); +#ifndef SC_NO_PALETTE_LOADING + save_palette(sc->adp, sc->palette); +#endif + +#if NSPLASH > 0 + if (!(sc->flags & SC_SPLASH_SCRN) && (flags & SC_KERNEL_CONSOLE)) { + /* we are ready to put up the splash image! */ + splash_init(sc->adp, scsplash_callback, sc); + sc->flags |= SC_SPLASH_SCRN; } - /* - * FONT KLUDGE - * Always use the font page #0. XXX - */ - (*vidsw[cur_console->ad]->show_font)(cur_console->adp, 0); +#endif /* NSPLASH */ } - save_palette(cur_console->adp, palette); + + /* the rest is not necessary, if we have done it once */ + if (sc->flags & SC_INIT_DONE) + return; + + /* clear structures */ + for (i = 1; i < sc->vtys; i++) + sc->console[i] = NULL; + + /* initialize mapscrn arrays to a one to one map */ + for (i = 0; i < sizeof(sc->scr_map); i++) + sc->scr_map[i] = sc->scr_rmap[i] = i; + + sc->flags |= SC_INIT_DONE; +} + +static void +scterm(int unit, int flags) +{ + sc_softc_t *sc; + + sc = sc_get_softc(unit, flags & SC_KERNEL_CONSOLE); + if (sc == NULL) + return; /* shouldn't happen */ #if NSPLASH > 0 - /* we are ready to put up the splash image! */ - splash_init(cur_console->adp, scsplash_callback); + /* this console is no longer available for the splash screen */ + if (sc->flags & SC_SPLASH_SCRN) { + splash_term(sc->adp); + sc->flags &= ~SC_SPLASH_SCRN; + } +#endif /* NSPLASH */ + +#if 0 /* XXX */ + /* move the hardware cursor to the upper-left corner */ + (*vidsw[sc->adapter]->set_hw_cursor)(sc->adp, 0, 0); +#endif + + /* release the keyboard and the video card */ + if (sc->keyboard >= 0) + kbd_release(sc->kbd, &sc->keyboard); + if (sc->adapter >= 0) + vid_release(sc->adp, &sc->adapter); + + /* clear the structure */ + if (!(flags & SC_KERNEL_CONSOLE)) { + free(sc->console, M_DEVBUF); + free(sc->tty, M_DEVBUF); +#ifdef DEVFS + free(sc->devfs_token, M_DEVBUF); #endif +#ifndef SC_NO_FONT_LOADING + free(sc->font_8, M_DEVBUF); + free(sc->font_14, M_DEVBUF); + free(sc->font_16, M_DEVBUF); +#endif + /* XXX vtb, history */ + } + bzero(sc, sizeof(*sc)); + sc->keyboard = -1; + sc->adapter = -1; } static void scshutdown(int howto, void *arg) { + /* assert(sc_console != NULL) */ + sc_touch_scrn_saver(); - if (!cold && cur_console->smode.mode == VT_AUTO - && console[0]->smode.mode == VT_AUTO) - switch_scr(cur_console, 0); + if (!cold && sc_console + && sc_console->sc->cur_scp->smode.mode == VT_AUTO + && sc_console->smode.mode == VT_AUTO) + switch_scr(sc_console->sc, sc_console->index); shutdown_in_progress = TRUE; } @@ -3305,108 +3418,83 @@ sc_clean_up(scr_stat *scp) int error; sc_touch_scrn_saver(); - if ((error = wait_scrn_saver_stop())) +#if NSPLASH > 0 + if ((error = wait_scrn_saver_stop(scp->sc))) return error; +#endif /* NSPLASH */ scp->status &= ~MOUSE_VISIBLE; - remove_cutmarking(scp); + sc_remove_cutmarking(scp); return 0; } void -sc_alloc_scr_buffer(scr_stat *scp, int wait, int clear) +sc_alloc_scr_buffer(scr_stat *scp, int wait, int discard) { - if (scp->scr_buf) - free(scp->scr_buf, M_DEVBUF); - scp->scr_buf = (u_short *)malloc(scp->xsize*scp->ysize*sizeof(u_short), - M_DEVBUF, (wait) ? M_WAITOK : M_NOWAIT); + sc_vtb_t new; + sc_vtb_t old; + int s; - if (clear) { + old = scp->vtb; + sc_vtb_init(&new, VTB_MEMORY, scp->xsize, scp->ysize, NULL, wait); + if (!discard && (old.vtb_flags & VTB_VALID)) { + /* retain the current cursor position and buffer contants */ + scp->cursor_oldpos = scp->cursor_pos; + /* + * This works only if the old buffer has the same size as or larger + * than the new one. XXX + */ + sc_vtb_copy(&old, 0, &new, 0, scp->xsize*scp->ysize); + scp->vtb = new; + } else { /* clear the screen and move the text cursor to the top-left position */ + s = splhigh(); + scp->vtb = new; sc_clear_screen(scp); - } else { - /* retain the current cursor position, but adjust pointers */ - move_crsr(scp, scp->xpos, scp->ypos); - scp->cursor_oldpos = scp->cursor_pos; + splx(s); + sc_vtb_destroy(&old); } +#ifndef SC_NO_SYSMOUSE /* move the mouse cursor at the center of the screen */ - sc_move_mouse(scp, scp->xpixel / 2, scp->ypixel / 2); -} - -void -sc_alloc_cut_buffer(scr_stat *scp, int wait) -{ - if ((cut_buffer == NULL) - || (cut_buffer_size < scp->xsize * scp->ysize + 1)) { - if (cut_buffer != NULL) - free(cut_buffer, M_DEVBUF); - cut_buffer_size = scp->xsize * scp->ysize + 1; - cut_buffer = (u_char *)malloc(cut_buffer_size, - M_DEVBUF, (wait) ? M_WAITOK : M_NOWAIT); - if (cut_buffer != NULL) - cut_buffer[0] = '\0'; - } -} - -void -sc_alloc_history_buffer(scr_stat *scp, int lines, int extra, int wait) -{ - u_short *usp; - - if (lines < scp->ysize) - lines = scp->ysize; - - usp = scp->history; - scp->history = NULL; - if (usp != NULL) { - free(usp, M_DEVBUF); - if (extra > 0) - extra_history_size += extra; - } - - scp->history_size = lines * scp->xsize; - if (lines > imax(sc_history_size, scp->ysize)) - extra_history_size -= lines - imax(sc_history_size, scp->ysize); - usp = (u_short *)malloc(scp->history_size * sizeof(u_short), - M_DEVBUF, (wait) ? M_WAITOK : M_NOWAIT); - if (usp != NULL) - bzero(usp, scp->history_size * sizeof(u_short)); - scp->history_head = scp->history_pos = usp; - scp->history = usp; + sc_mouse_move(scp, scp->xpixel / 2, scp->ypixel / 2); +#endif } static scr_stat -*alloc_scp() +*alloc_scp(sc_softc_t *sc, int vty) { scr_stat *scp; + /* assert(sc_malloc) */ + scp = (scr_stat *)malloc(sizeof(scr_stat), M_DEVBUF, M_WAITOK); - init_scp(scp); + init_scp(sc, vty, scp); + sc_alloc_scr_buffer(scp, TRUE, TRUE); - if (ISMOUSEAVAIL(scp->adp->va_flags)) + +#ifndef SC_NO_SYSMOUSE + if (ISMOUSEAVAIL(sc->adp->va_flags)) sc_alloc_cut_buffer(scp, TRUE); - sc_alloc_history_buffer(scp, sc_history_size, 0, TRUE); -/* SOS - if (scp->adp->va_flags & V_ADP_MODECHANGE) - set_mode(scp); -*/ +#endif + +#ifndef SC_NO_HISTORY + sc_alloc_history_buffer(scp, 0, TRUE); +#endif + sc_clear_screen(scp); - scp->cursor_saveunder = *scp->cursor_pos; return scp; } static void -init_scp(scr_stat *scp) +init_scp(sc_softc_t *sc, int vty, scr_stat *scp) { video_info_t info; - scp->ad = adapter; - scp->adp = vid_get_adapter(scp->ad); - (*vidsw[scp->ad]->get_info)(scp->adp, initial_video_mode, &info); - + scp->index = vty; + scp->sc = sc; scp->status = 0; - scp->mode = initial_video_mode; - scp->scr_buf = NULL; + scp->mode = sc->initial_mode; + (*vidsw[sc->adapter]->get_info)(sc->adp, scp->mode, &info); if (info.vi_flags & V_INFO_GRAPHICS) { scp->status |= GRAPHICS_MODE; scp->xpixel = info.vi_width; @@ -3414,17 +3502,41 @@ init_scp(scr_stat *scp) scp->xsize = info.vi_width/8; scp->ysize = info.vi_height/info.vi_cheight; scp->font_size = FONT_NONE; + scp->font = NULL; } else { scp->xsize = info.vi_width; scp->ysize = info.vi_height; scp->xpixel = scp->xsize*8; scp->ypixel = scp->ysize*info.vi_cheight; - scp->font_size = info.vi_cheight; + if (info.vi_cheight < 14) { + scp->font_size = 8; +#ifndef SC_NO_FONT_LOADING + scp->font = sc->font_8; +#else + scp->font = NULL; +#endif + } else if (info.vi_cheight >= 16) { + scp->font_size = 16; +#ifndef SC_NO_FONT_LOADING + scp->font = sc->font_16; +#else + scp->font = NULL; +#endif + } else { + scp->font_size = 14; +#ifndef SC_NO_FONT_LOADING + scp->font = sc->font_14; +#else + scp->font = NULL; +#endif + } } + sc_vtb_init(&scp->vtb, VTB_MEMORY, 0, 0, NULL, FALSE); + sc_vtb_init(&scp->scr, VTB_FRAMEBUFFER, 0, 0, NULL, FALSE); scp->xoff = scp->yoff = 0; scp->xpos = scp->ypos = 0; scp->saved_xpos = scp->saved_ypos = -1; - scp->start = scp->xsize * scp->ysize; + scp->start = scp->xsize * scp->ysize - 1; scp->end = 0; scp->term.esc = 0; scp->term.attr_mask = NORMAL_ATTR; @@ -3433,70 +3545,30 @@ init_scp(scr_stat *scp) current_default->std_color; scp->term.rev_color = current_default->rev_color; scp->border = BG_BLACK; - scp->cursor_start = bios_value.cursor_start; - scp->cursor_end = bios_value.cursor_end; - scp->mouse_xpos = scp->xsize*8/2; - scp->mouse_ypos = scp->ysize*scp->font_size/2; - scp->mouse_cut_start = scp->mouse_cut_end = NULL; + scp->cursor_base = sc->cursor_base; + scp->cursor_height = imin(sc->cursor_height, scp->font_size); + scp->mouse_xpos = scp->xoff*8 + scp->xsize*8/2; + scp->mouse_ypos = (scp->ysize + scp->yoff)*scp->font_size/2; + scp->mouse_cut_start = scp->xsize*scp->ysize; + scp->mouse_cut_end = -1; scp->mouse_signal = 0; scp->mouse_pid = 0; scp->mouse_proc = NULL; scp->kbd_mode = K_XLATE; - scp->bell_pitch = BELL_PITCH; + scp->bell_pitch = bios_value.bell_pitch; scp->bell_duration = BELL_DURATION; - scp->status |= (bios_value.shift_state & 0x20) ? NLKED : 0; + scp->status |= (bios_value.shift_state & NLKED); scp->status |= CURSOR_ENABLED; scp->pid = 0; scp->proc = NULL; scp->smode.mode = VT_AUTO; - scp->history_head = scp->history_pos = scp->history = NULL; - scp->history_size = imax(sc_history_size, scp->ysize) * scp->xsize; -} - -static void -get_bios_values(void) -{ - bios_value.cursor_start = *(u_int8_t *)pa_to_va(0x461); - bios_value.cursor_end = *(u_int8_t *)pa_to_va(0x460); - bios_value.shift_state = *(u_int8_t *)pa_to_va(0x417); -} - -static void -history_to_screen(scr_stat *scp) -{ - int i; - - for (i=0; i<scp->ysize; i++) - bcopy(scp->history + (((scp->history_pos - scp->history) + - scp->history_size-((i+1)*scp->xsize))%scp->history_size), - scp->scr_buf + (scp->xsize * (scp->ysize-1 - i)), - scp->xsize * sizeof(u_short)); - mark_all(scp); -} - -static int -history_up_line(scr_stat *scp) -{ - if (WRAPHIST(scp, scp->history_pos, -(scp->xsize*scp->ysize)) != - scp->history_head) { - scp->history_pos = WRAPHIST(scp, scp->history_pos, -scp->xsize); - history_to_screen(scp); - return 0; - } - else - return -1; -} + scp->history = NULL; + scp->history_pos = 0; + scp->history_size = 0; -static int -history_down_line(scr_stat *scp) -{ - if (scp->history_pos != scp->history_head) { - scp->history_pos = WRAPHIST(scp, scp->history_pos, scp->xsize); - history_to_screen(scp); - return 0; - } - else - return -1; + /* what if the following call fails... XXX */ + scp->rndr = sc_render_match(scp, scp->sc->adp, + scp->status & (GRAPHICS_MODE | PIXEL_MODE)); } /* @@ -3506,26 +3578,30 @@ history_down_line(scr_stat *scp) * return NOKEY if there is nothing there. */ static u_int -scgetc(keyboard_t *kbd, u_int flags) +scgetc(sc_softc_t *sc, u_int flags) { + scr_stat *scp; u_int c; int this_scr; int f; int i; - if (kbd == NULL) + if (sc->kbd == NULL) return NOKEY; next_code: +#if 1 /* I don't like this, but... XXX */ if (flags & SCGETC_CN) - sccnupdate(cur_console); + sccnupdate(sc->cur_scp); +#endif + scp = sc->cur_scp; /* first see if there is something in the keyboard port */ for (;;) { - c = kbd_read_char(kbd, !(flags & SCGETC_NONBLOCK)); + c = kbd_read_char(sc->kbd, !(flags & SCGETC_NONBLOCK)); if (c == ERRKEY) { if (!(flags & SCGETC_CN)) - do_bell(cur_console, BELL_PITCH, BELL_DURATION); + do_bell(scp, bios_value.bell_pitch, BELL_DURATION); } else if (c == NOKEY) return c; else @@ -3542,81 +3618,67 @@ next_code: add_keyboard_randomness(c); #endif - if (cur_console->kbd_mode != K_XLATE) + if (scp->kbd_mode != K_XLATE) return KEYCHAR(c); /* if scroll-lock pressed allow history browsing */ - if (!ISGRAPHSC(cur_console) && cur_console->history - && cur_console->status & SLKED) { - - cur_console->status &= ~CURSOR_ENABLED; - if (!(cur_console->status & BUFFER_SAVED)) { - cur_console->status |= BUFFER_SAVED; - cur_console->history_save = cur_console->history_head; - - /* copy screen into top of history buffer */ - for (i=0; i<cur_console->ysize; i++) { - bcopy(cur_console->scr_buf + (cur_console->xsize * i), - cur_console->history_head, - cur_console->xsize * sizeof(u_short)); - cur_console->history_head += cur_console->xsize; - if (cur_console->history_head + cur_console->xsize > - cur_console->history + cur_console->history_size) - cur_console->history_head=cur_console->history; - } - cur_console->history_pos = cur_console->history_head; - history_to_screen(cur_console); + if (!ISGRAPHSC(scp) && scp->history && scp->status & SLKED) { + + scp->status &= ~CURSOR_ENABLED; + remove_cursor_image(scp); + +#ifndef SC_NO_HISTORY + if (!(scp->status & BUFFER_SAVED)) { + scp->status |= BUFFER_SAVED; + sc_hist_save(scp); } switch (c) { /* FIXME: key codes */ case SPCLKEY | FKEY | F(49): /* home key */ - remove_cutmarking(cur_console); - cur_console->history_pos = cur_console->history_head; - history_to_screen(cur_console); + sc_remove_cutmarking(scp); + sc_hist_home(scp); goto next_code; case SPCLKEY | FKEY | F(57): /* end key */ - remove_cutmarking(cur_console); - cur_console->history_pos = - WRAPHIST(cur_console, cur_console->history_head, - cur_console->xsize*cur_console->ysize); - history_to_screen(cur_console); + sc_remove_cutmarking(scp); + sc_hist_end(scp); goto next_code; case SPCLKEY | FKEY | F(50): /* up arrow key */ - remove_cutmarking(cur_console); - if (history_up_line(cur_console)) + sc_remove_cutmarking(scp); + if (sc_hist_up_line(scp)) if (!(flags & SCGETC_CN)) - do_bell(cur_console, BELL_PITCH, BELL_DURATION); + do_bell(scp, bios_value.bell_pitch, BELL_DURATION); goto next_code; case SPCLKEY | FKEY | F(58): /* down arrow key */ - remove_cutmarking(cur_console); - if (history_down_line(cur_console)) + sc_remove_cutmarking(scp); + if (sc_hist_down_line(scp)) if (!(flags & SCGETC_CN)) - do_bell(cur_console, BELL_PITCH, BELL_DURATION); + do_bell(scp, bios_value.bell_pitch, BELL_DURATION); goto next_code; case SPCLKEY | FKEY | F(51): /* page up key */ - remove_cutmarking(cur_console); - for (i=0; i<cur_console->ysize; i++) - if (history_up_line(cur_console)) { + sc_remove_cutmarking(scp); + for (i=0; i<scp->ysize; i++) + if (sc_hist_up_line(scp)) { if (!(flags & SCGETC_CN)) - do_bell(cur_console, BELL_PITCH, BELL_DURATION); + do_bell(scp, bios_value.bell_pitch, BELL_DURATION); break; } goto next_code; case SPCLKEY | FKEY | F(59): /* page down key */ - remove_cutmarking(cur_console); - for (i=0; i<cur_console->ysize; i++) - if (history_down_line(cur_console)) { + sc_remove_cutmarking(scp); + for (i=0; i<scp->ysize; i++) + if (sc_hist_down_line(scp)) { if (!(flags & SCGETC_CN)) - do_bell(cur_console, BELL_PITCH, BELL_DURATION); + do_bell(scp, bios_value.bell_pitch, BELL_DURATION); break; } goto next_code; } +#endif /* SC_NO_HISTORY */ } /* @@ -3635,33 +3697,22 @@ next_code: case NLK: case CLK: case ALK: break; case SLK: - kbd_ioctl(kbd, KDGKBSTATE, (caddr_t)&f); + kbd_ioctl(sc->kbd, KDGKBSTATE, (caddr_t)&f); if (f & SLKED) { - cur_console->status |= SLKED; + scp->status |= SLKED; } else { - if (cur_console->status & SLKED) { - cur_console->status &= ~SLKED; - if (cur_console->status & BUFFER_SAVED) { - int i; - u_short *ptr = cur_console->history_save; - - for (i=0; i<cur_console->ysize; i++) { - bcopy(ptr, - cur_console->scr_buf + - (cur_console->xsize*i), - cur_console->xsize * sizeof(u_short)); - ptr += cur_console->xsize; - if (ptr + cur_console->xsize > - cur_console->history + - cur_console->history_size) - ptr = cur_console->history; - } - cur_console->status &= ~BUFFER_SAVED; - cur_console->history_head=cur_console->history_save; - cur_console->status |= CURSOR_ENABLED; - mark_all(cur_console); + if (scp->status & SLKED) { + scp->status &= ~SLKED; +#ifndef SC_NO_HISTORY + if (scp->status & BUFFER_SAVED) { + if (!sc_hist_restore(scp)) + sc_remove_cutmarking(scp); + scp->status &= ~BUFFER_SAVED; + scp->status |= CURSOR_ENABLED; + draw_cursor_image(scp); } - scstart(VIRTUAL_TTY(get_scr_num())); +#endif + scstart(VIRTUAL_TTY(sc, scp->index)); } } break; @@ -3673,27 +3724,29 @@ next_code: break; case BTAB: - return c; + if (!(sc->flags & SC_SCRN_BLANKED)) + return c; + break; case SPSC: +#if NSPLASH > 0 /* force activatation/deactivation of the screen saver */ - if (!scrn_blanked) { + if (!(sc->flags & SC_SCRN_BLANKED)) { run_scrn_saver = TRUE; - scrn_time_stamp -= scrn_blank_time; + sc->scrn_time_stamp -= scrn_blank_time; } -#if NSPLASH > 0 if (cold) { /* * While devices are being probed, the screen saver need * to be invoked explictly. XXX */ - if (scrn_blanked) { + if (sc->flags & SC_SCRN_BLANKED) { scsplash_stick(FALSE); - stop_scrn_saver(current_saver); + stop_scrn_saver(sc, current_saver); } else { - if (!ISGRAPHSC(cur_console)) { + if (!ISGRAPHSC(scp)) { scsplash_stick(TRUE); - (*current_saver)(TRUE); + (*current_saver)(sc, TRUE); } } } @@ -3720,28 +3773,53 @@ next_code: #endif case DBG: -#ifdef DDB /* try to switch to console 0 */ - /* - * TRY to make sure the screen saver is stopped, - * and the screen is updated before switching to - * the vty0. - */ - scrn_timer((void *)FALSE); - if (cur_console->smode.mode == VT_AUTO && - console[0]->smode.mode == VT_AUTO) - switch_scr(cur_console, 0); +#ifndef SC_DISABLE_DDBKEY +#ifdef DDB + if (debugger) + break; + /* try to switch to the kernel console screen */ + if (sc_console) { + /* + * TRY to make sure the screen saver is stopped, + * and the screen is updated before switching to + * the vty0. + */ + scrn_timer(NULL); + if (!cold + && sc_console->sc->cur_scp->smode.mode == VT_AUTO + && sc_console->smode.mode == VT_AUTO) + switch_scr(sc_console->sc, sc_console->index); + } Debugger("manual escape to debugger"); #else printf("No debugger in kernel\n"); #endif +#else /* SC_DISABLE_DDBKEY */ + /* do nothing */ +#endif /* SC_DISABLE_DDBKEY */ break; case NEXT: - this_scr = get_scr_num(); - for (i = this_scr + 1; i != this_scr; i = (i + 1)%MAXCONS) { - struct tty *tp = VIRTUAL_TTY(i); + this_scr = scp->index; + for (i = (this_scr - sc->first_vty + 1)%sc->vtys; + sc->first_vty + i != this_scr; + i = (i + 1)%sc->vtys) { + struct tty *tp = VIRTUAL_TTY(sc, sc->first_vty + i); + if (tp->t_state & TS_ISOPEN) { + switch_scr(scp->sc, sc->first_vty + i); + break; + } + } + break; + + case PREV: + this_scr = scp->index; + for (i = (this_scr - sc->first_vty + sc->vtys - 1)%sc->vtys; + sc->first_vty + i != this_scr; + i = (i + sc->vtys - 1)%sc->vtys) { + struct tty *tp = VIRTUAL_TTY(sc, sc->first_vty + i); if (tp->t_state & TS_ISOPEN) { - switch_scr(cur_console, i); + switch_scr(scp->sc, sc->first_vty + i); break; } } @@ -3749,16 +3827,19 @@ next_code: default: if (KEYCHAR(c) >= F_SCR && KEYCHAR(c) <= L_SCR) { - switch_scr(cur_console, KEYCHAR(c) - F_SCR); + switch_scr(scp->sc, sc->first_vty + KEYCHAR(c) - F_SCR); break; } /* assert(c & FKEY) */ - return c; + if (!(sc->flags & SC_SCRN_BLANKED)) + return c; + break; } /* goto next_code */ } else { /* regular keys (maybe MKEY is set) */ - return c; + if (!(sc->flags & SC_SCRN_BLANKED)) + return c; } } @@ -3775,7 +3856,7 @@ scmmap(dev_t dev, vm_offset_t offset, int nprot) if (!tp) return ENXIO; scp = sc_get_scr_stat(tp->t_dev); - return (*vidsw[scp->ad]->mmap)(scp->adp, offset); + return (*vidsw[scp->sc->adapter]->mmap)(scp->sc->adp, offset, nprot); } /* @@ -3813,7 +3894,7 @@ save_kbd_state(scr_stat *scp) int state; int error; - error = kbd_ioctl(kbd, KDGKBSTATE, (caddr_t)&state); + error = kbd_ioctl(scp->sc->kbd, KDGKBSTATE, (caddr_t)&state); if (error == ENOIOCTL) error = ENODEV; if (error == 0) { @@ -3824,13 +3905,13 @@ save_kbd_state(scr_stat *scp) } static int -update_kbd_state(int new_bits, int mask) +update_kbd_state(scr_stat *scp, int new_bits, int mask) { int state; int error; if (mask != LOCK_MASK) { - error = kbd_ioctl(kbd, KDGKBSTATE, (caddr_t)&state); + error = kbd_ioctl(scp->sc->kbd, KDGKBSTATE, (caddr_t)&state); if (error == ENOIOCTL) error = ENODEV; if (error) @@ -3840,19 +3921,19 @@ update_kbd_state(int new_bits, int mask) } else { state = new_bits & LOCK_MASK; } - error = kbd_ioctl(kbd, KDSKBSTATE, (caddr_t)&state); + error = kbd_ioctl(scp->sc->kbd, KDSKBSTATE, (caddr_t)&state); if (error == ENOIOCTL) error = ENODEV; return error; } static int -update_kbd_leds(int which) +update_kbd_leds(scr_stat *scp, int which) { int error; which &= LOCK_MASK; - error = kbd_ioctl(kbd, KDSETLED, (caddr_t)&which); + error = kbd_ioctl(scp->sc->kbd, KDSETLED, (caddr_t)&which); if (error == ENOIOCTL) error = ENODEV; return error; @@ -3864,28 +3945,31 @@ set_mode(scr_stat *scp) video_info_t info; /* reject unsupported mode */ - if ((*vidsw[scp->ad]->get_info)(scp->adp, scp->mode, &info)) + if ((*vidsw[scp->sc->adapter]->get_info)(scp->sc->adp, scp->mode, &info)) return 1; /* if this vty is not currently showing, do nothing */ - if (scp != cur_console) + if (scp != scp->sc->cur_scp) return 0; /* setup video hardware for the given mode */ - (*vidsw[scp->ad]->set_mode)(scp->adp, scp->mode); + (*vidsw[scp->sc->adapter]->set_mode)(scp->sc->adp, scp->mode); + sc_vtb_init(&scp->scr, VTB_FRAMEBUFFER, scp->xsize, scp->ysize, + (void *)scp->sc->adp->va_window, FALSE); +#ifndef SC_NO_FONT_LOADING + /* load appropriate font */ if (!(scp->status & GRAPHICS_MODE)) { - /* load appropriate font */ - if (!(scp->status & PIXEL_MODE) && ISFONTAVAIL(scp->adp->va_flags)) { + if (!(scp->status & PIXEL_MODE) && ISFONTAVAIL(scp->sc->adp->va_flags)) { if (scp->font_size < 14) { - if (fonts_loaded & FONT_8) - copy_font(scp, LOAD, 8, font_8); + if (scp->sc->fonts_loaded & FONT_8) + copy_font(scp, LOAD, 8, scp->sc->font_8); } else if (scp->font_size >= 16) { - if (fonts_loaded & FONT_16) - copy_font(scp, LOAD, 16, font_16); + if (scp->sc->fonts_loaded & FONT_16) + copy_font(scp, LOAD, 16, scp->sc->font_16); } else { - if (fonts_loaded & FONT_14) - copy_font(scp, LOAD, 14, font_14); + if (scp->sc->fonts_loaded & FONT_14) + copy_font(scp, LOAD, 14, scp->sc->font_14); } /* * FONT KLUDGE: @@ -3894,18 +3978,14 @@ set_mode(scr_stat *scp) * Somehow we cannot show the font in other font pages on * some video cards... XXX */ - (*vidsw[scp->ad]->show_font)(scp->adp, 0); + (*vidsw[scp->sc->adapter]->show_font)(scp->sc->adp, 0); } mark_all(scp); } - - if (scp->status & PIXEL_MODE) - bzero_io(scp->adp->va_window, scp->xpixel*scp->ypixel/8); +#endif /* !SC_NO_FONT_LOADING */ set_border(scp, scp->border); - - /* move hardware cursor out of the way */ - (*vidsw[scp->ad]->set_hw_cursor)(scp->adp, -1, -1); + sc_set_cursor_image(scp); return 0; } @@ -3913,43 +3993,12 @@ set_mode(scr_stat *scp) void set_border(scr_stat *scp, int color) { - vm_offset_t p; - int xoff; - int yoff; - int xlen; - int ylen; - int i; - - (*vidsw[scp->ad]->set_border)(scp->adp, color); - - if (scp->status & PIXEL_MODE) { - outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */ - outw(GDCIDX, 0x0003); /* data rotate/function select */ - outw(GDCIDX, 0x0f01); /* set/reset enable */ - outw(GDCIDX, 0xff08); /* bit mask */ - outw(GDCIDX, (color << 8) | 0x00); /* set/reset */ - p = scp->adp->va_window; - xoff = scp->xoff; - yoff = scp->yoff*scp->font_size; - xlen = scp->xpixel/8; - ylen = scp->ysize*scp->font_size; - if (yoff > 0) { - bzero_io(p, xlen*yoff); - bzero_io(p + xlen*(yoff + ylen), - xlen*scp->ypixel - xlen*(yoff + ylen)); - } - if (xoff > 0) { - for (i = 0; i < ylen; ++i) { - bzero_io(p + xlen*(yoff + i), xoff); - bzero_io(p + xlen*(yoff + i) + xoff + scp->xsize, - xlen - xoff - scp->xsize); - } - } - outw(GDCIDX, 0x0000); /* set/reset */ - outw(GDCIDX, 0x0001); /* set/reset enable */ - } + ++scp->sc->videoio_in_progress; + (*scp->rndr->draw_border)(scp, color); + --scp->sc->videoio_in_progress; } +#ifndef SC_NO_FONT_LOADING void copy_font(scr_stat *scp, int operation, int font_size, u_char *buf) { @@ -3960,450 +4009,41 @@ copy_font(scr_stat *scp, int operation, int font_size, u_char *buf) * Somehow we cannot show the font in other font pages on * some video cards... XXX */ - font_loading_in_progress = TRUE; + scp->sc->font_loading_in_progress = TRUE; if (operation == LOAD) { - (*vidsw[scp->ad]->load_font)(scp->adp, 0, font_size, buf, 0, 256); - if (sc_flags & CHAR_CURSOR) - set_destructive_cursor(scp); + (*vidsw[scp->sc->adapter]->load_font)(scp->sc->adp, 0, font_size, + buf, 0, 256); } else if (operation == SAVE) { - (*vidsw[scp->ad]->save_font)(scp->adp, 0, font_size, buf, 0, 256); + (*vidsw[scp->sc->adapter]->save_font)(scp->sc->adp, 0, font_size, + buf, 0, 256); } - font_loading_in_progress = FALSE; + scp->sc->font_loading_in_progress = FALSE; } +#endif /* !SC_NO_FONT_LOADING */ -static void -set_destructive_cursor(scr_stat *scp) +#ifndef SC_NO_SYSMOUSE +struct tty +*sc_get_mouse_tty(void) { - u_char cursor[32]; - u_char *font_buffer; - int font_size; - int crtc_addr; - int i; - - if (!ISFONTAVAIL(scp->adp->va_flags) - || (scp->status & (GRAPHICS_MODE | PIXEL_MODE))) - return; - - if (scp->font_size < 14) { - font_buffer = font_8; - font_size = 8; - } else if (scp->font_size >= 16) { - font_buffer = font_16; - font_size = 16; - } else { - font_buffer = font_14; - font_size = 14; - } - - if (scp->status & MOUSE_VISIBLE) { - if ((scp->cursor_saveunder & 0xff) == SC_MOUSE_CHAR) - bcopy(&scp->mouse_cursor[0], cursor, scp->font_size); - else if ((scp->cursor_saveunder & 0xff) == SC_MOUSE_CHAR + 1) - bcopy(&scp->mouse_cursor[32], cursor, scp->font_size); - else if ((scp->cursor_saveunder & 0xff) == SC_MOUSE_CHAR + 2) - bcopy(&scp->mouse_cursor[64], cursor, scp->font_size); - else if ((scp->cursor_saveunder & 0xff) == SC_MOUSE_CHAR + 3) - bcopy(&scp->mouse_cursor[96], cursor, scp->font_size); - else - bcopy(font_buffer+((scp->cursor_saveunder & 0xff)*scp->font_size), - cursor, scp->font_size); - } - else - bcopy(font_buffer + ((scp->cursor_saveunder & 0xff) * scp->font_size), - cursor, scp->font_size); - for (i=0; i<32; i++) - if ((i >= scp->cursor_start && i <= scp->cursor_end) || - (scp->cursor_start >= scp->font_size && i == scp->font_size - 1)) - cursor[i] |= 0xff; -#if 1 - crtc_addr = scp->adp->va_crtc_addr; - while (!(inb(crtc_addr+6) & 0x08)) /* wait for vertical retrace */ ; -#endif - font_loading_in_progress = TRUE; - (*vidsw[scp->ad]->load_font)(scp->adp, 0, font_size, cursor, DEAD_CHAR, 1); - font_loading_in_progress = FALSE; + return MOUSE_TTY; } +#endif /* !SC_NO_SYSMOUSE */ +#ifndef SC_NO_CUTPASTE void -sc_move_mouse(scr_stat *scp, int x, int y) +sc_paste(scr_stat *scp, u_char *p, int count) { - scp->mouse_xpos = x; - scp->mouse_ypos = y; - scp->mouse_pos = scp->mouse_oldpos = - scp->scr_buf + (y / scp->font_size) * scp->xsize + x / 8; -} - -static void -set_mouse_pos(scr_stat *scp) -{ - static int last_xpos = -1, last_ypos = -1; - - if (scp->mouse_xpos < 0) - scp->mouse_xpos = 0; - if (scp->mouse_ypos < 0) - scp->mouse_ypos = 0; - if (!ISTEXTSC(scp)) { - if (scp->mouse_xpos > scp->xpixel-1) - scp->mouse_xpos = scp->xpixel-1; - if (scp->mouse_ypos > scp->ypixel-1) - scp->mouse_ypos = scp->ypixel-1; - return; - } - if (scp->mouse_xpos > (scp->xsize*8)-1) - scp->mouse_xpos = (scp->xsize*8)-1; - if (scp->mouse_ypos > (scp->ysize*scp->font_size)-1) - scp->mouse_ypos = (scp->ysize*scp->font_size)-1; - - if (scp->mouse_xpos != last_xpos || scp->mouse_ypos != last_ypos) { - scp->status |= MOUSE_MOVED; - - scp->mouse_pos = scp->scr_buf + - ((scp->mouse_ypos/scp->font_size)*scp->xsize + scp->mouse_xpos/8); - - if ((scp->status & MOUSE_VISIBLE) && (scp->status & MOUSE_CUTTING)) - mouse_cut(scp); - } -} - -#define isspace(c) (((c) & 0xff) == ' ') - -static int -skip_spc_right(scr_stat *scp, u_short *p) -{ - int i; - - for (i = (p - scp->scr_buf) % scp->xsize; i < scp->xsize; ++i) { - if (!isspace(*p)) - break; - ++p; - } - return i; -} - -static int -skip_spc_left(scr_stat *scp, u_short *p) -{ - int i; - - for (i = (p-- - scp->scr_buf) % scp->xsize - 1; i >= 0; --i) { - if (!isspace(*p)) - break; - --p; - } - return i; -} - -static void -mouse_cut(scr_stat *scp) -{ - u_short *end; - u_short *p; - int i = 0; - int j = 0; - - scp->mouse_cut_end = (scp->mouse_pos >= scp->mouse_cut_start) ? - scp->mouse_pos + 1 : scp->mouse_pos; - end = (scp->mouse_cut_start > scp->mouse_cut_end) ? - scp->mouse_cut_start : scp->mouse_cut_end; - for (p = (scp->mouse_cut_start > scp->mouse_cut_end) ? - scp->mouse_cut_end : scp->mouse_cut_start; p < end; ++p) { - cut_buffer[i] = *p & 0xff; - /* remember the position of the last non-space char */ - if (!isspace(cut_buffer[i++])) - j = i; - /* trim trailing blank when crossing lines */ - if (((p - scp->scr_buf) % scp->xsize) == (scp->xsize - 1)) { - cut_buffer[j++] = '\r'; - i = j; - } - } - cut_buffer[i] = '\0'; - - /* scan towards the end of the last line */ - --p; - for (i = (p - scp->scr_buf) % scp->xsize; i < scp->xsize; ++i) { - if (!isspace(*p)) - break; - ++p; - } - /* if there is nothing but blank chars, trim them, but mark towards eol */ - if (i >= scp->xsize) { - if (scp->mouse_cut_start > scp->mouse_cut_end) - scp->mouse_cut_start = p; - else - scp->mouse_cut_end = p; - cut_buffer[j++] = '\r'; - cut_buffer[j] = '\0'; - } - - mark_for_update(scp, scp->mouse_cut_start - scp->scr_buf); - mark_for_update(scp, scp->mouse_cut_end - scp->scr_buf); -} - -static void -mouse_cut_start(scr_stat *scp) -{ - int i; - - if (scp->status & MOUSE_VISIBLE) { - if (scp->mouse_pos == scp->mouse_cut_start && - scp->mouse_cut_start == scp->mouse_cut_end - 1) { - cut_buffer[0] = '\0'; - remove_cutmarking(scp); - } else if (skip_spc_right(scp, scp->mouse_pos) >= scp->xsize) { - /* if the pointer is on trailing blank chars, mark towards eol */ - i = skip_spc_left(scp, scp->mouse_pos) + 1; - scp->mouse_cut_start = scp->scr_buf + - ((scp->mouse_pos - scp->scr_buf) / scp->xsize) * scp->xsize + i; - scp->mouse_cut_end = scp->scr_buf + - ((scp->mouse_pos - scp->scr_buf) / scp->xsize + 1) * scp->xsize; - cut_buffer[0] = '\r'; - cut_buffer[1] = '\0'; - scp->status |= MOUSE_CUTTING; - } else { - scp->mouse_cut_start = scp->mouse_pos; - scp->mouse_cut_end = scp->mouse_cut_start + 1; - cut_buffer[0] = *scp->mouse_cut_start & 0xff; - cut_buffer[1] = '\0'; - scp->status |= MOUSE_CUTTING; - } - mark_all(scp); - /* delete all other screens cut markings */ - for (i=0; i<MAXCONS; i++) { - if (console[i] == NULL || console[i] == scp) - continue; - remove_cutmarking(console[i]); - } - } -} - -static void -mouse_cut_end(scr_stat *scp) -{ - if (scp->status & MOUSE_VISIBLE) { - scp->status &= ~MOUSE_CUTTING; - } -} - -static void -mouse_cut_word(scr_stat *scp) -{ - u_short *p; - u_short *sol; - u_short *eol; - int i; - - /* - * Because we don't have locale information in the kernel, - * we only distinguish space char and non-space chars. Punctuation - * chars, symbols and other regular chars are all treated alike. - */ - if (scp->status & MOUSE_VISIBLE) { - sol = scp->scr_buf - + ((scp->mouse_pos - scp->scr_buf) / scp->xsize) * scp->xsize; - eol = sol + scp->xsize; - if (isspace(*scp->mouse_pos)) { - for (p = scp->mouse_pos; p >= sol; --p) - if (!isspace(*p)) - break; - scp->mouse_cut_start = ++p; - for (p = scp->mouse_pos; p < eol; ++p) - if (!isspace(*p)) - break; - scp->mouse_cut_end = p; - } else { - for (p = scp->mouse_pos; p >= sol; --p) - if (isspace(*p)) - break; - scp->mouse_cut_start = ++p; - for (p = scp->mouse_pos; p < eol; ++p) - if (isspace(*p)) - break; - scp->mouse_cut_end = p; - } - for (i = 0, p = scp->mouse_cut_start; p < scp->mouse_cut_end; ++p) - cut_buffer[i++] = *p & 0xff; - cut_buffer[i] = '\0'; - scp->status |= MOUSE_CUTTING; - } -} - -static void -mouse_cut_line(scr_stat *scp) -{ - u_short *p; - int i; - - if (scp->status & MOUSE_VISIBLE) { - scp->mouse_cut_start = scp->scr_buf - + ((scp->mouse_pos - scp->scr_buf) / scp->xsize) * scp->xsize; - scp->mouse_cut_end = scp->mouse_cut_start + scp->xsize; - for (i = 0, p = scp->mouse_cut_start; p < scp->mouse_cut_end; ++p) - cut_buffer[i++] = *p & 0xff; - cut_buffer[i++] = '\r'; - cut_buffer[i] = '\0'; - scp->status |= MOUSE_CUTTING; - } -} - -static void -mouse_cut_extend(scr_stat *scp) -{ - if ((scp->status & MOUSE_VISIBLE) && !(scp->status & MOUSE_CUTTING) - && (scp->mouse_cut_start != NULL)) { - mouse_cut(scp); - scp->status |= MOUSE_CUTTING; - } -} + struct tty *tp; + u_char *rmap; -static void -mouse_paste(scr_stat *scp) -{ if (scp->status & MOUSE_VISIBLE) { - struct tty *tp; - u_char *ptr = cut_buffer; - - tp = VIRTUAL_TTY(get_scr_num()); - while (*ptr) - (*linesw[tp->t_line].l_rint)(scr_rmap[*ptr++], tp); - } -} - -static void -draw_mouse_image(scr_stat *scp) -{ - u_short buffer[32]; - u_short xoffset, yoffset; - vm_offset_t crt_pos = scp->adp->va_window + 2*(scp->mouse_pos - scp->scr_buf); - u_char *font_buffer; - int font_size; - int crtc_addr; - int i; - - if (scp->font_size < 14) { - font_buffer = font_8; - font_size = 8; - } else if (scp->font_size >= 16) { - font_buffer = font_16; - font_size = 16; - } else { - font_buffer = font_14; - font_size = 14; - } - - xoffset = scp->mouse_xpos % 8; - yoffset = scp->mouse_ypos % scp->font_size; - - /* prepare mousepointer char's bitmaps */ - bcopy(font_buffer + ((*(scp->mouse_pos) & 0xff) * font_size), - &scp->mouse_cursor[0], font_size); - bcopy(font_buffer + ((*(scp->mouse_pos+1) & 0xff) * font_size), - &scp->mouse_cursor[32], font_size); - bcopy(font_buffer + ((*(scp->mouse_pos+scp->xsize) & 0xff) * font_size), - &scp->mouse_cursor[64], font_size); - bcopy(font_buffer + ((*(scp->mouse_pos+scp->xsize+1) & 0xff) * font_size), - &scp->mouse_cursor[96], font_size); - for (i=0; i<font_size; i++) { - buffer[i] = scp->mouse_cursor[i]<<8 | scp->mouse_cursor[i+32]; - buffer[i+font_size]=scp->mouse_cursor[i+64]<<8|scp->mouse_cursor[i+96]; - } - - /* now and-or in the mousepointer image */ - for (i=0; i<16; i++) { - buffer[i+yoffset] = - ( buffer[i+yoffset] & ~(mouse_and_mask[i] >> xoffset)) - | (mouse_or_mask[i] >> xoffset); - } - for (i=0; i<font_size; i++) { - scp->mouse_cursor[i] = (buffer[i] & 0xff00) >> 8; - scp->mouse_cursor[i+32] = buffer[i] & 0xff; - scp->mouse_cursor[i+64] = (buffer[i+font_size] & 0xff00) >> 8; - scp->mouse_cursor[i+96] = buffer[i+font_size] & 0xff; - } - - scp->mouse_oldpos = scp->mouse_pos; - -#if 1 - /* wait for vertical retrace to avoid jitter on some videocards */ - crtc_addr = scp->adp->va_crtc_addr; - while (!(inb(crtc_addr+6) & 0x08)) /* idle */ ; -#endif - font_loading_in_progress = TRUE; - (*vidsw[scp->ad]->load_font)(scp->adp, 0, 32, scp->mouse_cursor, - SC_MOUSE_CHAR, 4); - font_loading_in_progress = FALSE; - - writew(crt_pos, (*(scp->mouse_pos) & 0xff00) | SC_MOUSE_CHAR); - writew(crt_pos+2*scp->xsize, - (*(scp->mouse_pos + scp->xsize) & 0xff00) | (SC_MOUSE_CHAR + 2)); - if (scp->mouse_xpos < (scp->xsize-1)*8) { - writew(crt_pos + 2, (*(scp->mouse_pos + 1) & 0xff00) | (SC_MOUSE_CHAR + 1)); - writew(crt_pos+2*scp->xsize + 2, - (*(scp->mouse_pos + scp->xsize + 1) & 0xff00) | (SC_MOUSE_CHAR + 3)); - } - mark_for_update(scp, scp->mouse_pos - scp->scr_buf); - mark_for_update(scp, scp->mouse_pos + scp->xsize + 1 - scp->scr_buf); -} - -static void -remove_mouse_image(scr_stat *scp) -{ - vm_offset_t crt_pos; - - if (!ISTEXTSC(scp)) - return; - - crt_pos = scp->adp->va_window + 2*(scp->mouse_oldpos - scp->scr_buf); - writew(crt_pos, *(scp->mouse_oldpos)); - writew(crt_pos+2, *(scp->mouse_oldpos+1)); - writew(crt_pos+2*scp->xsize, *(scp->mouse_oldpos+scp->xsize)); - writew(crt_pos+2*scp->xsize+2, *(scp->mouse_oldpos+scp->xsize+1)); - mark_for_update(scp, scp->mouse_oldpos - scp->scr_buf); - mark_for_update(scp, scp->mouse_oldpos + scp->xsize + 1 - scp->scr_buf); -} - -static void -draw_cutmarking(scr_stat *scp) -{ - vm_offset_t crt_pos; - u_short *ptr; - u_short och, nch; - - crt_pos = scp->adp->va_window; - for (ptr=scp->scr_buf; ptr<=(scp->scr_buf+(scp->xsize*scp->ysize)); ptr++) { - nch = och = readw(crt_pos + 2*(ptr - scp->scr_buf)); - /* are we outside the selected area ? */ - if ( ptr < (scp->mouse_cut_start > scp->mouse_cut_end ? - scp->mouse_cut_end : scp->mouse_cut_start) || - ptr >= (scp->mouse_cut_start > scp->mouse_cut_end ? - scp->mouse_cut_start : scp->mouse_cut_end)) { - if (ptr != scp->cursor_pos) - nch = (och & 0xff) | (*ptr & 0xff00); - } - else { - /* are we clear of the cursor image ? */ - if (ptr != scp->cursor_pos) - nch = (och & 0x88ff) | (*ptr & 0x7000)>>4 | (*ptr & 0x0700)<<4; - else { - if (sc_flags & CHAR_CURSOR) - nch = (och & 0x88ff)|(*ptr & 0x7000)>>4|(*ptr & 0x0700)<<4; - else - if (!(sc_flags & BLINK_CURSOR)) - nch = (och & 0xff) | (*ptr & 0xff00); - } - } - if (nch != och) - writew(crt_pos + 2*(ptr - scp->scr_buf), nch); + tp = VIRTUAL_TTY(scp->sc, scp->sc->cur_scp->index); + rmap = scp->sc->scr_rmap; + for (; count > 0; --count) + (*linesw[tp->t_line].l_rint)(rmap[*p++], tp); } } - -static void -remove_cutmarking(scr_stat *scp) -{ - scp->mouse_cut_start = scp->mouse_cut_end = NULL; - scp->status &= ~MOUSE_CUTTING; - mark_all(scp); -} +#endif /* SC_NO_CUTPASTE */ static void do_bell(scr_stat *scp, int pitch, int duration) @@ -4411,18 +4051,18 @@ do_bell(scr_stat *scp, int pitch, int duration) if (cold || shutdown_in_progress) return; - if (scp != cur_console && (sc_flags & QUIET_BELL)) + if (scp != scp->sc->cur_scp && (scp->sc->flags & SC_QUIET_BELL)) return; - if (sc_flags & VISUAL_BELL) { - if (blink_in_progress) + if (scp->sc->flags & SC_VISUAL_BELL) { + if (scp->sc->blink_in_progress) return; - blink_in_progress = 4; - if (scp != cur_console) - blink_in_progress += 2; - blink_screen(cur_console); + scp->sc->blink_in_progress = 3; + if (scp != scp->sc->cur_scp) + scp->sc->blink_in_progress += 2; + blink_screen(scp->sc->cur_scp); } else { - if (scp != cur_console) + if (scp != scp->sc->cur_scp) pitch *= 2; sysbeep(pitch, duration); } @@ -4433,122 +4073,19 @@ blink_screen(void *arg) { scr_stat *scp = arg; - if (!ISTEXTSC(scp) || (blink_in_progress <= 1)) { - blink_in_progress = FALSE; + if (ISGRAPHSC(scp) || (scp->sc->blink_in_progress <= 1)) { + scp->sc->blink_in_progress = 0; mark_all(scp); - if (delayed_next_scr) - switch_scr(scp, delayed_next_scr - 1); + scstart(VIRTUAL_TTY(scp->sc, scp->index)); + if (scp->sc->delayed_next_scr) + switch_scr(scp->sc, scp->sc->delayed_next_scr - 1); } else { - if (blink_in_progress & 1) - fillw_io(kernel_default.std_color | scr_map[0x20], - scp->adp->va_window, - scp->xsize * scp->ysize); - else - fillw_io(kernel_default.rev_color | scr_map[0x20], - scp->adp->va_window, - scp->xsize * scp->ysize); - blink_in_progress--; + (*scp->rndr->draw)(scp, 0, scp->xsize*scp->ysize, + scp->sc->blink_in_progress & 1); + scp->sc->blink_in_progress--; timeout(blink_screen, scp, hz / 10); } } -void -sc_bcopy(scr_stat *scp, u_short *p, int from, int to, int mark) -{ - u_char *font; - vm_offset_t d; - vm_offset_t e; - u_char *f; - int font_size; - int line_length; - int xsize; - u_short bg; - int i, j; - u_char c; - - if (ISTEXTSC(scp)) { - bcopy_toio(p + from, scp->adp->va_window + 2*from, - (to - from + 1)*sizeof(u_short)); - } else /* if ISPIXELSC(scp) */ { - if (mark) - mark = 255; - font_size = scp->font_size; - if (font_size < 14) - font = font_8; - else if (font_size >= 16) - font = font_16; - else - font = font_14; - line_length = scp->xpixel/8; - xsize = scp->xsize; - d = scp->adp->va_window - + scp->xoff + scp->yoff*font_size*line_length - + (from%xsize) + font_size*line_length*(from/xsize); - - outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */ - outw(GDCIDX, 0x0003); /* data rotate/function select */ - outw(GDCIDX, 0x0f01); /* set/reset enable */ - bg = -1; - for (i = from ; i <= to ; i++) { - /* set background color in EGA/VGA latch */ - if (bg != (p[i] & 0xf000)) { - bg = (p[i] & 0xf000); - outw(GDCIDX, (bg >> 4) | 0x00); /* set/reset */ - outw(GDCIDX, 0xff08); /* bit mask */ - writeb(d, 0); - c = readb(d); /* set the background color in the latch */ - } - /* foreground color */ - outw(GDCIDX, (p[i] & 0x0f00) | 0x00); /* set/reset */ - e = d; - f = &font[(p[i] & 0x00ff)*font_size]; - for (j = 0 ; j < font_size; j++, f++) { - outw(GDCIDX, ((*f^mark) << 8) | 0x08); /* bit mask */ - writeb(e, 0); - e += line_length; - } - d++; - if ((i % xsize) == xsize - 1) - d += scp->xoff*2 + (font_size - 1)*line_length; - } - outw(GDCIDX, 0x0000); /* set/reset */ - outw(GDCIDX, 0x0001); /* set/reset enable */ - outw(GDCIDX, 0xff08); /* bit mask */ - -#if 0 /* VGA only */ - outw(GDCIDX, 0x0305); /* read mode 0, write mode 3 */ - outw(GDCIDX, 0x0003); /* data rotate/function select */ - outw(GDCIDX, 0x0f01); /* set/reset enable */ - outw(GDCIDX, 0xff08); /* bit mask */ - bg = -1; - for (i = from ; i <= to ; i++) { - /* set background color in EGA/VGA latch */ - if (bg != (p[i] & 0xf000)) { - bg = (p[i] & 0xf000); - outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */ - outw(GDCIDX, (bg >> 4) | 0x00); /* set/reset */ - *d = 0; - c = *d; /* set the background color in the latch */ - outw(GDCIDX, 0x0305); /* read mode 0, write mode 3 */ - } - /* foreground color */ - outw(GDCIDX, (p[i] & 0x0f00) | 0x00); /* set/reset */ - e = (u_char *)d; - f = &font[(p[i] & 0x00ff)*font_size]; - for (j = 0 ; j < font_size; j++, f++) { - *e = *f^mark; - e += line_length; - } - d++; - if ((i % xsize) == xsize - 1) - d += scp->xoff*2 + (font_size - 1)*line_length; - } - outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */ - outw(GDCIDX, 0x0000); /* set/reset */ - outw(GDCIDX, 0x0001); /* set/reset enable */ -#endif /* 0 */ - } -} - #endif /* NSC */ diff --git a/sys/dev/syscons/syscons.h b/sys/dev/syscons/syscons.h index c8ba6cd..da48c7c 100644 --- a/sys/dev/syscons/syscons.h +++ b/sys/dev/syscons/syscons.h @@ -25,21 +25,51 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: syscons.h,v 1.46 1999/01/19 11:31:19 yokota Exp $ + * $Id: syscons.h,v 1.47 1999/04/12 13:34:56 des Exp $ */ #ifndef _DEV_SYSCONS_SYSCONS_H_ #define _DEV_SYSCONS_SYSCONS_H_ -/* vm things */ -#define ISMAPPED(pa, width) \ - (((pa) <= (u_long)0x1000 - (width)) \ - || ((pa) >= 0xa0000 && (pa) <= 0x100000 - (width))) -#define pa_to_va(pa) (KERNBASE + (pa)) /* works if ISMAPPED(pa...) */ +/* machine-dependent part of the header */ + +#ifdef PC98 +#include <pc98/pc98/sc_machdep.h> +#elif defined(__i386__) +/* nothing for the moment */ +#elif defined(__alpha__) +/* nothing for the moment */ +#endif + +/* default values for configuration options */ + +#ifndef MAXCONS +#define MAXCONS 16 +#endif + +#ifdef SC_NO_SYSMOUSE +#undef SC_NO_CUTPASTE +#define SC_NO_CUTPASTE 1 +#endif + +#ifdef SC_NO_MODE_CHANGE +#undef SC_PIXEL_MODE +#endif + +#ifndef SC_DEBUG_LEVEL +#define SC_DEBUG_LEVEL 0 +#endif + +#define DPRINTF(l, p) if (SC_DEBUG_LEVEL >= (l)) printf p + +#define SC_DRIVER_NAME "sc" +#define SC_VTY(dev) minor(dev) /* printable chars */ +#ifndef PRINTABLE #define PRINTABLE(ch) ((ch) > 0x1b || ((ch) > 0x0d && (ch) < 0x1b) \ || (ch) < 0x07) +#endif /* macros for "intelligent" screen update */ #define mark_for_update(scp, x) {\ @@ -51,33 +81,20 @@ scp->end = scp->xsize * scp->ysize - 1;\ } -/* status flags */ +/* vty status flags (scp->status) */ #define UNKNOWN_MODE 0x00010 #define SWITCH_WAIT_REL 0x00080 #define SWITCH_WAIT_ACQ 0x00100 #define BUFFER_SAVED 0x00200 #define CURSOR_ENABLED 0x00400 -#define MOUSE_ENABLED 0x00800 #define MOUSE_MOVED 0x01000 #define MOUSE_CUTTING 0x02000 #define MOUSE_VISIBLE 0x04000 #define GRAPHICS_MODE 0x08000 #define PIXEL_MODE 0x10000 #define SAVER_RUNNING 0x20000 - -/* configuration flags */ -#define VISUAL_BELL 0x00001 -#define BLINK_CURSOR 0x00002 -#define CHAR_CURSOR 0x00004 -/* these options are now obsolete; use corresponding options for kbd driver */ -#if 0 -#define DETECT_KBD 0x00008 -#define XT_KEYBD 0x00010 -#define KBD_NORESET 0x00020 -#endif -#define QUIET_BELL 0x00040 -#define VESA800X600 0x00080 -#define AUTODETECT_KBD 0x00100 +#define VR_CURSOR_BLINK 0x40000 +#define VR_CURSOR_ON 0x80000 /* attribute flags */ #define NORMAL_ATTR 0x00 @@ -96,8 +113,6 @@ #define SAVE 0 #define COL 80 #define ROW 25 -#define BELL_DURATION 5 -#define BELL_PITCH 800 #define CONSOLE_BUFSIZE 1024 #define PCBURST 128 #define FONT_NONE 1 @@ -105,6 +120,11 @@ #define FONT_14 4 #define FONT_16 8 +#ifndef BELL_DURATION +#define BELL_DURATION 5 +#define BELL_PITCH 800 +#endif + /* special characters */ #define cntlc 0x03 #define cntld 0x04 @@ -115,6 +135,23 @@ #define DEAD_CHAR 0x07 /* char used for cursor */ +/* virtual terminal buffer */ +typedef struct sc_vtb { + int vtb_flags; +#define VTB_VALID (1 << 0) + int vtb_type; +#define VTB_INVALID 0 +#define VTB_MEMORY 1 +#define VTB_FRAMEBUFFER 2 +#define VTB_RINGBUFFER 3 + int vtb_cols; + int vtb_rows; + int vtb_size; + vm_offset_t vtb_buffer; + int vtb_tail; /* valid for VTB_RINGBUFFER only */ +} sc_vtb_t; + +/* terminal status */ typedef struct term_stat { int esc; /* processing escape sequence */ int num_param; /* # of parameters to ESC */ @@ -127,10 +164,89 @@ typedef struct term_stat { int rev_color; /* reverse hardware color */ } term_stat; +/* softc */ + +struct keyboard; +struct video_adapter; +struct scr_stat; +struct tty; + +typedef struct sc_softc { + int unit; /* unit # */ + int config; /* configuration flags */ +#define SC_VESA800X600 (1 << 7) +#define SC_AUTODETECT_KBD (1 << 8) +#define SC_KERNEL_CONSOLE (1 << 9) + + int flags; /* status flags */ +#define SC_VISUAL_BELL (1 << 0) +#define SC_QUIET_BELL (1 << 1) +#define SC_BLINK_CURSOR (1 << 2) +#define SC_CHAR_CURSOR (1 << 3) +#define SC_MOUSE_ENABLED (1 << 4) +#define SC_SCRN_IDLE (1 << 5) +#define SC_SCRN_BLANKED (1 << 6) +#define SC_SAVER_FAILED (1 << 7) + +#define SC_INIT_DONE (1 << 16) +#define SC_SPLASH_SCRN (1 << 17) + + int keyboard; /* -1 if unavailable */ + struct keyboard *kbd; + + int adapter; + struct video_adapter *adp; + int initial_mode; /* initial video mode */ + + int first_vty; + int vtys; + struct tty *tty; + struct scr_stat **console; + struct scr_stat *cur_scp; + struct scr_stat *new_scp; + struct scr_stat *old_scp; + int delayed_next_scr; + + void **devfs_token; + + char font_loading_in_progress; + char switch_in_progress; + char videoio_in_progress; + char write_in_progress; + char blink_in_progress; + + long scrn_time_stamp; + + char cursor_base; + char cursor_height; + + u_char scr_map[256]; + u_char scr_rmap[256]; + +#ifdef _SC_MD_SOFTC_DECLARED_ + sc_md_softc_t md; /* machine dependent vars */ +#endif + +#ifndef SC_NO_PALETTE_LOADING + u_char palette[256*3]; +#endif + +#ifndef SC_NO_FONT_LOADING + int fonts_loaded; + u_char *font_8; + u_char *font_14; + u_char *font_16; +#endif + +} sc_softc_t; + +/* virtual screen */ typedef struct scr_stat { - int ad; /* video adapter index */ - video_adapter_t *adp; /* video adapter structure */ - u_short *scr_buf; /* buffer when off screen */ + int index; /* index of this vty */ + struct sc_softc *sc; /* pointer to softc */ + struct sc_rndr_sw *rndr; /* renderer */ + sc_vtb_t scr; + sc_vtb_t vtb; int xpos; /* current X position */ int ypos; /* current Y position */ int saved_xpos; /* saved X position */ @@ -141,25 +257,26 @@ typedef struct scr_stat { int ypixel; /* Y graphics size */ int xoff; /* X offset in pixel mode */ int yoff; /* Y offset in pixel mode */ + u_char *font; /* current font */ int font_size; /* fontsize in Y direction */ int start; /* modified area start */ int end; /* modified area end */ term_stat term; /* terminal emulation stuff */ int status; /* status (bitfield) */ int kbd_mode; /* keyboard I/O mode */ - u_short *cursor_pos; /* cursor buffer position */ - u_short *cursor_oldpos; /* cursor old buffer position */ - u_short cursor_saveunder; /* saved chars under cursor */ - char cursor_start; /* cursor start line # */ - char cursor_end; /* cursor end line # */ - u_short *mouse_pos; /* mouse buffer position */ - u_short *mouse_oldpos; /* mouse old buffer position */ + int cursor_pos; /* cursor buffer position */ + int cursor_oldpos; /* cursor old buffer position */ + u_short cursor_saveunder_char; /* saved char under cursor */ + u_short cursor_saveunder_attr; /* saved attr under cursor */ + char cursor_base; /* cursor base line # */ + char cursor_height; /* cursor height */ + int mouse_pos; /* mouse buffer position */ + int mouse_oldpos; /* mouse old buffer position */ short mouse_xpos; /* mouse x coordinate */ short mouse_ypos; /* mouse y coordinate */ short mouse_buttons; /* mouse buttons */ - u_char mouse_cursor[128]; /* mouse cursor bitmap store */ - u_short *mouse_cut_start; /* mouse cut start pos */ - u_short *mouse_cut_end; /* mouse cut end pos */ + int mouse_cut_start; /* mouse cut start pos */ + int mouse_cut_end; /* mouse cut end pos */ struct proc *mouse_proc; /* proc* of controlling proc */ pid_t mouse_pid; /* pid of controlling proc */ int mouse_signal; /* signal # to report with */ @@ -170,16 +287,14 @@ typedef struct scr_stat { pid_t pid; /* pid of controlling proc */ struct proc *proc; /* proc* of controlling proc */ struct vt_mode smode; /* switch mode */ - u_short *history; /* circular history buffer */ - u_short *history_head; /* current head position */ - u_short *history_pos; /* position shown on screen */ - u_short *history_save; /* save area index */ + sc_vtb_t *history; /* circular history buffer */ + int history_pos; /* position shown on screen */ int history_size; /* size of history buffer */ -#ifdef __i386__ - struct apmhook r_hook; /* reconfiguration support */ -#endif int splash_save_mode; /* saved mode for splash screen */ int splash_save_status; /* saved status for splash screen */ +#ifdef _SCR_MD_STAT_DECLARED_ + scr_md_stat_t md; /* machine dependent vars */ +#endif } scr_stat; typedef struct default_attr { @@ -187,7 +302,63 @@ typedef struct default_attr { int rev_color; /* reverse hardware color */ } default_attr; +#ifndef SC_NORM_ATTR +#define SC_NORM_ATTR (FG_LIGHTGREY | BG_BLACK) +#endif +#ifndef SC_NORM_REV_ATTR +#define SC_NORM_REV_ATTR (FG_BLACK | BG_LIGHTGREY) +#endif +#ifndef SC_KERNEL_CONS_ATTR +#define SC_KERNEL_CONS_ATTR (FG_WHITE | BG_BLACK) +#endif +#ifndef SC_KERNEL_CONS_REV_ATTR +#define SC_KERNEL_CONS_REV_ATTR (FG_BLACK | BG_LIGHTGREY) +#endif + +/* renderer function table */ +typedef void vr_clear_t(scr_stat *scp, int c, int attr); +typedef void vr_draw_border_t(scr_stat *scp, int color); +typedef void vr_draw_t(scr_stat *scp, int from, int count, int flip); +typedef void vr_set_cursor_t(scr_stat *scp, int base, int height, int blink); +typedef void vr_draw_cursor_t(scr_stat *scp, int at, int blink, + int on, int flip); +typedef void vr_blink_cursor_t(scr_stat *scp, int at, int flip); +typedef void vr_set_mouse_t(scr_stat *scp); +typedef void vr_draw_mouse_t(scr_stat *scp, int x, int y, int on); + +typedef struct sc_rndr_sw { + vr_clear_t *clear; + vr_draw_border_t *draw_border; + vr_draw_t *draw; + vr_set_cursor_t *set_cursor; + vr_draw_cursor_t *draw_cursor; + vr_blink_cursor_t *blink_cursor; + vr_set_mouse_t *set_mouse; + vr_draw_mouse_t *draw_mouse; +} sc_rndr_sw_t; + +typedef struct sc_renderer { + char *name; + int mode; + sc_rndr_sw_t *rndrsw; +} sc_renderer_t; + +#define RENDERER(name, mode, sw) \ + static struct sc_renderer name##_##mode##_renderer = { \ + #name, mode, &sw \ + }; \ + DATA_SET(scrndr_set, name##_##mode##_renderer) +extern struct linker_set scrndr_set; + +typedef struct { + int cursor_start; + int cursor_end; + int shift_state; + int bell_pitch; +} bios_values_t; + +/* other macros */ #define ISTEXTSC(scp) (!((scp)->status \ & (UNKNOWN_MODE | GRAPHICS_MODE | PIXEL_MODE))) #define ISGRAPHSC(scp) (((scp)->status \ @@ -197,41 +368,143 @@ typedef struct default_attr { == PIXEL_MODE) #define ISUNKNOWNSC(scp) ((scp)->status & UNKNOWN_MODE) -#define ISFONTAVAIL(af) ((af) & V_ADP_FONT) +#ifndef ISMOUSEAVAIL +#ifdef SC_ALT_MOUSE_IMAGE +#define ISMOUSEAVAIL(af) (1) +#else #define ISMOUSEAVAIL(af) ((af) & V_ADP_FONT) +#endif /* SC_ALT_MOUSE_IMAGE */ +#define ISFONTAVAIL(af) ((af) & V_ADP_FONT) #define ISPALAVAIL(af) ((af) & V_ADP_PALETTE) +#endif /* ISMOUSEAVAIL */ -/* misc prototypes used by different syscons related LKM's */ +#define ISSIGVALID(sig) ((sig) > 0 && (sig) < NSIG) + +#define kbd_read_char(kbd, wait) \ + (*kbdsw[(kbd)->kb_index]->read_char)((kbd), (wait)) +#define kbd_check_char(kbd) \ + (*kbdsw[(kbd)->kb_index]->check_char)((kbd)) +#define kbd_enable(kbd) \ + (*kbdsw[(kbd)->kb_index]->enable)((kbd)) +#define kbd_disable(kbd) \ + (*kbdsw[(kbd)->kb_index]->disable)((kbd)) +#define kbd_lock(kbd, lockf) \ + (*kbdsw[(kbd)->kb_index]->lock)((kbd), (lockf)) +#define kbd_ioctl(kbd, cmd, arg) \ + (((kbd) == NULL) ? \ + ENODEV : (*kbdsw[(kbd)->kb_index]->ioctl)((kbd), (cmd), (arg))) +#define kbd_clear_state(kbd) \ + (*kbdsw[(kbd)->kb_index]->clear_state)((kbd)) +#define kbd_get_fkeystr(kbd, fkey, len) \ + (*kbdsw[(kbd)->kb_index]->get_fkeystr)((kbd), (fkey), (len)) +#define kbd_poll(kbd, on) \ + (*kbdsw[(kbd)->kb_index]->poll)((kbd), (on)) /* syscons.c */ -int sc_probe_unit(int unit, int flags); -int sc_attach_unit(int unit, int flags); +extern int (*sc_user_ioctl)(dev_t dev, u_long cmd, caddr_t data, + int flag, struct proc *p); + +int sc_probe_unit(int unit, int flags); +int sc_attach_unit(int unit, int flags); +int sc_resume_unit(int unit); -extern int (*sc_user_ioctl)(dev_t dev, u_long cmd, caddr_t data, int flag, - struct proc *p); +int set_mode(scr_stat *scp); +scr_stat *sc_get_scr_stat(dev_t dev); -int set_mode(scr_stat *scp); -scr_stat *sc_get_scr_stat(dev_t dev); +void copy_font(scr_stat *scp, int operation, int font_size, + u_char *font_image); +void set_border(scr_stat *scp, int color); -void copy_font(scr_stat *scp, int operation, int font_size, u_char *font_image); -void set_border(scr_stat *scp, int color); +void sc_touch_scrn_saver(void); +void sc_clear_screen(scr_stat *scp); +void sc_set_cursor_image(scr_stat *scp); +int sc_clean_up(scr_stat *scp); +void sc_alloc_scr_buffer(scr_stat *scp, int wait, int discard); +struct tty *scdevtotty(dev_t dev); +#ifndef SC_NO_SYSMOUSE +struct tty *sc_get_mouse_tty(void); +#endif /* SC_NO_SYSMOUSE */ +#ifndef SC_NO_CUTPASTE +void sc_paste(scr_stat *scp, u_char *p, int count); +#endif /* SC_NO_CUTPASTE */ -void sc_touch_scrn_saver(void); -void sc_clear_screen(scr_stat *scp); -void sc_move_mouse(scr_stat *scp, int x, int y); -int sc_clean_up(scr_stat *scp); -void sc_alloc_scr_buffer(scr_stat *scp, int wait, int clear); -void sc_alloc_cut_buffer(scr_stat *scp, int wait); -void sc_alloc_history_buffer(scr_stat *scp, int lines, int extra, int wait); -struct tty *scdevtotty(dev_t dev); +/* schistory.c */ +#ifndef SC_NO_HISTORY +int sc_alloc_history_buffer(scr_stat *scp, int lines, int wait); +void sc_hist_save(scr_stat *scp); +#define sc_hist_save_one_line(scp, from) \ + sc_vtb_append(&(scp)->vtb, (from), (scp)->history, (scp)->xsize) +int sc_hist_restore(scr_stat *scp); +void sc_hist_home(scr_stat *scp); +void sc_hist_end(scr_stat *scp); +int sc_hist_up_line(scr_stat *scp); +int sc_hist_down_line(scr_stat *scp); +int sc_hist_ioctl(struct tty *tp, u_long cmd, caddr_t data, + int flag, struct proc *p); +#endif /* SC_NO_HISTORY */ + +/* scmouse.c */ +#ifndef SC_NO_CUTPASTE +void sc_alloc_cut_buffer(scr_stat *scp, int wait); +void sc_draw_mouse_image(scr_stat *scp); +void sc_remove_mouse_image(scr_stat *scp); +int sc_inside_cutmark(scr_stat *scp, int pos); +void sc_remove_cutmarking(scr_stat *scp); +void sc_remove_all_cutmarkings(sc_softc_t *scp); +void sc_remove_all_mouse(sc_softc_t *scp); +#else +#define sc_inside_cutmark(scp, pos) FALSE +#define sc_remove_cutmarking(scp) +#endif /* SC_NO_CUTPASTE */ +#ifndef SC_NO_SYSMOUSE +void sc_mouse_set_level(int level); +void sc_mouse_move(scr_stat *scp, int x, int y); +int sc_mouse_ioctl(struct tty *tp, u_long cmd, caddr_t data, + int flag, struct proc *p); +#endif /* SC_NO_SYSMOUSE */ /* scvidctl.c */ -int sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, - int xsize, int ysize, int fontsize); -int sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode); -int sc_set_pixel_mode(scr_stat *scp, struct tty *tp, - int xsize, int ysize, int fontsize); -int sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, - struct proc *p); +int sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, + int xsize, int ysize, int fontsize); +int sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode); +int sc_set_pixel_mode(scr_stat *scp, struct tty *tp, + int xsize, int ysize, int fontsize); +sc_rndr_sw_t *sc_render_match(scr_stat *scp, video_adapter_t *adp, int mode); +int sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, + struct proc *p); + +/* scvtb.c */ +void sc_vtb_init(sc_vtb_t *vtb, int type, int cols, int rows, + void *buffer, int wait); +void sc_vtb_destroy(sc_vtb_t *vtb); +size_t sc_vtb_size(int cols, int rows); +void sc_vtb_clear(sc_vtb_t *vtb, int c, int attr); + +int sc_vtb_getc(sc_vtb_t *vtb, int at); +int sc_vtb_geta(sc_vtb_t *vtb, int at); +void sc_vtb_putc(sc_vtb_t *vtb, int at, int c, int a); +vm_offset_t sc_vtb_putchar(sc_vtb_t *vtb, vm_offset_t p, int c, int a); +vm_offset_t sc_vtb_pointer(sc_vtb_t *vtb, int at); +int sc_vtb_pos(sc_vtb_t *vtb, int pos, int offset); + +#define sc_vtb_tail(vtb) ((vtb)->vtb_tail) +#define sc_vtb_rows(vtb) ((vtb)->vtb_rows) + +void sc_vtb_copy(sc_vtb_t *vtb1, int from, sc_vtb_t *vtb2, int to, + int count); +void sc_vtb_append(sc_vtb_t *vtb1, int from, sc_vtb_t *vtb2, + int count); +void sc_vtb_seek(sc_vtb_t *vtb, int pos); +void sc_vtb_erase(sc_vtb_t *vtb, int at, int count, int c, int attr); +void sc_vtb_delete(sc_vtb_t *vtb, int at, int count, int c, int attr); +void sc_vtb_ins(sc_vtb_t *vtb, int at, int count, int c, int attr); + +/* machine dependent functions */ +int sc_max_unit(void); +sc_softc_t *sc_get_softc(int unit, int flags); +sc_softc_t *sc_find_softc(struct video_adapter *adp, struct keyboard *kbd); +int sc_get_cons_priority(int *unit, int *flags); +void sc_get_bios_values(bios_values_t *values); +int sc_tone(int herz); #endif /* !_DEV_SYSCONS_SYSCONS_H_ */ diff --git a/sys/dev/syscons/warp/warp_saver.c b/sys/dev/syscons/warp/warp_saver.c index 3476c36..cd6f42b 100644 --- a/sys/dev/syscons/warp/warp_saver.c +++ b/sys/dev/syscons/warp/warp_saver.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: warp_saver.c,v 1.4 1999/01/11 03:18:55 yokota Exp $ + * $Id: warp_saver.c,v 1.5 1999/04/12 13:34:58 des Exp $ */ #include <sys/param.h> @@ -33,11 +33,14 @@ #include <sys/kernel.h> #include <sys/module.h> #include <sys/syslog.h> +#include <sys/consio.h> +#include <sys/fbio.h> -#include <machine/md_var.h> #include <machine/random.h> -#include <saver.h> +#include <dev/fb/fbreg.h> +#include <dev/fb/splashreg.h> +#include <dev/syscons/syscons.h> static u_char *vid; static int blanked; diff --git a/sys/i386/conf/LINT b/sys/i386/conf/LINT index 5563146..cc51183 100644 --- a/sys/i386/conf/LINT +++ b/sys/i386/conf/LINT @@ -2,7 +2,7 @@ # LINT -- config file for checking all the sources, tries to pull in # as much of the source tree as it can. # -# $Id: LINT,v 1.606 1999/06/15 13:14:40 des Exp $ +# $Id: LINT,v 1.607 1999/06/19 20:20:52 rnordier Exp $ # # NB: You probably don't want to try running a kernel built from this # file. Instead, you should start from GENERIC, and add options from @@ -912,6 +912,9 @@ options VGA_NO_MODE_CHANGE # don't change video modes # Older video cards may require this option for proper operation. options VGA_SLOW_IOACCESS # do byte-wide i/o's to TS and GDC regs +# The following option probably won't work with the LCD displays. +options VGA_WIDTH90 # support 90 column modes + # To include support for VESA video modes options VESA @@ -939,18 +942,20 @@ options PCVT_VT220KEYB # The syscons console driver (sco color console compatible). device sc0 at isa? options MAXCONS=16 # number of virtual consoles -options STD8X16FONT # Compile font in -makeoptions STD8X16FONT=cp850 -options SC_HISTORY_SIZE=200 # number of history buffer lines +options SC_ALT_MOUSE_IMAGE # simplified mouse cursor in text mode +options SC_DFLT_FONT # compile font in +makeoptions SC_DFLT_FONT="cp850" +options SC_DISABLE_DDBKEY # disable `debug' key options SC_DISABLE_REBOOT # disable reboot key sequence +options SC_HISTORY_SIZE=200 # number of history buffer lines +options SC_MOUSE_CHAR=0x3 # char code for text mode mouse cursor +options SC_PIXEL_MODE # add support for the raster text mode -# -# `flags' for sc0: -# 0x01 Use a 'visual' bell -# 0x02 Use a 'blink' cursor -# 0x04 Use a 'underline' cursor -# 0x06 Use a 'blinking underline' (destructive) cursor -# 0x40 Make the bell quiet if it is rung in the background vty. +# You can selectively disable features in syscons. +options SC_NO_CUTPASTE +options SC_NO_FONT_LOADING +options SC_NO_HISTORY +options SC_NO_SYSMOUSE # # The Numeric Processing eXtension driver. This should be configured if @@ -2155,6 +2160,10 @@ options ULPT_DEBUG options UMASS_DEBUG options UMS_DEBUG +# options for ukbd: +options UKBD_DFLT_KEYMAP # specify the built-in keymap +makeoptions UKBD_DFLT_KEYMAP="it.iso" + # # Embedded system options: # diff --git a/sys/i386/conf/NOTES b/sys/i386/conf/NOTES index 5563146..cc51183 100644 --- a/sys/i386/conf/NOTES +++ b/sys/i386/conf/NOTES @@ -2,7 +2,7 @@ # LINT -- config file for checking all the sources, tries to pull in # as much of the source tree as it can. # -# $Id: LINT,v 1.606 1999/06/15 13:14:40 des Exp $ +# $Id: LINT,v 1.607 1999/06/19 20:20:52 rnordier Exp $ # # NB: You probably don't want to try running a kernel built from this # file. Instead, you should start from GENERIC, and add options from @@ -912,6 +912,9 @@ options VGA_NO_MODE_CHANGE # don't change video modes # Older video cards may require this option for proper operation. options VGA_SLOW_IOACCESS # do byte-wide i/o's to TS and GDC regs +# The following option probably won't work with the LCD displays. +options VGA_WIDTH90 # support 90 column modes + # To include support for VESA video modes options VESA @@ -939,18 +942,20 @@ options PCVT_VT220KEYB # The syscons console driver (sco color console compatible). device sc0 at isa? options MAXCONS=16 # number of virtual consoles -options STD8X16FONT # Compile font in -makeoptions STD8X16FONT=cp850 -options SC_HISTORY_SIZE=200 # number of history buffer lines +options SC_ALT_MOUSE_IMAGE # simplified mouse cursor in text mode +options SC_DFLT_FONT # compile font in +makeoptions SC_DFLT_FONT="cp850" +options SC_DISABLE_DDBKEY # disable `debug' key options SC_DISABLE_REBOOT # disable reboot key sequence +options SC_HISTORY_SIZE=200 # number of history buffer lines +options SC_MOUSE_CHAR=0x3 # char code for text mode mouse cursor +options SC_PIXEL_MODE # add support for the raster text mode -# -# `flags' for sc0: -# 0x01 Use a 'visual' bell -# 0x02 Use a 'blink' cursor -# 0x04 Use a 'underline' cursor -# 0x06 Use a 'blinking underline' (destructive) cursor -# 0x40 Make the bell quiet if it is rung in the background vty. +# You can selectively disable features in syscons. +options SC_NO_CUTPASTE +options SC_NO_FONT_LOADING +options SC_NO_HISTORY +options SC_NO_SYSMOUSE # # The Numeric Processing eXtension driver. This should be configured if @@ -2155,6 +2160,10 @@ options ULPT_DEBUG options UMASS_DEBUG options UMS_DEBUG +# options for ukbd: +options UKBD_DFLT_KEYMAP # specify the built-in keymap +makeoptions UKBD_DFLT_KEYMAP="it.iso" + # # Embedded system options: # diff --git a/sys/i386/conf/files.i386 b/sys/i386/conf/files.i386 index 44c115c..ae19e96 100644 --- a/sys/i386/conf/files.i386 +++ b/sys/i386/conf/files.i386 @@ -1,7 +1,7 @@ # This file tells config what files go into building a kernel, # files marked standard are always included. # -# $Id: files.i386,v 1.246 1999/06/01 18:18:38 jlemon Exp $ +# $Id: files.i386,v 1.247 1999/06/18 19:55:50 green Exp $ # # The long compile-with and dependency lines are required because of # limitations in config: backslash-newline doesn't work in strings, and @@ -19,10 +19,10 @@ linux_assym.h optional compat_linux \ no-obj no-implicit-rule before-depend \ clean "linux_assym.h" # -font8x16.o optional std8x16font \ - compile-with "uudecode < /usr/share/syscons/fonts/${STD8X16FONT}-8x16.fnt && file2c 'unsigned char font_16[16*256] = {' '};' < ${STD8X16FONT}-8x16 > font8x16.c && ${CC} -c ${CFLAGS} font8x16.c" \ - no-implicit-rule before-depend \ - clean "${STD8X16FONT}-8x16 font8x16.c" +font.h optional sc_dflt_font \ + compile-with "uudecode < /usr/share/syscons/fonts/${SC_DFLT_FONT}-8x16.fnt && file2c 'static u_char dflt_font_16[16*256] = {' '};' < ${SC_DFLT_FONT}-8x16 > font.h && uudecode < /usr/share/syscons/fonts/${SC_DFLT_FONT}-8x14.fnt && file2c 'static u_char dflt_font_14[14*256] = {' '};' < ${SC_DFLT_FONT}-8x14 >> font.h && uudecode < /usr/share/syscons/fonts/${SC_DFLT_FONT}-8x8.fnt && file2c 'static u_char dflt_font_8[8*256] = {' '};' < ${SC_DFLT_FONT}-8x8 >> font.h" \ + no-obj no-implicit-rule before-depend \ + clean "font.h" # atkbdmap.h optional atkbd_dflt_keymap \ compile-with "kbdcontrol -L ${ATKBD_DFLT_KEYMAP} | sed -e 's/^static keymap_t.* = /static keymap_t key_map = /' -e 's/^static accentmap_t.* = /static accentmap_t accent_map = /' > atkbdmap.h" \ @@ -44,14 +44,19 @@ dev/ata/atapi-tape.c optional atapist device-driver dev/fb/fb.c optional fb device-driver dev/fb/fb.c optional vga device-driver dev/fb/splash.c optional splash +dev/fb/vga.c optional vga device-driver dev/kbd/atkbd.c optional atkbd device-driver dev/kbd/atkbdc.c optional atkbdc device-driver dev/kbd/kbd.c optional atkbd device-driver dev/kbd/kbd.c optional kbd device-driver dev/kbd/kbd.c optional ukbd device-driver dev/syscons/syscons.c optional sc device-driver +dev/syscons/schistory.c optional sc device-driver +dev/syscons/scmouse.c optional sc device-driver dev/syscons/scvidctl.c optional sc device-driver dev/syscons/scvesactl.c optional sc device-driver +dev/syscons/scvgarndr.c optional sc device-driver +dev/syscons/scvtb.c optional sc device-driver i386/apm/apm.c optional apm device-driver i386/apm/apm_setup.s optional apm i386/eisa/dpt_eisa.c optional eisa dpt device-driver diff --git a/sys/i386/conf/options.i386 b/sys/i386/conf/options.i386 index c3aa0d9..d7cc7b4 100644 --- a/sys/i386/conf/options.i386 +++ b/sys/i386/conf/options.i386 @@ -1,4 +1,4 @@ -# $Id: options.i386,v 1.116 1999/06/06 22:45:04 steve Exp $ +# $Id: options.i386,v 1.117 1999/06/15 13:14:43 des Exp $ DISABLE_PSE IDE_DELAY @@ -65,17 +65,30 @@ I586_CPU opt_global.h I686_CPU opt_global.h MAXCONS opt_syscons.h -STD8X16FONT opt_syscons.h -SC_HISTORY_SIZE opt_syscons.h +SC_ALT_MOUSE_IMAGE opt_syscons.h +SC_DEBUG_LEVEL opt_syscons.h +SC_DFLT_FONT opt_syscons.h +SC_DISABLE_DDBKEY opt_syscons.h SC_DISABLE_REBOOT opt_syscons.h +SC_HISTORY_SIZE opt_syscons.h SC_MOUSE_CHAR opt_syscons.h - +SC_NO_CUTPASTE opt_syscons.h +SC_NO_FONT_LOADING opt_syscons.h +SC_NO_HISTORY opt_syscons.h +SC_NO_SYSMOUSE opt_syscons.h +SC_PIXEL_MODE opt_syscons.h +SC_RENDER_DEBUG opt_syscons.h +SC_VIDEO_DEBUG opt_syscons.h + +FB_DEBUG opt_fb.h FB_INSTALL_CDEV opt_fb.h VGA_ALT_SEQACCESS opt_vga.h +VGA_DEBUG opt_vga.h VGA_NO_FONT_LOADING opt_vga.h VGA_NO_MODE_CHANGE opt_vga.h VGA_SLOW_IOACCESS opt_vga.h +VGA_WIDTH90 opt_vga.h VESA opt_vesa.h VESA_DEBUG opt_vesa.h diff --git a/sys/i386/i386/cons.c b/sys/i386/i386/cons.c index acc8503..cee6564 100644 --- a/sys/i386/i386/cons.c +++ b/sys/i386/i386/cons.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * from: @(#)cons.c 7.2 (Berkeley) 5/9/91 - * $Id: cons.c,v 1.66 1999/05/30 16:52:03 phk Exp $ + * $Id: cons.c,v 1.67 1999/05/31 11:25:41 phk Exp $ */ #include "opt_devfs.h" @@ -109,19 +109,19 @@ static struct tty *cn_tp; /* physical console tty struct */ static void *cn_devfs_token; /* represents the devfs entry */ #endif /* DEVFS */ -CONS_DRIVER(cons, NULL, NULL, NULL, NULL, NULL); +CONS_DRIVER(cons, NULL, NULL, NULL, NULL, NULL, NULL); void cninit() { struct consdev *best_cp, *cp; - struct consdev **list; + const struct consdev **list; /* * Find the first console with the highest priority. */ best_cp = NULL; - list = (struct consdev **)cons_set.ls_items; + list = (const struct consdev **)cons_set.ls_items; while ((cp = *list++) != NULL) { if (cp->cn_probe == NULL) continue; @@ -147,6 +147,8 @@ cninit() * If no console, give up. */ if (best_cp == NULL) { + if (cn_tab != NULL && cn_tab->cn_term != NULL) + (*cn_tab->cn_term)(cn_tab); cn_tab = best_cp; return; } @@ -154,10 +156,13 @@ cninit() /* * Initialize console, then attach to it. This ordering allows * debugging using the previous console, if any. - * XXX if there was a previous console, then its driver should - * be informed when we forget about it. */ (*best_cp->cn_init)(best_cp); + if (cn_tab != NULL && cn_tab != best_cp) { + /* Turn off the previous console. */ + if (cn_tab->cn_term != NULL) + (*cn_tab->cn_term)(cn_tab); + } cn_tab = best_cp; } diff --git a/sys/i386/i386/cons.h b/sys/i386/i386/cons.h index 1656b12..ea84d7e 100644 --- a/sys/i386/i386/cons.h +++ b/sys/i386/i386/cons.h @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * from: @(#)cons.h 7.2 (Berkeley) 5/9/91 - * $Id: cons.h,v 1.18 1999/01/07 14:14:11 yokota Exp $ + * $Id: cons.h,v 1.19 1999/01/09 14:07:37 bde Exp $ */ #ifndef _MACHINE_CONS_H_ @@ -45,6 +45,7 @@ struct consdev; typedef void cn_probe_t __P((struct consdev *)); typedef void cn_init_t __P((struct consdev *)); +typedef void cn_term_t __P((struct consdev *)); typedef int cn_getc_t __P((dev_t)); typedef int cn_checkc_t __P((dev_t)); typedef void cn_putc_t __P((dev_t, int)); @@ -54,6 +55,8 @@ struct consdev { /* probe hardware and fill in consdev info */ cn_init_t *cn_init; /* turn on as console */ + cn_term_t *cn_term; + /* turn off as console */ cn_getc_t *cn_getc; /* kernel getchar interface */ cn_checkc_t *cn_checkc; @@ -75,10 +78,10 @@ struct consdev { extern struct linker_set cons_set; extern int cons_unavail; -#define CONS_DRIVER(name, probe, init, getc, checkc, putc) \ - static struct consdev name##_consdev = { \ - probe, init, getc, checkc, putc \ - }; \ +#define CONS_DRIVER(name, probe, init, term, getc, checkc, putc) \ + static struct consdev name##_consdev = { \ + probe, init, term, getc, checkc, putc \ + }; \ DATA_SET(cons_set, name##_consdev) /* Other kernel entry points. */ diff --git a/sys/i386/include/console.h b/sys/i386/include/console.h index 54409d0..79a6b57 100644 --- a/sys/i386/include/console.h +++ b/sys/i386/include/console.h @@ -1,635 +1,8 @@ -/*- - * Copyright (c) 1991-1996 Søren Schmidt - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $Id: console.h,v 1.44 1999/02/05 11:52:09 yokota Exp $ - */ +#ifndef _MACHINE_CONSOLE_H_ +#define _MACHINE_CONSOLE_H_ -#ifndef _MACHINE_CONSOLE_H_ -#define _MACHINE_CONSOLE_H_ - -#ifndef KERNEL -#include <sys/types.h> -#endif -#include <sys/ioccom.h> - -#define KDGKBMODE _IOR('K', 6, int) -#define KDSKBMODE _IO('K', 7 /*, int */) -#define KDMKTONE _IO('K', 8 /*, int */) -#define KDGETMODE _IOR('K', 9, int) -#define KDSETMODE _IO('K', 10 /*, int */) -#define KDSBORDER _IO('K', 13 /*, int */) -#define KDGKBSTATE _IOR('K', 19, int) -#define KDSKBSTATE _IO('K', 20 /*, int */) -#define KDENABIO _IO('K', 60) -#define KDDISABIO _IO('K', 61) -#define KIOCSOUND _IO('K', 63 /*, int */) -#define KDGKBTYPE _IOR('K', 64, int) -#define KDGETLED _IOR('K', 65, int) -#define KDSETLED _IO('K', 66 /*, int */) -#define KDSETRAD _IO('K', 67 /*, int */) /* obsolete */ -#define KDRASTER _IOW('K', 100, scr_size_t) -#define KDGKBINFO _IOR('K', 101, keyboard_info_t) -#define KDSETREPEAT _IOW('K', 102, keyboard_delay_t) - -#define GETFKEY _IOWR('k', 0, fkeyarg_t) -#define SETFKEY _IOWR('k', 1, fkeyarg_t) -#define GIO_SCRNMAP _IOR('k', 2, scrmap_t) -#define PIO_SCRNMAP _IOW('k', 3, scrmap_t) -#define GIO_KEYMAP _IOR('k', 6, keymap_t) -#define PIO_KEYMAP _IOW('k', 7, keymap_t) -#define GIO_DEADKEYMAP _IOR('k', 8, accentmap_t) -#define PIO_DEADKEYMAP _IOW('k', 9, accentmap_t) -#define GIO_KEYMAPENT _IOWR('k', 10, keyarg_t) -#define PIO_KEYMAPENT _IOW('k', 11, keyarg_t) - -#define GIO_ATTR _IOR('a', 0, int) -#define GIO_COLOR _IOR('c', 0, int) -#define CONS_CURRENT _IOR('c', 1, int) -#define CONS_GET _IOR('c', 2, int) -#define CONS_IO _IO('c', 3) -#define CONS_BLANKTIME _IOW('c', 4, int) -#define CONS_SSAVER _IOW('c', 5, ssaver_t) -#define CONS_GSAVER _IOWR('c', 6, ssaver_t) -#define CONS_CURSORTYPE _IOW('c', 7, int) -#define CONS_BELLTYPE _IOW('c', 8, int) -#define CONS_HISTORY _IOW('c', 9, int) -#define CONS_MOUSECTL _IOWR('c', 10, mouse_info_t) -#define CONS_IDLE _IOR('c', 11, int) -#define CONS_SAVERMODE _IOW('c', 12, int) -#define CONS_SAVERSTART _IOW('c', 13, int) -#define PIO_FONT8x8 _IOW('c', 64, fnt8_t) -#define GIO_FONT8x8 _IOR('c', 65, fnt8_t) -#define PIO_FONT8x14 _IOW('c', 66, fnt14_t) -#define GIO_FONT8x14 _IOR('c', 67, fnt14_t) -#define PIO_FONT8x16 _IOW('c', 68, fnt16_t) -#define GIO_FONT8x16 _IOR('c', 69, fnt16_t) -#define CONS_GETINFO _IOWR('c', 73, vid_info_t) -#define CONS_GETVERS _IOR('c', 74, int) -#define CONS_CURRENTADP _IOR('c', 100, int) -#define CONS_ADPINFO _IOWR('c', 101, video_adapter_info_t) -#define CONS_MODEINFO _IOWR('c', 102, video_info_t) -#define CONS_FINDMODE _IOWR('c', 103, video_info_t) -#define CONS_SETWINORG _IO('c', 104 /* u_int */) - -#define CONS_SETKBD _IO('c', 110 /* int */) -#define CONS_RELKBD _IO('c', 111) - -/* CONS_SAVERMODE */ -#define CONS_LKM_SAVER 0 -#define CONS_USR_SAVER 1 - -#ifdef PC98 -#define ADJUST_CLOCK _IO('t',100) /* for 98note resume */ -#endif - -#define VT_OPENQRY _IOR('v', 1, int) -#define VT_SETMODE _IOW('v', 2, vtmode_t) -#define VT_GETMODE _IOR('v', 3, vtmode_t) -#define VT_RELDISP _IO('v', 4 /*, int */) -#define VT_ACTIVATE _IO('v', 5 /*, int */) -#define VT_WAITACTIVE _IO('v', 6 /*, int */) -#define VT_GETACTIVE _IOR('v', 7, int) - -#define VT_FALSE 0 -#define VT_TRUE 1 -#define VT_ACKACQ 2 - -#define VT_AUTO 0 /* switching is automatic */ -#define VT_PROCESS 1 /* switching controlled by prog */ -#define VT_KERNEL 255 /* switching controlled in kernel */ - -#ifndef _VT_MODE_DECLARED -#define _VT_MODE_DECLARED -struct vt_mode { - char mode; - char waitv; /* not implemented yet SOS */ - short relsig; - short acqsig; - short frsig; /* not implemented yet SOS */ -}; - -typedef struct vt_mode vtmode_t; -#endif /* !_VT_MODE_DECLARED */ - -struct mouse_data { - int x; - int y; - int z; - int buttons; -}; - -struct mouse_mode { - int mode; - int signal; -}; - -struct mouse_event { - int id; /* one based */ - int value; -}; - -#define MOUSE_SHOW 0x01 -#define MOUSE_HIDE 0x02 -#define MOUSE_MOVEABS 0x03 -#define MOUSE_MOVEREL 0x04 -#define MOUSE_GETINFO 0x05 -#define MOUSE_MODE 0x06 -#define MOUSE_ACTION 0x07 -#define MOUSE_MOTION_EVENT 0x08 -#define MOUSE_BUTTON_EVENT 0x09 - -struct mouse_info { - int operation; - union { - struct mouse_data data; - struct mouse_mode mode; - struct mouse_event event; - }u; -}; - -#define KD_MONO 1 /* monochrome adapter */ -#define KD_HERCULES 2 /* hercules adapter */ -#define KD_CGA 3 /* color graphics adapter */ -#define KD_EGA 4 /* enhanced graphics adapter */ -#define KD_VGA 5 /* video graphics adapter */ -#define KD_PC98 6 /* PC-98 display */ - -#define KD_TEXT 0 /* set text mode restore fonts */ -#define KD_TEXT0 0 /* ditto */ -#define KD_TEXT1 2 /* set text mode !restore fonts */ -#define KD_GRAPHICS 1 /* set graphics mode */ -#define KD_PIXEL 3 /* set pixel mode */ - -#define K_RAW 0 /* keyboard returns scancodes */ -#define K_XLATE 1 /* keyboard returns ascii */ -#define K_CODE 2 /* keyboard returns keycodes */ - -#define KB_84 1 /* 'old' 84 key AT-keyboard */ -#define KB_101 2 /* MF-101 or MF-102 keyboard */ -#define KB_OTHER 3 /* keyboard not known */ - -#define CLKED 1 /* Caps locked */ -#define NLKED 2 /* Num locked */ -#define SLKED 4 /* Scroll locked */ -#define ALKED 8 /* AltGr locked */ -#define LOCK_MASK (CLKED | NLKED | SLKED | ALKED) -#define LED_CAP 1 /* Caps lock LED */ -#define LED_NUM 2 /* Num lock LED */ -#define LED_SCR 4 /* Scroll lock LED */ -#define LED_MASK (LED_CAP | LED_NUM | LED_SCR) - -/* possible flag values */ -#define FLAG_LOCK_O 0 -#define FLAG_LOCK_C 1 -#define FLAG_LOCK_N 2 - -#define NUM_KEYS 256 /* number of keys in table */ -#define NUM_STATES 8 /* states per key */ -#define ALTGR_OFFSET 128 /* offset for altlock keys */ - -#ifndef _KEYMAP_DECLARED -#define _KEYMAP_DECLARED -struct keyent_t { - u_char map[NUM_STATES]; - u_char spcl; - u_char flgs; -}; - -struct keymap { - u_short n_keys; - struct keyent_t key[NUM_KEYS]; -}; - -typedef struct keymap keymap_t; - -struct keyarg { - u_short keynum; - struct keyent_t key; -}; - -typedef struct keyarg keyarg_t; -#endif /* !_KEYMAP_DECLARED */ - -#define NUM_DEADKEYS 15 /* number of accent keys */ -#define NUM_ACCENTCHARS 52 /* max number of accent chars */ - -struct acc_t { - u_char accchar; - u_char map[NUM_ACCENTCHARS][2]; -}; - -struct accentmap { - u_short n_accs; - struct acc_t acc[NUM_DEADKEYS]; -}; - -#define MAXFK 16 -#define NUM_FKEYS 96 - -struct fkeytab { - u_char str[MAXFK]; - u_char len; -}; - -struct fkeyarg { - u_short keynum; - char keydef[MAXFK]; - char flen; -}; - -struct colors { - char fore; - char back; -}; - -struct vid_info { - short size; - short m_num; - u_short mv_row, mv_col; - u_short mv_rsz, mv_csz; - struct colors mv_norm, - mv_rev, - mv_grfc; - u_char mv_ovscan; - u_char mk_keylock; -}; - -#define MAXSSAVER 16 - -struct ssaver { - char name[MAXSSAVER]; - int num; - long time; -}; - -/* video mode information block */ -struct video_info { - int vi_mode; - int vi_flags; -#define V_INFO_COLOR (1<<0) -#define V_INFO_GRAPHICS (1<<1) -#define V_INFO_LINEAR (1<<2) -#define V_INFO_VESA (1<<3) - int vi_width; - int vi_height; - int vi_cwidth; - int vi_cheight; - int vi_depth; - int vi_planes; - u_int vi_window; /* physical address */ - size_t vi_window_size; - size_t vi_window_gran; - u_int vi_buffer; /* physical address */ - size_t vi_buffer_size; - /* XXX pixel format, memory model,... */ -}; - -/* adapter infromation block */ -struct video_adapter { - int va_index; - int va_type; - char *va_name; - int va_unit; - int va_minor; - int va_flags; -#define V_ADP_COLOR (1<<0) -#define V_ADP_MODECHANGE (1<<1) -#define V_ADP_STATESAVE (1<<2) -#define V_ADP_STATELOAD (1<<3) -#define V_ADP_FONT (1<<4) -#define V_ADP_PALETTE (1<<5) -#define V_ADP_BORDER (1<<6) -#define V_ADP_VESA (1<<7) -#define V_ADP_PROBED (1<<16) -#define V_ADP_INITIALIZED (1<<17) -#define V_ADP_REGISTERED (1<<18) - int va_io_base; - int va_io_size; - int va_crtc_addr; - int va_mem_base; - int va_mem_size; - u_int va_window; /* virtual address */ - size_t va_window_size; - size_t va_window_gran; - u_int va_buffer; /* virtual address */ - size_t va_buffer_size; - int va_initial_mode; - int va_initial_bios_mode; - int va_mode; - struct video_info va_info; - int va_line_width; - void *va_token; -}; - -struct video_adapter_info { - int va_index; - int va_type; - char va_name[16]; - int va_unit; - int va_flags; - int va_io_base; - int va_io_size; - int va_crtc_addr; - int va_mem_base; - int va_mem_size; - u_int va_window; /* virtual address */ - size_t va_window_size; - size_t va_window_gran; - u_int va_buffer; /* virtual address */ - size_t va_buffer_size; - int va_initial_mode; - int va_initial_bios_mode; - int va_mode; - int va_line_width; -}; - -#define V_ADP_PRIMARY 0 -#define V_ADP_SECONDARY 1 - -struct keyboard_info { - int kb_index; /* kbdio index# */ - char kb_name[16]; /* driver name */ - int kb_unit; /* unit# */ - int kb_type; /* KB_84, KB_101, KB_OTHER,... */ - int kb_config; /* device configuration flags */ - int kb_flags; /* internal flags */ -}; - -typedef struct accentmap accentmap_t; -typedef struct fkeytab fkeytab_t; -typedef struct fkeyarg fkeyarg_t; -typedef struct vid_info vid_info_t; -typedef struct mouse_info mouse_info_t; -typedef struct {char scrmap[256];} scrmap_t; -typedef struct {char fnt8x8[8*256];} fnt8_t; -typedef struct {char fnt8x14[14*256];} fnt14_t; -typedef struct {char fnt8x16[16*256];} fnt16_t; -typedef struct ssaver ssaver_t; -typedef struct video_adapter video_adapter_t; -typedef struct video_adapter_info video_adapter_info_t; -typedef struct video_info video_info_t; -typedef struct keyboard_info keyboard_info_t; -typedef struct {int scr_size[3];} scr_size_t; -typedef struct {int kbd_delay[2];} keyboard_delay_t; - -/* defines for "special" keys (spcl bit set in keymap) */ -#define NOP 0x00 /* nothing (dead key) */ -#define LSH 0x02 /* left shift key */ -#define RSH 0x03 /* right shift key */ -#define CLK 0x04 /* caps lock key */ -#define NLK 0x05 /* num lock key */ -#define SLK 0x06 /* scroll lock key */ -#define LALT 0x07 /* left alt key */ -#define BTAB 0x08 /* backwards tab */ -#define LCTR 0x09 /* left control key */ -#define NEXT 0x0a /* switch to next screen */ -#define F_SCR 0x0b /* switch to first screen */ -#define L_SCR 0x1a /* switch to last screen */ -#define F_FN 0x1b /* first function key */ -#define L_FN 0x7a /* last function key */ -/* 0x7b-0x7f reserved do not use ! */ -#define RCTR 0x80 /* right control key */ -#define RALT 0x81 /* right alt (altgr) key */ -#define ALK 0x82 /* alt lock key */ -#define ASH 0x83 /* alt shift key */ -#define META 0x84 /* meta key */ -#define RBT 0x85 /* boot machine */ -#define DBG 0x86 /* call debugger */ -#define SUSP 0x87 /* suspend power (APM) */ -#define SPSC 0x88 /* toggle splash/text screen */ - -#define F_ACC DGRA /* first accent key */ -#define DGRA 0x89 /* grave */ -#define DACU 0x8a /* acute */ -#define DCIR 0x8b /* circumflex */ -#define DTIL 0x8c /* tilde */ -#define DMAC 0x8d /* macron */ -#define DBRE 0x8e /* breve */ -#define DDOT 0x8f /* dot */ -#define DUML 0x90 /* umlaut/diaresis */ -#define DDIA 0x90 /* diaresis */ -#define DSLA 0x91 /* slash */ -#define DRIN 0x92 /* ring */ -#define DCED 0x93 /* cedilla */ -#define DAPO 0x94 /* apostrophe */ -#define DDAC 0x95 /* double acute */ -#define DOGO 0x96 /* ogonek */ -#define DCAR 0x97 /* caron */ -#define L_ACC DCAR /* last accent key */ - -#define STBY 0x98 /* Go into standby mode (apm) */ - -#define F(x) ((x)+F_FN-1) -#define S(x) ((x)+F_SCR-1) -#define ACC(x) ((x)+F_ACC) -#define NOKEY 0x100 /* no key pressed marker */ -#define FKEY 0x200 /* function key marker */ -#define MKEY 0x400 /* meta key marker (prepend ESC)*/ -#define BKEY 0x800 /* backtab (ESC [ Z) */ - -#define SPCLKEY 0x8000 /* special key */ -#define RELKEY 0x4000 /* key released */ -#define ERRKEY 0x2000 /* error */ - -#define KEYCHAR(c) ((c) & 0x00ff) -#define KEYFLAGS(c) ((c) & ~0x00ff) - -/* video mode definitions */ -#define M_B40x25 0 /* black & white 40 columns */ -#define M_C40x25 1 /* color 40 columns */ -#define M_B80x25 2 /* black & white 80 columns */ -#define M_C80x25 3 /* color 80 columns */ -#define M_BG320 4 /* black & white graphics 320x200 */ -#define M_CG320 5 /* color graphics 320x200 */ -#define M_BG640 6 /* black & white graphics 640x200 hi-res */ -#define M_EGAMONO80x25 7 /* ega-mono 80x25 */ -#define M_CG320_D 13 /* ega mode D */ -#define M_CG640_E 14 /* ega mode E */ -#define M_EGAMONOAPA 15 /* ega mode F */ -#define M_CG640x350 16 /* ega mode 10 */ -#define M_ENHMONOAPA2 17 /* ega mode F with extended memory */ -#define M_ENH_CG640 18 /* ega mode 10* */ -#define M_ENH_B40x25 19 /* ega enhanced black & white 40 columns */ -#define M_ENH_C40x25 20 /* ega enhanced color 40 columns */ -#define M_ENH_B80x25 21 /* ega enhanced black & white 80 columns */ -#define M_ENH_C80x25 22 /* ega enhanced color 80 columns */ -#define M_VGA_C40x25 23 /* vga 8x16 font on color */ -#define M_VGA_C80x25 24 /* vga 8x16 font on color */ -#define M_VGA_M80x25 25 /* vga 8x16 font on mono */ - -#define M_VGA11 26 /* vga 640x480 2 colors */ -#define M_BG640x480 26 -#define M_VGA12 27 /* vga 640x480 16 colors */ -#define M_CG640x480 27 -#define M_VGA13 28 /* vga 640x200 256 colors */ -#define M_VGA_CG320 28 - -#define M_VGA_C80x50 30 /* vga 8x8 font on color */ -#define M_VGA_M80x50 31 /* vga 8x8 font on color */ -#define M_VGA_C80x30 32 /* vga 8x16 font on color */ -#define M_VGA_M80x30 33 /* vga 8x16 font on color */ -#define M_VGA_C80x60 34 /* vga 8x8 font on color */ -#define M_VGA_M80x60 35 /* vga 8x8 font on color */ -#define M_VGA_CG640 36 /* vga 640x400 256 color */ -#define M_VGA_MODEX 37 /* vga 320x240 256 color */ - -#define M_ENH_B80x43 0x70 /* ega black & white 80x43 */ -#define M_ENH_C80x43 0x71 /* ega color 80x43 */ - -#define M_PC98_80x25 98 /* PC98 80x25 */ -#define M_PC98_80x30 99 /* PC98 80x30 */ - -#define M_HGC_P0 0xe0 /* hercules graphics - page 0 @ B0000 */ -#define M_HGC_P1 0xe1 /* hercules graphics - page 1 @ B8000 */ -#define M_MCA_MODE 0xff /* monochrome adapter mode */ - -#define M_TEXT_80x25 200 /* generic text modes */ -#define M_TEXT_80x30 201 -#define M_TEXT_80x43 202 -#define M_TEXT_80x50 203 -#define M_TEXT_80x60 204 -#define M_TEXT_132x25 205 -#define M_TEXT_132x30 206 -#define M_TEXT_132x43 207 -#define M_TEXT_132x50 208 -#define M_TEXT_132x60 209 - -#define SW_PC98_80x25 _IO('S', M_PC98_80x25) -#define SW_PC98_80x30 _IO('S', M_PC98_80x30) -#define SW_B40x25 _IO('S', M_B40x25) -#define SW_C40x25 _IO('S', M_C40x25) -#define SW_B80x25 _IO('S', M_B80x25) -#define SW_C80x25 _IO('S', M_C80x25) -#define SW_BG320 _IO('S', M_BG320) -#define SW_CG320 _IO('S', M_CG320) -#define SW_BG640 _IO('S', M_BG640) -#define SW_EGAMONO80x25 _IO('S', M_EGAMONO80x25) -#define SW_CG320_D _IO('S', M_CG320_D) -#define SW_CG640_E _IO('S', M_CG640_E) -#define SW_EGAMONOAPA _IO('S', M_EGAMONOAPA) -#define SW_CG640x350 _IO('S', M_CG640x350) -#define SW_ENH_MONOAPA2 _IO('S', M_ENHMONOAPA2) -#define SW_ENH_CG640 _IO('S', M_ENH_CG640) -#define SW_ENH_B40x25 _IO('S', M_ENH_B40x25) -#define SW_ENH_C40x25 _IO('S', M_ENH_C40x25) -#define SW_ENH_B80x25 _IO('S', M_ENH_B80x25) -#define SW_ENH_C80x25 _IO('S', M_ENH_C80x25) -#define SW_ENH_B80x43 _IO('S', M_ENH_B80x43) -#define SW_ENH_C80x43 _IO('S', M_ENH_C80x43) -#define SW_MCAMODE _IO('S', M_MCA_MODE) -#define SW_VGA_C40x25 _IO('S', M_VGA_C40x25) -#define SW_VGA_C80x25 _IO('S', M_VGA_C80x25) -#define SW_VGA_C80x30 _IO('S', M_VGA_C80x30) -#define SW_VGA_C80x50 _IO('S', M_VGA_C80x50) -#define SW_VGA_C80x60 _IO('S', M_VGA_C80x60) -#define SW_VGA_M80x25 _IO('S', M_VGA_M80x25) -#define SW_VGA_M80x30 _IO('S', M_VGA_M80x30) -#define SW_VGA_M80x50 _IO('S', M_VGA_M80x50) -#define SW_VGA_M80x60 _IO('S', M_VGA_M80x60) -#define SW_VGA11 _IO('S', M_VGA11) -#define SW_BG640x480 _IO('S', M_VGA11) -#define SW_VGA12 _IO('S', M_VGA12) -#define SW_CG640x480 _IO('S', M_VGA12) -#define SW_VGA13 _IO('S', M_VGA13) -#define SW_VGA_CG320 _IO('S', M_VGA13) -#define SW_VGA_CG640 _IO('S', M_VGA_CG640) -#define SW_VGA_MODEX _IO('S', M_VGA_MODEX) - -#define SW_TEXT_80x25 _IO('S', M_TEXT_80x25) -#define SW_TEXT_80x30 _IO('S', M_TEXT_80x30) -#define SW_TEXT_80x43 _IO('S', M_TEXT_80x43) -#define SW_TEXT_80x50 _IO('S', M_TEXT_80x50) -#define SW_TEXT_80x60 _IO('S', M_TEXT_80x60) -#define SW_TEXT_132x25 _IO('S', M_TEXT_132x25) -#define SW_TEXT_132x30 _IO('S', M_TEXT_132x30) -#define SW_TEXT_132x43 _IO('S', M_TEXT_132x43) -#define SW_TEXT_132x50 _IO('S', M_TEXT_132x50) -#define SW_TEXT_132x60 _IO('S', M_TEXT_132x60) - -#define M_VESA_BASE 0x100 /* VESA mode number base */ - -#define M_VESA_CG640x400 0x100 /* 640x400, 256 color */ -#define M_VESA_CG640x480 0x101 /* 640x480, 256 color */ -#define M_VESA_800x600 0x102 /* 800x600, 16 color */ -#define M_VESA_CG800x600 0x103 /* 800x600, 256 color */ -#define M_VESA_1024x768 0x104 /* 1024x768, 16 color */ -#define M_VESA_CG1024x768 0x105 /* 1024x768, 256 color */ -#define M_VESA_1280x1024 0x106 /* 1280x1024, 16 color */ -#define M_VESA_CG1280x1024 0x107 /* 1280x1024, 256 color */ -#define M_VESA_C80x60 0x108 /* 8x8 font */ -#define M_VESA_C132x25 0x109 /* 8x16 font */ -#define M_VESA_C132x43 0x10a /* 8x14 font */ -#define M_VESA_C132x50 0x10b /* 8x8 font */ -#define M_VESA_C132x60 0x10c /* 8x8 font */ -#define M_VESA_32K_320 0x10d /* 320x200, 5:5:5 */ -#define M_VESA_64K_320 0x10e /* 320x200, 5:6:5 */ -#define M_VESA_FULL_320 0x10f /* 320x200, 8:8:8 */ -#define M_VESA_32K_640 0x110 /* 640x480, 5:5:5 */ -#define M_VESA_64K_640 0x111 /* 640x480, 5:6:5 */ -#define M_VESA_FULL_640 0x112 /* 640x480, 8:8:8 */ -#define M_VESA_32K_800 0x113 /* 800x600, 5:5:5 */ -#define M_VESA_64K_800 0x114 /* 800x600, 5:6:5 */ -#define M_VESA_FULL_800 0x115 /* 800x600, 8:8:8 */ -#define M_VESA_32K_1024 0x116 /* 1024x768, 5:5:5 */ -#define M_VESA_64K_1024 0x117 /* 1024x768, 5:6:5 */ -#define M_VESA_FULL_1024 0x118 /* 1024x768, 8:8:8 */ -#define M_VESA_32K_1280 0x119 /* 1280x1024, 5:5:5 */ -#define M_VESA_64K_1280 0x11a /* 1280x1024, 5:6:5 */ -#define M_VESA_FULL_1280 0x11b /* 1280x1024, 8:8:8 */ -#define M_VESA_MODE_MAX 0x1ff - -#define SW_VESA_CG640x400 _IO('V', M_VESA_CG640x400 - M_VESA_BASE) -#define SW_VESA_CG640x480 _IO('V', M_VESA_CG640x480 - M_VESA_BASE) -#define SW_VESA_800x600 _IO('V', M_VESA_800x600 - M_VESA_BASE) -#define SW_VESA_CG800x600 _IO('V', M_VESA_CG800x600 - M_VESA_BASE) -#define SW_VESA_1024x768 _IO('V', M_VESA_1024x768 - M_VESA_BASE) -#define SW_VESA_CG1024x768 _IO('V', M_VESA_CG1024x768 - M_VESA_BASE) -#define SW_VESA_1280x1024 _IO('V', M_VESA_1280x1024 - M_VESA_BASE) -#define SW_VESA_CG1280x1024 _IO('V', M_VESA_CG1280x1024 - M_VESA_BASE) -#define SW_VESA_C80x60 _IO('V', M_VESA_C80x60 - M_VESA_BASE) -#define SW_VESA_C132x25 _IO('V', M_VESA_C132x25 - M_VESA_BASE) -#define SW_VESA_C132x43 _IO('V', M_VESA_C132x43 - M_VESA_BASE) -#define SW_VESA_C132x50 _IO('V', M_VESA_C132x50 - M_VESA_BASE) -#define SW_VESA_C132x60 _IO('V', M_VESA_C132x60 - M_VESA_BASE) -#define SW_VESA_32K_320 _IO('V', M_VESA_32K_320 - M_VESA_BASE) -#define SW_VESA_64K_320 _IO('V', M_VESA_64K_320 - M_VESA_BASE) -#define SW_VESA_FULL_320 _IO('V', M_VESA_FULL_320 - M_VESA_BASE) -#define SW_VESA_32K_640 _IO('V', M_VESA_32K_640 - M_VESA_BASE) -#define SW_VESA_64K_640 _IO('V', M_VESA_64K_640 - M_VESA_BASE) -#define SW_VESA_FULL_640 _IO('V', M_VESA_FULL_640 - M_VESA_BASE) -#define SW_VESA_32K_800 _IO('V', M_VESA_32K_800 - M_VESA_BASE) -#define SW_VESA_64K_800 _IO('V', M_VESA_64K_800 - M_VESA_BASE) -#define SW_VESA_FULL_800 _IO('V', M_VESA_FULL_800 - M_VESA_BASE) -#define SW_VESA_32K_1024 _IO('V', M_VESA_32K_1024 - M_VESA_BASE) -#define SW_VESA_64K_1024 _IO('V', M_VESA_64K_1024 - M_VESA_BASE) -#define SW_VESA_FULL_1024 _IO('V', M_VESA_FULL_1024 - M_VESA_BASE) -#define SW_VESA_32K_1280 _IO('V', M_VESA_32K_1280 - M_VESA_BASE) -#define SW_VESA_64K_1280 _IO('V', M_VESA_64K_1280 - M_VESA_BASE) -#define SW_VESA_FULL_1280 _IO('V', M_VESA_FULL_1280 - M_VESA_BASE) +#include <sys/fbio.h> +#include <sys/kbio.h> +#include <sys/consio.h> #endif /* !_MACHINE_CONSOLE_H_ */ - diff --git a/sys/i386/isa/pcvt/pcvt_drv.c b/sys/i386/isa/pcvt/pcvt_drv.c index a0dd214..c988fef 100644 --- a/sys/i386/isa/pcvt/pcvt_drv.c +++ b/sys/i386/isa/pcvt/pcvt_drv.c @@ -93,6 +93,7 @@ static void *pcvt_devfs_token[MAXCONS]; #endif /*DEVFS*/ #if PCVT_FREEBSD >= 200 +#include <sys/bus.h> #include <machine/stdarg.h> #else #include "machine/stdarg.h" @@ -121,7 +122,7 @@ static cn_getc_t pccngetc; static cn_checkc_t pccncheckc; static cn_putc_t pccnputc; -CONS_DRIVER(pc, pccnprobe, pccninit, pccngetc, pccncheckc, pccnputc); +CONS_DRIVER(pc, pccnprobe, pccninit, NULL, pccngetc, pccncheckc, pccnputc); static d_open_t pcopen; static d_close_t pcclose; @@ -1178,6 +1179,12 @@ pccnprobe(struct consdev *cp) static int uarg = 0; int i; + /* See if this driver is disabled in probe hint. */ + if (resource_int_value("vt", 0, "disabled", &i) == 0 && i) { + cp->cn_pri = CN_DEAD; + return; + } + #ifdef _DEV_KBD_KBDREG_H_ /* * Don't reset the keyboard via `kbdio' just yet. diff --git a/sys/i386/isa/vesa.c b/sys/i386/isa/vesa.c index d734c64..0756880 100644 --- a/sys/i386/isa/vesa.c +++ b/sys/i386/isa/vesa.c @@ -23,7 +23,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: vesa.c,v 1.23 1999/05/09 15:57:52 peter Exp $ + * $Id: vesa.c,v 1.24 1999/06/01 18:20:18 jlemon Exp $ */ #include "vga.h" @@ -42,10 +42,13 @@ #include <sys/kernel.h> #include <sys/module.h> #include <sys/malloc.h> +#include <sys/fbio.h> + #include <vm/vm.h> +#include <vm/vm_extern.h> +#include <vm/vm_kern.h> #include <vm/pmap.h> -#include <machine/console.h> #include <machine/md_var.h> #include <machine/vm86.h> #include <machine/pc/bios.h> @@ -75,12 +78,10 @@ typedef struct adp_state adp_state_t; /* VESA video adapter */ static video_adapter_t *vesa_adp = NULL; static int vesa_state_buf_size = 0; -#if 0 -static void *vesa_state_buf = NULL; -#endif /* VESA functions */ static int vesa_nop(void); +static int vesa_error(void); static vi_probe_t vesa_probe; static vi_init_t vesa_init; static vi_get_info_t vesa_get_info; @@ -98,8 +99,14 @@ static vi_set_win_org_t vesa_set_origin; static vi_read_hw_cursor_t vesa_read_hw_cursor; static vi_set_hw_cursor_t vesa_set_hw_cursor; static vi_set_hw_cursor_shape_t vesa_set_hw_cursor_shape; +static vi_blank_display_t vesa_blank_display; static vi_mmap_t vesa_mmap; +static vi_ioctl_t vesa_ioctl; +static vi_clear_t vesa_clear; +static vi_fill_rect_t vesa_fill_rect; +static vi_bitblt_t vesa_bitblt; static vi_diag_t vesa_diag; +static int vesa_bios_info(int level); static struct vm86context vesa_vmcontext; static video_switch_t vesavidsw = { @@ -120,8 +127,14 @@ static video_switch_t vesavidsw = { vesa_read_hw_cursor, vesa_set_hw_cursor, vesa_set_hw_cursor_shape, - (vi_blank_display_t *)vesa_nop, + vesa_blank_display, vesa_mmap, + vesa_ioctl, + vesa_clear, + vesa_fill_rect, + vesa_bitblt, + vesa_error, + vesa_error, vesa_diag, }; @@ -132,9 +145,11 @@ static video_switch_t *prevvidsw; #define EOT (-1) #define NA (-2) -static video_info_t vesa_vmode[VESA_MAXMODES + 1] = { - { EOT, }, -}; +#define MODE_TABLE_DELTA 8 + +static int vesa_vmode_max = 0; +static video_info_t vesa_vmode_empty = { EOT }; +static video_info_t *vesa_vmode = &vesa_vmode_empty; static int vesa_init_done = FALSE; static int has_vesa_bios = FALSE; @@ -155,8 +170,12 @@ static int vesa_bios_get_dac(void); static int vesa_bios_set_dac(int bits); static int vesa_bios_save_palette(int start, int colors, u_char *palette, int bits); +static int vesa_bios_save_palette2(int start, int colors, u_char *r, u_char *g, + u_char *b, int bits); static int vesa_bios_load_palette(int start, int colors, u_char *palette, int bits); +static int vesa_bios_load_palette2(int start, int colors, u_char *r, u_char *g, + u_char *b, int bits); #define STATE_SIZE 0 #define STATE_SAVE 1 #define STATE_LOAD 2 @@ -169,12 +188,20 @@ static int vesa_bios_load_palette(int start, int colors, u_char *palette, static int vesa_bios_state_buf_size(void); static int vesa_bios_save_restore(int code, void *p, size_t size); static int vesa_bios_get_line_length(void); +static int vesa_bios_set_line_length(int pixel); +static int vesa_bios_get_start(int *x, int *y); +static int vesa_bios_set_start(int x, int y); static int vesa_map_gen_mode_num(int type, int color, int mode); static int vesa_translate_flags(u_int16_t vflags); +static int vesa_translate_mmodel(u_int8_t vmodel); static void *vesa_fix_ptr(u_int32_t p, u_int16_t seg, u_int16_t off, u_char *buf); static int vesa_bios_init(void); static void vesa_clear_modes(video_info_t *info, int color); +static vm_offset_t vesa_map_buffer(u_int paddr, size_t size); +static void vesa_unmap_buffer(vm_offset_t vaddr, size_t size); + +static int vesa_get_origin(video_adapter_t *adp, off_t *offset); static void dump_buffer(u_char *buf, size_t len) @@ -294,6 +321,36 @@ vesa_bios_save_palette(int start, int colors, u_char *palette, int bits) } static int +vesa_bios_save_palette2(int start, int colors, u_char *r, u_char *g, u_char *b, + int bits) +{ + struct vm86frame vmf; + u_char *p; + int err; + int i; + + bzero(&vmf, sizeof(vmf)); + vmf.vmf_eax = 0x4f09; + vmf.vmf_ebx = 1; /* get primary palette data */ + vmf.vmf_ecx = colors; + vmf.vmf_edx = start; + p = (u_char *)vm86_getpage(&vesa_vmcontext, 1); + vm86_getptr(&vesa_vmcontext, (vm_offset_t)p, &vmf.vmf_es, &vmf.vmf_di); + + err = vm86_datacall(0x10, &vmf, &vesa_vmcontext); + if ((err != 0) || (vmf.vmf_eax != 0x4f)) + return 1; + + bits = 8 - bits; + for (i = 0; i < colors; ++i) { + r[i] = p[i*4 + 2] << bits; + g[i] = p[i*4 + 1] << bits; + b[i] = p[i*4] << bits; + } + return 0; +} + +static int vesa_bios_load_palette(int start, int colors, u_char *palette, int bits) { struct vm86frame vmf; @@ -322,6 +379,35 @@ vesa_bios_load_palette(int start, int colors, u_char *palette, int bits) } static int +vesa_bios_load_palette2(int start, int colors, u_char *r, u_char *g, u_char *b, + int bits) +{ + struct vm86frame vmf; + u_char *p; + int err; + int i; + + p = (u_char *)vm86_getpage(&vesa_vmcontext, 1); + bits = 8 - bits; + for (i = 0; i < colors; ++i) { + p[i*4] = b[i] >> bits; + p[i*4 + 1] = g[i] >> bits; + p[i*4 + 2] = r[i] >> bits; + p[i*4 + 3] = 0; + } + + bzero(&vmf, sizeof(vmf)); + vmf.vmf_eax = 0x4f09; + vmf.vmf_ebx = 0; /* set primary palette data */ + vmf.vmf_ecx = colors; + vmf.vmf_edx = start; + vm86_getptr(&vesa_vmcontext, (vm_offset_t)p, &vmf.vmf_es, &vmf.vmf_di); + + err = vm86_datacall(0x10, &vmf, &vesa_vmcontext); + return ((err != 0) || (vmf.vmf_eax != 0x4f)); +} + +static int vesa_bios_state_buf_size(void) { struct vm86frame vmf; @@ -371,6 +457,55 @@ vesa_bios_get_line_length(void) return vmf.vmf_bx; /* line length in bytes */ } +static int +vesa_bios_set_line_length(int pixel) +{ + struct vm86frame vmf; + int err; + + bzero(&vmf, sizeof(vmf)); + vmf.vmf_eax = 0x4f06; + vmf.vmf_ebx = 0; /* set scan line length in pixel */ + vmf.vmf_ecx = pixel; + err = vm86_intcall(0x10, &vmf); +#if VESA_DEBUG > 1 + printf("bx:%d, cx:%d, dx:%d\n", vmf.vmf_bx, vmf.vmf_cx, vmf.vmf_dx); +#endif + return ((err != 0) || (vmf.vmf_eax != 0x4f)); +} + +static int +vesa_bios_get_start(int *x, int *y) +{ + struct vm86frame vmf; + int err; + + bzero(&vmf, sizeof(vmf)); + vmf.vmf_eax = 0x4f07; + vmf.vmf_ebx = 1; /* get display start */ + err = vm86_intcall(0x10, &vmf); + if ((err != 0) || (vmf.vmf_eax != 0x4f)) + return 1; + *x = vmf.vmf_cx; + *y = vmf.vmf_dx; + return 0; +} + +static int +vesa_bios_set_start(int x, int y) +{ + struct vm86frame vmf; + int err; + + bzero(&vmf, sizeof(vmf)); + vmf.vmf_eax = 0x4f07; + vmf.vmf_ebx = 0x80; /* set display start */ + vmf.vmf_edx = y; + vmf.vmf_ecx = x; + err = vm86_intcall(0x10, &vmf); + return ((err != 0) || (vmf.vmf_eax != 0x4f)); +} + /* map a generic video mode to a known mode */ static int vesa_map_gen_mode_num(int type, int color, int mode) @@ -415,6 +550,29 @@ vesa_translate_flags(u_int16_t vflags) return flags; } +static int +vesa_translate_mmodel(u_int8_t vmodel) +{ + static struct { + u_int8_t vmodel; + int mmodel; + } mtable[] = { + { V_MMTEXT, V_INFO_MM_TEXT }, + { V_MMCGA, V_INFO_MM_CGA }, + { V_MMHGC, V_INFO_MM_HGC }, + { V_MMEGA, V_INFO_MM_PLANAR }, + { V_MMPACKED, V_INFO_MM_PACKED }, + { V_MMDIRCOLOR, V_INFO_MM_DIRECT }, + }; + int i; + + for (i = 0; mtable[i].mmodel >= 0; ++i) { + if (mtable[i].vmodel == vmodel) + return mtable[i].mmodel; + } + return V_INFO_MM_OTHER; +} + static void *vesa_fix_ptr(u_int32_t p, u_int16_t seg, u_int16_t off, u_char *buf) { @@ -434,6 +592,7 @@ vesa_bios_init(void) static u_char buf[512]; struct vm86frame vmf; struct vesa_mode vmode; + video_info_t *p; u_char *vmbuf; int modes; int err; @@ -444,6 +603,7 @@ vesa_bios_init(void) has_vesa_bios = FALSE; vesa_adp_info = NULL; + vesa_vmode_max = 0; vesa_vmode[0].vi_mode = EOT; vmbuf = (u_char *)vm86_addpage(&vesa_vmcontext, 1, 0); @@ -463,6 +623,15 @@ vesa_bios_init(void) } if (vesa_adp_info->v_flags & V_NONVGA) return 1; + if (vesa_adp_info->v_version < 0x0102) { + printf("VESA: VBE version %d.%d is not supported; " + "version 1.2 or later is required.\n", + ((vesa_adp_info->v_version & 0xf000) >> 12) * 10 + + ((vesa_adp_info->v_version & 0x0f00) >> 8), + ((vesa_adp_info->v_version & 0x00f0) >> 4) * 10 + + (vesa_adp_info->v_version & 0x000f)); + return 1; + } /* fix string ptrs */ vesa_oemstr = (char *)vesa_fix_ptr(vesa_adp_info->v_oemstr, @@ -480,7 +649,6 @@ vesa_bios_init(void) } /* obtain video mode information */ - vesa_vmode[0].vi_mode = EOT; vesa_vmodetab = (u_int16_t *)vesa_fix_ptr(vesa_adp_info->v_modetable, vmf.vmf_es, vmf.vmf_di, buf); if (vesa_vmodetab == NULL) @@ -488,8 +656,6 @@ vesa_bios_init(void) for (i = 0, modes = 0; (i < (M_VESA_MODE_MAX - M_VESA_BASE + 1)) && (vesa_vmodetab[i] != 0xffff); ++i) { - if (modes >= VESA_MAXMODES) - break; if (vesa_bios_get_mode(vesa_vmodetab[i], &vmode)) continue; @@ -505,6 +671,22 @@ vesa_bios_init(void) continue; #endif + /* expand the array if necessary */ + if (modes >= vesa_vmode_max) { + vesa_vmode_max += MODE_TABLE_DELTA; + p = malloc(sizeof(*vesa_vmode)*(vesa_vmode_max + 1), + M_DEVBUF, M_WAITOK); +#if VESA_DEBUG > 1 + printf("vesa_bios_init(): modes:%d, vesa_mode_max:%d\n", + modes, vesa_mode_max); +#endif + if (modes > 0) { + bcopy(vesa_vmode, p, sizeof(*vesa_vmode)*modes); + free(vesa_vmode, M_DEVBUF); + } + vesa_vmode = p; + } + /* copy some fields */ bzero(&vesa_vmode[modes], sizeof(vesa_vmode[modes])); vesa_vmode[modes].vi_mode = vesa_vmodetab[i]; @@ -518,15 +700,56 @@ vesa_bios_init(void) /* XXX window B */ vesa_vmode[modes].vi_window_size = vmode.v_wsize*1024; vesa_vmode[modes].vi_window_gran = vmode.v_wgran*1024; - vesa_vmode[modes].vi_buffer = vmode.v_lfb; + if (vmode.v_modeattr & V_MODELFB) + vesa_vmode[modes].vi_buffer = vmode.v_lfb; + else + vesa_vmode[modes].vi_buffer = 0; /* XXX */ + vesa_vmode[modes].vi_buffer_size + = vesa_adp_info->v_memsize*64*1024; +#if 0 if (vmode.v_offscreen > vmode.v_lfb) vesa_vmode[modes].vi_buffer_size - = vmode.v_offscreen - vmode.v_lfb; + = vmode.v_offscreen + vmode.v_offscreensize*1024 + - vmode.v_lfb; else - vesa_vmode[modes].vi_buffer_size = vmode.v_offscreen; - /* pixel format, memory model... */ - + vesa_vmode[modes].vi_buffer_size + = vmode.v_offscreen + vmode.v_offscreensize*1024 +#endif + vesa_vmode[modes].vi_mem_model + = vesa_translate_mmodel(vmode.v_memmodel); + vesa_vmode[modes].vi_pixel_fields[0] = 0; + vesa_vmode[modes].vi_pixel_fields[1] = 0; + vesa_vmode[modes].vi_pixel_fields[2] = 0; + vesa_vmode[modes].vi_pixel_fields[3] = 0; + vesa_vmode[modes].vi_pixel_fsizes[0] = 0; + vesa_vmode[modes].vi_pixel_fsizes[1] = 0; + vesa_vmode[modes].vi_pixel_fsizes[2] = 0; + vesa_vmode[modes].vi_pixel_fsizes[3] = 0; + if (vesa_vmode[modes].vi_mem_model == V_INFO_MM_PACKED) { + vesa_vmode[modes].vi_pixel_size = (vmode.v_bpp + 7)/8; + } else if (vesa_vmode[modes].vi_mem_model == V_INFO_MM_DIRECT) { + vesa_vmode[modes].vi_pixel_size = (vmode.v_bpp + 7)/8; + vesa_vmode[modes].vi_pixel_fields[0] + = vmode.v_redfieldpos; + vesa_vmode[modes].vi_pixel_fields[1] + = vmode.v_greenfieldpos; + vesa_vmode[modes].vi_pixel_fields[2] + = vmode.v_bluefieldpos; + vesa_vmode[modes].vi_pixel_fields[3] + = vmode.v_resfieldpos; + vesa_vmode[modes].vi_pixel_fsizes[0] + = vmode.v_redmasksize; + vesa_vmode[modes].vi_pixel_fsizes[1] + = vmode.v_greenmasksize; + vesa_vmode[modes].vi_pixel_fsizes[2] + = vmode.v_bluemasksize; + vesa_vmode[modes].vi_pixel_fsizes[3] + = vmode.v_resmasksize; + } else { + vesa_vmode[modes].vi_pixel_size = 0; + } + vesa_vmode[modes].vi_flags = vesa_translate_flags(vmode.v_modeattr) | V_INFO_VESA; ++modes; @@ -549,6 +772,30 @@ vesa_clear_modes(video_info_t *info, int color) } } +static vm_offset_t +vesa_map_buffer(u_int paddr, size_t size) +{ + vm_offset_t vaddr; + u_int off; + + off = paddr - trunc_page(paddr); + vaddr = (vm_offset_t)pmap_mapdev(paddr - off, size + off); +#if VESA_DEBUG > 1 + printf("vesa_map_buffer: paddr:%x vaddr:%x size:%x off:%x\n", + paddr, vaddr, size, off); +#endif + return (vaddr + off); +} + +static void +vesa_unmap_buffer(vm_offset_t vaddr, size_t size) +{ +#if VESA_DEBUG > 1 + printf("vesa_unmap_buffer: vaddr:%x size:%x\n", vaddr, size); +#endif + kmem_free(kernel_map, vaddr, size); +} + /* entry points */ static int @@ -624,6 +871,12 @@ vesa_nop(void) } static int +vesa_error(void) +{ + return 1; +} + +static int vesa_probe(int unit, video_adapter_t **adpp, void *arg, int flags) { return (*prevvidsw->probe)(unit, adpp, arg, flags); @@ -701,43 +954,36 @@ static int vesa_set_mode(video_adapter_t *adp, int mode) { video_info_t info; - size_t len; + int len; if (adp != vesa_adp) return (*prevvidsw->set_mode)(adp, mode); - mode = vesa_map_gen_mode_num(vesa_adp->va_type, - vesa_adp->va_flags & V_ADP_COLOR, mode); + mode = vesa_map_gen_mode_num(adp->va_type, + adp->va_flags & V_ADP_COLOR, mode); #if VESA_DEBUG > 0 printf("VESA: set_mode(): %d(%x) -> %d(%x)\n", - vesa_adp->va_mode, vesa_adp->va_mode, mode, mode); + adp->va_mode, adp->va_mode, mode, mode); #endif /* * If the current mode is a VESA mode and the new mode is not, - * restore the state of the adapter first, so that non-standard, - * extended SVGA registers are set to the state compatible with - * the standard VGA modes. Otherwise (*prevvidsw->set_mode)() - * may not be able to set up the new mode correctly. + * restore the state of the adapter first by setting one of the + * standard VGA mode, so that non-standard, extended SVGA registers + * are set to the state compatible with the standard VGA modes. + * Otherwise (*prevvidsw->set_mode)() may not be able to set up + * the new mode correctly. */ - if (VESA_MODE(vesa_adp->va_mode)) { + if (VESA_MODE(adp->va_mode)) { if ((*prevvidsw->get_info)(adp, mode, &info) == 0) { - int10_set_mode(vesa_adp->va_initial_bios_mode); -#if 0 - /* assert(vesa_state_buf != NULL); */ - if ((vesa_state_buf == NULL) - || vesa_load_state(adp, vesa_state_buf)) - return 1; - free(vesa_state_buf, M_DEVBUF); - vesa_state_buf = NULL; -#if VESA_DEBUG > 0 - printf("VESA: restored\n"); -#endif -#endif /* 0 */ + int10_set_mode(adp->va_initial_bios_mode); + if (adp->va_info.vi_flags & V_INFO_LINEAR) + vesa_unmap_buffer(adp->va_buffer, + vesa_adp_info->v_memsize*64*1024); + /* + * Once (*prevvidsw->get_info)() succeeded, + * (*prevvidsw->set_mode)() below won't fail... + */ } - /* - * once (*prevvidsw->get_info)() succeeded, - * (*prevvidsw->set_mode)() below won't fail... - */ } /* we may not need to handle this mode after all... */ @@ -752,33 +998,17 @@ vesa_set_mode(video_adapter_t *adp, int mode) #if VESA_DEBUG > 0 printf("VESA: about to set a VESA mode...\n"); #endif - /* - * If the current mode is not a VESA mode, save the current state - * so that the adapter state can be restored later when a non-VESA - * mode is to be set up. See above. - */ -#if 0 - if (!VESA_MODE(vesa_adp->va_mode) && (vesa_state_buf == NULL)) { - len = vesa_save_state(adp, NULL, 0); - vesa_state_buf = malloc(len, M_DEVBUF, M_WAITOK); - if (vesa_save_state(adp, vesa_state_buf, len)) { -#if VESA_DEBUG > 0 - printf("VESA: state save failed! (len=%d)\n", len); -#endif - free(vesa_state_buf, M_DEVBUF); - vesa_state_buf = NULL; - return 1; - } -#if VESA_DEBUG > 0 - printf("VESA: saved (len=%d)\n", len); - dump_buffer(vesa_state_buf, len); -#endif - } -#endif /* 0 */ + /* don't use the linear frame buffer for text modes. XXX */ + if (!(info.vi_flags & V_INFO_GRAPHICS)) + info.vi_flags &= ~V_INFO_LINEAR; - if (vesa_bios_set_mode(mode)) + if (vesa_bios_set_mode(mode | ((info.vi_flags & V_INFO_LINEAR) ? 0x4000 : 0))) return 1; + if (adp->va_info.vi_flags & V_INFO_LINEAR) + vesa_unmap_buffer(adp->va_buffer, + vesa_adp_info->v_memsize*64*1024); + #if VESA_DEBUG > 0 printf("VESA: mode set!\n"); #endif @@ -788,16 +1018,25 @@ vesa_set_mode(video_adapter_t *adp, int mode) (info.vi_flags & V_INFO_COLOR) ? V_ADP_COLOR : 0; vesa_adp->va_crtc_addr = (vesa_adp->va_flags & V_ADP_COLOR) ? COLOR_CRTC : MONO_CRTC; - vesa_adp->va_window = BIOS_PADDRTOVADDR(info.vi_window); - vesa_adp->va_window_size = info.vi_window_size; - vesa_adp->va_window_gran = info.vi_window_gran; - if (info.vi_buffer_size == 0) { - vesa_adp->va_buffer = 0; - vesa_adp->va_buffer_size = 0; + if (info.vi_flags & V_INFO_LINEAR) { +#if VESA_DEBUG > 1 + printf("VESA: setting up LFB\n"); +#endif + vesa_adp->va_buffer = + vesa_map_buffer(info.vi_buffer, + vesa_adp_info->v_memsize*64*1024); + vesa_adp->va_buffer_size = info.vi_buffer_size; + vesa_adp->va_window = vesa_adp->va_buffer; + vesa_adp->va_window_size = info.vi_buffer_size/info.vi_planes; + vesa_adp->va_window_gran = info.vi_buffer_size/info.vi_planes; } else { - vesa_adp->va_buffer = BIOS_PADDRTOVADDR(info.vi_buffer); + vesa_adp->va_buffer = 0; vesa_adp->va_buffer_size = info.vi_buffer_size; + vesa_adp->va_window = BIOS_PADDRTOVADDR(info.vi_window); + vesa_adp->va_window_size = info.vi_window_size; + vesa_adp->va_window_gran = info.vi_window_gran; } + vesa_adp->va_window_orig = 0; len = vesa_bios_get_line_length(); if (len > 0) { vesa_adp->va_line_width = len; @@ -820,6 +1059,8 @@ vesa_set_mode(video_adapter_t *adp, int mode) } else { vesa_adp->va_line_width = info.vi_width; } + vesa_adp->va_disp_start.x = 0; + vesa_adp->va_disp_start.y = 0; #if VESA_DEBUG > 0 printf("vesa_set_mode(): vi_width:%d, len:%d, line_width:%d\n", info.vi_width, len, vesa_adp->va_line_width); @@ -927,6 +1168,22 @@ vesa_load_state(video_adapter_t *adp, void *p) } static int +vesa_get_origin(video_adapter_t *adp, off_t *offset) +{ + struct vm86frame vmf; + int err; + + bzero(&vmf, sizeof(vmf)); + vmf.vmf_eax = 0x4f05; + vmf.vmf_ebx = 0x10; /* WINDOW_A, XXX */ + err = vm86_intcall(0x10, &vmf); + if ((err != 0) || (vmf.vmf_eax != 0x4f)) + return 1; + *offset = vmf.vmf_dx*adp->va_window_gran; + return 0; +} + +static int vesa_set_origin(video_adapter_t *adp, off_t offset) { struct vm86frame vmf; @@ -941,20 +1198,26 @@ vesa_set_origin(video_adapter_t *adp, off_t offset) if (adp != vesa_adp) return (*prevvidsw->set_win_org)(adp, offset); - if (vesa_adp->va_window_gran == 0) + /* if this is a linear frame buffer, do nothing */ + if (adp->va_info.vi_flags & V_INFO_LINEAR) + return 0; + /* XXX */ + if (adp->va_window_gran == 0) return 1; + bzero(&vmf, sizeof(vmf)); vmf.vmf_eax = 0x4f05; vmf.vmf_ebx = 0; /* WINDOW_A, XXX */ - vmf.vmf_edx = offset/vesa_adp->va_window_gran; + vmf.vmf_edx = offset/adp->va_window_gran; err = vm86_intcall(0x10, &vmf); if ((err != 0) || (vmf.vmf_eax != 0x4f)) return 1; bzero(&vmf, sizeof(vmf)); vmf.vmf_eax = 0x4f05; vmf.vmf_ebx = 1; /* WINDOW_B, XXX */ - vmf.vmf_edx = offset/vesa_adp->va_window_gran; + vmf.vmf_edx = offset/adp->va_window_gran; err = vm86_intcall(0x10, &vmf); + adp->va_window_orig = (offset/adp->va_window_gran)*adp->va_window_gran; return 0; /* XXX */ } @@ -979,25 +1242,222 @@ vesa_set_hw_cursor_shape(video_adapter_t *adp, int base, int height, } static int -vesa_mmap(video_adapter_t *adp, vm_offset_t offset) +vesa_blank_display(video_adapter_t *adp, int mode) { - return (*prevvidsw->mmap)(adp, offset); + /* XXX: use VESA DPMS */ + return (*prevvidsw->blank_display)(adp, mode); } static int -vesa_diag(video_adapter_t *adp, int level) +vesa_mmap(video_adapter_t *adp, vm_offset_t offset, int prot) { -#if VESA_DEBUG > 1 - struct vesa_mode vmode; - int i; +#if VESA_DEBUG > 0 + printf("vesa_mmap(): window:0x%x, buffer:0x%x, offset:0x%x\n", + adp->va_info.vi_window, adp->va_info.vi_buffer, offset); #endif - if (adp != vesa_adp) + if ((adp == vesa_adp) && (adp->va_info.vi_flags & V_INFO_LINEAR)) { + /* va_window_size == va_buffer_size/vi_planes */ + /* XXX: is this correct? */ + if (offset > adp->va_window_size - PAGE_SIZE) + return -1; +#ifdef __i386__ + return i386_btop(adp->va_info.vi_buffer + offset); +#endif +#ifdef __alpha__ /* XXX */ + return alpha_btop(adp->va_info.vi_buffer + offset); +#endif + } else { + return (*prevvidsw->mmap)(adp, offset, prot); + } +} + +static int +vesa_clear(video_adapter_t *adp) +{ + return (*prevvidsw->clear)(adp); +} + +static int +vesa_fill_rect(video_adapter_t *adp, int val, int x, int y, int cx, int cy) +{ + return (*prevvidsw->fill_rect)(adp, val, x, y, cx, cy); +} + +static int +vesa_bitblt(video_adapter_t *adp,...) +{ + /* FIXME */ + return 1; +} + +static int +get_palette(video_adapter_t *adp, int base, int count, + u_char *red, u_char *green, u_char *blue, u_char *trans) +{ + u_char *r; + u_char *g; + u_char *b; + int bits; + int error; + + if ((base < 0) || (base >= 256) || (base + count > 256)) + return 1; + if (!(vesa_adp_info->v_flags & V_DAC8) || !VESA_MODE(adp->va_mode)) return 1; -#ifndef KLD_MODULE + bits = vesa_bios_get_dac(); + if (bits <= 6) + return 1; + + r = malloc(count*3, M_DEVBUF, M_WAITOK); + g = r + count; + b = g + count; + error = vesa_bios_save_palette2(base, count, r, g, b, bits); + if (error == 0) { + copyout(r, red, count); + copyout(g, green, count); + copyout(b, blue, count); + if (trans != NULL) { + bzero(r, count); + copyout(r, trans, count); + } + } + free(r, M_DEVBUF); + + /* if error && bits != 6 at this point, we are in in trouble... XXX */ + return error; +} + +static int +set_palette(video_adapter_t *adp, int base, int count, + u_char *red, u_char *green, u_char *blue, u_char *trans) +{ + return 1; +#if notyet + u_char *r; + u_char *g; + u_char *b; + int bits; + int error; + + if ((base < 0) || (base >= 256) || (base + count > 256)) + return 1; + if (!(vesa_adp_info->v_flags & V_DAC8) || !VESA_MODE(adp->va_mode) + || ((bits = vesa_bios_set_dac(8)) <= 6)) + return 1; + + r = malloc(count*3, M_DEVBUF, M_WAITOK); + g = r + count; + b = g + count; + copyin(red, r, count); + copyin(green, g, count); + copyin(blue, b, count); + + error = vesa_bios_load_palette2(base, count, r, g, b, bits); + free(r, M_DEVBUF); + if (error == 0) + return 0; + + /* if the following call fails, we are in trouble... XXX */ + vesa_bios_set_dac(6); + return 1; +#endif /* notyet */ +} + +static int +vesa_ioctl(video_adapter_t *adp, u_long cmd, caddr_t arg) +{ + if (adp != vesa_adp) + return (*prevvidsw->ioctl)(adp, cmd, arg); + + switch (cmd) { + case FBIO_SETWINORG: /* set frame buffer window origin */ + return (vesa_set_origin(adp, *(off_t *)arg) ? ENODEV : 0); + + case FBIO_SETDISPSTART: /* set display start address */ + if (vesa_bios_set_start(((video_display_start_t *)arg)->x, + ((video_display_start_t *)arg)->y)) + return ENODEV; + adp->va_disp_start.x = ((video_display_start_t *)arg)->x; + adp->va_disp_start.y = ((video_display_start_t *)arg)->y; + return 0; + + case FBIO_SETLINEWIDTH: /* set line length in pixel */ + if (vesa_bios_set_line_length(*(u_int *)arg)) + return ENODEV; + adp->va_line_width = (*(u_int *)arg + 7)/8; + return 0; + + case FBIO_GETPALETTE: /* get color palette */ + if (get_palette(adp, ((video_color_palette_t *)arg)->index, + ((video_color_palette_t *)arg)->count, + ((video_color_palette_t *)arg)->red, + ((video_color_palette_t *)arg)->green, + ((video_color_palette_t *)arg)->blue, + ((video_color_palette_t *)arg)->transparent)) + return (*prevvidsw->ioctl)(adp, cmd, arg); + return 0; + + + case FBIO_SETPALETTE: /* set color palette */ + if (set_palette(adp, ((video_color_palette_t *)arg)->index, + ((video_color_palette_t *)arg)->count, + ((video_color_palette_t *)arg)->red, + ((video_color_palette_t *)arg)->green, + ((video_color_palette_t *)arg)->blue, + ((video_color_palette_t *)arg)->transparent)) + return (*prevvidsw->ioctl)(adp, cmd, arg); + return 0; + + case FBIOGETCMAP: /* get color palette */ + if (get_palette(adp, ((struct fbcmap *)arg)->index, + ((struct fbcmap *)arg)->count, + ((struct fbcmap *)arg)->red, + ((struct fbcmap *)arg)->green, + ((struct fbcmap *)arg)->blue, NULL)) + return (*prevvidsw->ioctl)(adp, cmd, arg); + return 0; + + case FBIOPUTCMAP: /* set color palette */ + if (set_palette(adp, ((struct fbcmap *)arg)->index, + ((struct fbcmap *)arg)->count, + ((struct fbcmap *)arg)->red, + ((struct fbcmap *)arg)->green, + ((struct fbcmap *)arg)->blue, NULL)) + return (*prevvidsw->ioctl)(adp, cmd, arg); + return 0; + + default: + return (*prevvidsw->ioctl)(adp, cmd, arg); + } +} + +static int +vesa_diag(video_adapter_t *adp, int level) +{ + int error; + /* call the previous handler first */ - (*prevvidsw->diag)(adp, level); + error = (*prevvidsw->diag)(adp, level); + if (error) + return error; + + if (adp != vesa_adp) + return 1; + + if (level <= 0) + return 0; + + return 0; +} + +static int +vesa_bios_info(int level) +{ +#if VESA_DEBUG > 1 + struct vesa_mode vmode; + int i; #endif /* general adapter information */ @@ -1016,15 +1476,11 @@ vesa_diag(video_adapter_t *adp, int level) return 0; if (vesa_adp_info->v_version >= 0x0200) { - /* vendor name */ - if (vesa_venderstr != NULL) - printf("VESA: %s\n", vesa_venderstr); - /* product name */ - if (vesa_prodstr != NULL) - printf("VESA: %s\n", vesa_prodstr); - /* product revision */ - if (vesa_revstr != NULL) - printf("VESA: %s\n", vesa_revstr); + /* vender name, product name, product revision */ + printf("VESA: %s %s %s\n", + (vesa_venderstr != NULL) ? vesa_venderstr : "unknown", + (vesa_prodstr != NULL) ? vesa_prodstr : "unknown", + (vesa_revstr != NULL) ? vesa_revstr : "?"); } #if VESA_DEBUG > 1 @@ -1047,13 +1503,15 @@ vesa_diag(video_adapter_t *adp, int level) printf(", T %dx%d, ", vmode.v_width, vmode.v_height); } - printf("font:%dx%d", + printf("font:%dx%d, ", vmode.v_cwidth, vmode.v_cheight); + printf("pages:%d, mem:%d", + vmode.v_ipages + 1, vmode.v_memmodel); } if (vmode.v_modeattr & V_MODELFB) { - printf(", mem:%d, LFB:0x%x, off:0x%x", - vmode.v_memmodel, vmode.v_lfb, - vmode.v_offscreen); + printf("\nVESA: LFB:0x%x, off:0x%x, off_size:0x%x", + vmode.v_lfb, vmode.v_offscreen, + vmode.v_offscreensize*1024); } printf("\n"); printf("VESA: window A:0x%x (%x), window B:0x%x (%x), ", @@ -1062,7 +1520,7 @@ vesa_diag(video_adapter_t *adp, int level) printf("size:%dk, gran:%dk\n", vmode.v_wsize, vmode.v_wgran); } -#endif +#endif /* VESA_DEBUG > 1 */ return 0; } @@ -1084,14 +1542,14 @@ vesa_load(void) error = vesa_configure(0); splx(s); -#ifdef KLD_MODULE if (error == 0) - vesa_diag(vesa_adp, bootverbose); -#endif + vesa_bios_info(bootverbose); return error; } +#ifdef KLD_MODULE + static int vesa_unload(void) { @@ -1130,6 +1588,8 @@ vesa_unload(void) return error; } +#endif /* KLD_MODULE */ + static int vesa_mod_event(module_t mod, int type, void *data) { @@ -1137,7 +1597,11 @@ vesa_mod_event(module_t mod, int type, void *data) case MOD_LOAD: return vesa_load(); case MOD_UNLOAD: +#ifdef KLD_MODULE return vesa_unload(); +#else + return EBUSY; +#endif default: break; } diff --git a/sys/isa/sio.c b/sys/isa/sio.c index c3be310..6c17bc1 100644 --- a/sys/isa/sio.c +++ b/sys/isa/sio.c @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: sio.c,v 1.248 1999/06/19 08:14:56 grog Exp $ + * $Id: sio.c,v 1.249 1999/06/20 13:10:09 peter Exp $ * from: @(#)com.c 7.5 (Berkeley) 5/16/91 * from: i386/isa sio.c,v 1.234 */ @@ -2656,7 +2656,7 @@ static cn_checkc_t siocncheckc; static cn_getc_t siocngetc; static cn_putc_t siocnputc; -CONS_DRIVER(sio, siocnprobe, siocninit, siocngetc, siocncheckc, siocnputc); +CONS_DRIVER(sio, siocnprobe, siocninit, NULL, siocngetc, siocncheckc, siocnputc); /* To get the GDB related variables */ #if DDB > 0 @@ -2855,7 +2855,6 @@ siocnprobe(cp) cp->cn_pri = COM_FORCECONSOLE(flags) || boothowto & RB_SERIAL ? CN_REMOTE : CN_NORMAL; - printf("sio%d: system console\n", unit); siocniobase = iobase; siocnunit = unit; } @@ -2897,10 +2896,7 @@ siocnprobe(cp) #ifdef __alpha__ -struct consdev siocons = { - NULL, NULL, siocngetc, siocncheckc, siocnputc, - NULL, 0, CN_NORMAL, -}; +CONS_DRIVER(sio, NULL, NULL, NULL, siocngetc, siocncheckc, siocnputc); extern struct consdev *cn_tab; @@ -2915,6 +2911,8 @@ siocnattach(port, speed) siocniobase = port; comdefaultrate = speed; + sio_consdev.cn_pri = CN_NORMAL; + sio_consdev.cn_dev = makedev(CDEV_MAJOR, 0); s = spltty(); @@ -2938,8 +2936,7 @@ siocnattach(port, speed) siocnopen(&sp, siocniobase, comdefaultrate); splx(s); - siocons.cn_dev = makedev(CDEV_MAJOR, 0); - cn_tab = &siocons; + cn_tab = &sio_consdev; return 0; } diff --git a/sys/isa/syscons_isa.c b/sys/isa/syscons_isa.c index 85e626e..fcb2b06 100644 --- a/sys/isa/syscons_isa.c +++ b/sys/isa/syscons_isa.c @@ -23,7 +23,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: syscons_isa.c,v 1.3 1999/05/08 21:59:31 dfr Exp $ + * $Id: syscons_isa.c,v 1.4 1999/05/30 11:12:29 dfr Exp $ */ #include "sc.h" @@ -37,33 +37,53 @@ #include <sys/module.h> #include <sys/bus.h> +#include <machine/cons.h> #include <machine/console.h> + #ifdef __i386__ -#include <machine/apm_bios.h> -#endif + +#include <machine/clock.h> +#include <machine/md_var.h> +#include <machine/pc/bios.h> + +#include <vm/vm.h> +#include <vm/pmap.h> + +#include <i386/isa/timerreg.h> + +#define BIOS_CLKED (1 << 6) +#define BIOS_NLKED (1 << 5) +#define BIOS_SLKED (1 << 4) +#define BIOS_ALKED 0 + +#endif /* __i386__ */ #include <dev/syscons/syscons.h> #include <isa/isareg.h> #include <isa/isavar.h> -devclass_t sc_devclass; +static devclass_t sc_devclass; static int scprobe(device_t dev); static int scattach(device_t dev); +static int scresume(device_t dev); static device_method_t sc_methods[] = { DEVMETHOD(device_probe, scprobe), DEVMETHOD(device_attach, scattach), + DEVMETHOD(device_resume, scresume), { 0, 0 } }; static driver_t sc_driver = { - "sc", + SC_DRIVER_NAME, sc_methods, 1, /* XXX */ }; +static sc_softc_t main_softc = { 0, 0, 0, -1, NULL, -1, NULL, }; + static int scprobe(device_t dev) { @@ -81,6 +101,146 @@ scattach(device_t dev) return sc_attach_unit(device_get_unit(dev), isa_get_flags(dev)); } +static int +scresume(device_t dev) +{ + return sc_resume_unit(device_get_unit(dev)); +} + +int +sc_max_unit(void) +{ + return devclass_get_maxunit(sc_devclass); +} + +sc_softc_t +*sc_get_softc(int unit, int flags) +{ + sc_softc_t *sc; + + if ((unit < 0) || (unit >= NSC)) + return NULL; + if (flags & SC_KERNEL_CONSOLE) { + /* FIXME: clear if it is wired to another unit! */ + main_softc.unit = unit; + return &main_softc; + } else { + sc = (sc_softc_t *)devclass_get_softc(sc_devclass, unit); + if (!(sc->flags & SC_INIT_DONE)) { + sc->unit = unit; + sc->keyboard = -1; + sc->adapter = -1; + } + return sc; + } +} + +sc_softc_t +*sc_find_softc(struct video_adapter *adp, struct keyboard *kbd) +{ + sc_softc_t *sc; + int units; + int i; + + sc = &main_softc; + if (((adp == NULL) || (adp == sc->adp)) + && ((kbd == NULL) || (kbd == sc->kbd))) + return sc; + units = devclass_get_maxunit(sc_devclass); + for (i = 0; i < units; ++i) { + sc = (sc_softc_t *)devclass_get_softc(sc_devclass, i); + if (sc == NULL) + continue; + if (((adp == NULL) || (adp == sc->adp)) + && ((kbd == NULL) || (kbd == sc->kbd))) + return sc; + } + return NULL; +} + +int +sc_get_cons_priority(int *unit, int *flags) +{ + int disabled; + int u, f; + int i; + + *unit = -1; + for (i = -1; (i = resource_locate(i, SC_DRIVER_NAME)) >= 0;) { + u = resource_query_unit(i); + if ((resource_int_value(SC_DRIVER_NAME, u, "disabled", + &disabled) == 0) && disabled) + continue; + if (resource_int_value(SC_DRIVER_NAME, u, "flags", &f) != 0) + f = 0; + if (f & SC_KERNEL_CONSOLE) { + /* the user designates this unit to be the console */ + *unit = u; + *flags = f; + break; + } + if (*unit < 0) { + /* ...otherwise remember the first found unit */ + *unit = u; + *flags = f; + } + } + if ((i < 0) && (*unit < 0)) + return CN_DEAD; +#if 0 + return ((*flags & SC_KERNEL_CONSOLE) ? CN_INTERNAL : CN_NORMAL); +#endif + return CN_INTERNAL; +} + +void +sc_get_bios_values(bios_values_t *values) +{ +#ifdef __i386__ + u_int8_t shift; + + values->cursor_start = *(u_int8_t *)BIOS_PADDRTOVADDR(0x461); + values->cursor_end = *(u_int8_t *)BIOS_PADDRTOVADDR(0x460); + shift = *(u_int8_t *)BIOS_PADDRTOVADDR(0x417); + values->shift_state = ((shift & BIOS_CLKED) ? CLKED : 0) + | ((shift & BIOS_NLKED) ? NLKED : 0) + | ((shift & BIOS_SLKED) ? SLKED : 0) + | ((shift & BIOS_ALKED) ? ALKED : 0); + values->bell_pitch = BELL_PITCH; +#else /* !__i386__ */ + values->cursor_start = 0; + values->cursor_end = 32; + values->shift_state = 0; + values->bell_pitch = BELL_PITCH; +#endif /* __i386__ */ +} + +int +sc_tone(int herz) +{ +#ifdef __i386__ + int pitch; + + if (herz) { + /* set command for counter 2, 2 byte write */ + if (acquire_timer2(TIMER_16BIT | TIMER_SQWAVE)) + return EBUSY; + /* set pitch */ + pitch = timer_freq/herz; + outb(TIMER_CNTR2, pitch); + outb(TIMER_CNTR2, pitch >> 8); + /* enable counter 2 output to speaker */ + outb(IO_PPI, inb(IO_PPI) | 3); + } else { + /* disable counter 2 output to speaker */ + outb(IO_PPI, inb(IO_PPI) & 0xFC); + release_timer2(); + } +#endif /* __i386__ */ + + return 0; +} + DRIVER_MODULE(sc, isa, sc_driver, sc_devclass, 0, 0); #endif /* NSC > 0 */ diff --git a/sys/isa/vga_isa.c b/sys/isa/vga_isa.c index 07bffa8..813458e 100644 --- a/sys/isa/vga_isa.c +++ b/sys/isa/vga_isa.c @@ -1,6 +1,5 @@ /*- * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp> - * Copyright (c) 1992-1998 Søren Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -12,8 +11,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES @@ -26,7 +23,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: vga_isa.c,v 1.9 1999/05/30 11:12:30 dfr Exp $ + * $Id: vga_isa.c,v 1.10 1999/05/30 16:52:49 phk Exp $ */ #include "vga.h" @@ -39,13 +36,18 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> +#include <sys/conf.h> #include <sys/bus.h> -#include <sys/malloc.h> +#include <sys/fbio.h> + +#include <machine/bus.h> +#include <machine/resource.h> + +#include <sys/rman.h> #include <vm/vm.h> #include <vm/pmap.h> -#include <machine/console.h> #include <machine/md_var.h> #include <machine/pc/bios.h> @@ -55,21 +57,10 @@ #include <isa/isareg.h> #include <isa/isavar.h> -#define DRIVER_NAME "vga" - -/* cdev driver declaration */ - -#define ISAVGA_UNIT(dev) minor(dev) -#define ISAVGA_MKMINOR(unit) (unit) +#define VGA_SOFTC(unit) \ + ((vga_softc_t *)devclass_get_softc(isavga_devclass, unit)) -typedef struct isavga_softc { - video_adapter_t *adp; -} isavga_softc_t; - -#define ISAVGA_SOFTC(unit) \ - ((isavga_softc_t *)devclass_get_softc(isavga_devclass, unit)) - -devclass_t isavga_devclass; +static devclass_t isavga_devclass; static int isavga_probe(device_t dev); static int isavga_attach(device_t dev); @@ -77,42 +68,41 @@ static int isavga_attach(device_t dev); static device_method_t isavga_methods[] = { DEVMETHOD(device_probe, isavga_probe), DEVMETHOD(device_attach, isavga_attach), + + DEVMETHOD(bus_print_child, bus_generic_print_child), { 0, 0 } }; static driver_t isavga_driver = { - DRIVER_NAME, + VGA_DRIVER_NAME, isavga_methods, - sizeof(isavga_softc_t), + sizeof(vga_softc_t), }; DRIVER_MODULE(vga, isa, isavga_driver, isavga_devclass, 0, 0); -static int isavga_probe_unit(int unit, isavga_softc_t *sc, - int flags); -static int isavga_attach_unit(int unit, isavga_softc_t *sc, - int flags); - #ifdef FB_INSTALL_CDEV -static d_open_t isavgaopen; -static d_close_t isavgaclose; -static d_read_t isavgaread; -static d_ioctl_t isavgaioctl; - -static struct cdevsw vga_cdevsw = { - /* open */ isavgaopen, - /* close */ isavgaclose, - /* read */ noread, - /* write */ nowrite, - /* ioctl */ isavgaioctl, +static d_open_t isavga_open; +static d_close_t isavga_close; +static d_read_t isavga_read; +static d_write_t isavga_write; +static d_ioctl_t isavga_ioctl; +static d_mmap_t isavga_mmap; + +static struct cdevsw isavga_cdevsw = { + /* open */ isavga_open, + /* close */ isavga_close, + /* read */ isavga_read, + /* write */ isavga_write, + /* ioctl */ isavga_ioctl, /* stop */ nostop, /* reset */ noreset, /* devtotty */ nodevtotty, /* poll */ nopoll, - /* mmap */ nommap, + /* mmap */ isavga_mmap, /* strategy */ nostrategy, - /* name */ DRIVER_NAME, + /* name */ VGA_DRIVER_NAME, /* parms */ noparms, /* maj */ -1, /* dump */ nodump, @@ -127,56 +117,59 @@ static struct cdevsw vga_cdevsw = { static int isavga_probe(device_t dev) { - isavga_softc_t *sc; + video_adapter_t adp; + device_t bus; + int error; /* No pnp support */ if (isa_get_vendorid(dev)) return (ENXIO); device_set_desc(dev, "Generic ISA VGA"); - sc = device_get_softc(dev); - return isavga_probe_unit(device_get_unit(dev), sc, isa_get_flags(dev)); + error = vga_probe_unit(device_get_unit(dev), &adp, isa_get_flags(dev)); + if (error == 0) { + bus = device_get_parent(dev); + ISA_SET_RESOURCE(bus, dev, SYS_RES_IOPORT, 0, + adp.va_io_base, adp.va_io_size); + ISA_SET_RESOURCE(bus, dev, SYS_RES_MEMORY, 0, + adp.va_mem_base, adp.va_mem_size); +#if 0 + isa_set_port(dev, adp.va_io_base); + isa_set_portsize(dev, adp.va_io_size); + isa_set_maddr(dev, adp.va_mem_base); + isa_set_msize(dev, adp.va_mem_size); +#endif + } + return error; } static int isavga_attach(device_t dev) { - isavga_softc_t *sc; + vga_softc_t *sc; + struct resource *port; + struct resource *mem; + int unit; + int rid; + int error; + unit = device_get_unit(dev); sc = device_get_softc(dev); - return isavga_attach_unit(device_get_unit(dev), sc, isa_get_flags(dev)); -} - -static int -isavga_probe_unit(int unit, isavga_softc_t *sc, int flags) -{ - video_switch_t *sw; - - bzero(sc, sizeof(*sc)); - sw = vid_get_switch(DRIVER_NAME); - if (sw == NULL) - return 0; - return (*sw->probe)(unit, &sc->adp, NULL, flags); -} - -static int -isavga_attach_unit(int unit, isavga_softc_t *sc, int flags) -{ - video_switch_t *sw; - int error; - sw = vid_get_switch(DRIVER_NAME); - if (sw == NULL) - return ENXIO; + rid = 0; + port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, + 0, ~0, 0, RF_ACTIVE | RF_SHAREABLE); + rid = 0; + mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, + 0, ~0, 0, RF_ACTIVE | RF_SHAREABLE); - error = (*sw->init)(unit, sc->adp, flags); + error = vga_attach_unit(unit, sc, isa_get_flags(dev)); if (error) - return ENXIO; + return error; #ifdef FB_INSTALL_CDEV /* attach a virtual frame buffer device */ - error = fb_attach(makedev(0, ISAVGA_MKMINOR(unit)), scp->adp, - &vga_cdevsw); + error = fb_attach(makedev(0, VGA_MKMINOR(unit)), sc->adp, &isavga_cdevsw); if (error) return error; #endif /* FB_INSTALL_CDEV */ @@ -184,2010 +177,52 @@ isavga_attach_unit(int unit, isavga_softc_t *sc, int flags) if (bootverbose) (*vidsw[sc->adp->va_index]->diag)(sc->adp, bootverbose); - return 0; -} - -/* LOW-LEVEL */ - -#include <machine/clock.h> -#include <machine/pc/vesa.h> - -#define probe_done(adp) ((adp)->va_flags & V_ADP_PROBED) -#define init_done(adp) ((adp)->va_flags & V_ADP_INITIALIZED) -#define config_done(adp) ((adp)->va_flags & V_ADP_REGISTERED) - -/* for compatibility with old kernel options */ -#ifdef SC_ALT_SEQACCESS -#undef SC_ALT_SEQACCESS -#undef VGA_ALT_SEQACCESS -#define VGA_ALT_SEQACCESS 1 -#endif - -#ifdef SLOW_VGA -#undef SLOW_VGA -#undef VGA_SLOW_IOACCESS -#define VGA_SLOW_IOACCESS 1 -#endif - -/* architecture dependent option */ -#ifdef __alpha__ -#define VGA_NO_BIOS 1 -#endif - -/* this should really be in `rtc.h' */ -#define RTC_EQUIPMENT 0x14 - -/* various sizes */ -#define V_MODE_MAP_SIZE (M_VGA_CG320 + 1) -#define V_MODE_PARAM_SIZE 64 - -/* video adapter state buffer */ -struct adp_state { - int sig; -#define V_STATE_SIG 0x736f6962 - u_char regs[V_MODE_PARAM_SIZE]; -}; -typedef struct adp_state adp_state_t; - -/* video adapter information */ -#define DCC_MONO 0 -#define DCC_CGA40 1 -#define DCC_CGA80 2 -#define DCC_EGAMONO 3 -#define DCC_EGA40 4 -#define DCC_EGA80 5 - -/* - * NOTE: `va_window' should have a virtual address, but is initialized - * with a physical address in the following table, as verify_adapter() - * will perform address conversion at run-time. - */ -static video_adapter_t adapter_init_value[] = { - /* DCC_MONO */ - { 0, KD_MONO, "mda", 0, 0, 0, IO_MDA, IO_MDASIZE, MONO_CRTC, - MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE, - 0, 0, 0, 7, 0, }, - /* DCC_CGA40 */ - { 0, KD_CGA, "cga", 0, 0, V_ADP_COLOR, IO_CGA, IO_CGASIZE, COLOR_CRTC, - CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, - 0, 0, 0, 3, 0, }, - /* DCC_CGA80 */ - { 0, KD_CGA, "cga", 0, 0, V_ADP_COLOR, IO_CGA, IO_CGASIZE, COLOR_CRTC, - CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, - 0, 0, 0, 3, 0, }, - /* DCC_EGAMONO */ - { 0, KD_EGA, "ega", 0, 0, 0, IO_MDA, 48, MONO_CRTC, - EGA_BUF_BASE, EGA_BUF_SIZE, MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE, - 0, 0, 0, 7, 0, }, - /* DCC_EGA40 */ - { 0, KD_EGA, "ega", 0, 0, V_ADP_COLOR, IO_MDA, 48, COLOR_CRTC, - EGA_BUF_BASE, EGA_BUF_SIZE, CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, - 0, 0, 0, 3, 0, }, - /* DCC_EGA80 */ - { 0, KD_EGA, "ega", 0, 0, V_ADP_COLOR, IO_MDA, 48, COLOR_CRTC, - EGA_BUF_BASE, EGA_BUF_SIZE, CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, - 0, 0, 0, 3, 0, }, -}; - -static video_adapter_t biosadapter[2]; -static int biosadapters = 0; - -/* video driver declarations */ -static int vga_configure(int flags); - int (*vga_sub_configure)(int flags); -static int vga_nop(void); -static vi_probe_t vga_probe; -static vi_init_t vga_init; -static vi_get_info_t vga_get_info; -static vi_query_mode_t vga_query_mode; -static vi_set_mode_t vga_set_mode; -static vi_save_font_t vga_save_font; -static vi_load_font_t vga_load_font; -static vi_show_font_t vga_show_font; -static vi_save_palette_t vga_save_palette; -static vi_load_palette_t vga_load_palette; -static vi_set_border_t vga_set_border; -static vi_save_state_t vga_save_state; -static vi_load_state_t vga_load_state; -static vi_set_win_org_t vga_set_origin; -static vi_read_hw_cursor_t vga_read_hw_cursor; -static vi_set_hw_cursor_t vga_set_hw_cursor; -static vi_set_hw_cursor_shape_t vga_set_hw_cursor_shape; -static vi_mmap_t vga_mmap; -static vi_diag_t vga_diag; - -static video_switch_t vgavidsw = { - vga_probe, - vga_init, - vga_get_info, - vga_query_mode, - vga_set_mode, - vga_save_font, - vga_load_font, - vga_show_font, - vga_save_palette, - vga_load_palette, - vga_set_border, - vga_save_state, - vga_load_state, - vga_set_origin, - vga_read_hw_cursor, - vga_set_hw_cursor, - vga_set_hw_cursor_shape, - (vi_blank_display_t *)vga_nop, - vga_mmap, - vga_diag, -}; - -VIDEO_DRIVER(mda, vgavidsw, NULL); -VIDEO_DRIVER(cga, vgavidsw, NULL); -VIDEO_DRIVER(ega, vgavidsw, NULL); -VIDEO_DRIVER(vga, vgavidsw, vga_configure); - -/* VGA BIOS standard video modes */ -#define EOT (-1) -#define NA (-2) - -static video_info_t bios_vmode[] = { - /* CGA */ - { M_B40x25, V_INFO_COLOR, 40, 25, 8, 8, 2, 1, - CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0 }, - { M_C40x25, V_INFO_COLOR, 40, 25, 8, 8, 4, 1, - CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0 }, - { M_B80x25, V_INFO_COLOR, 80, 25, 8, 8, 2, 1, - CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0 }, - { M_C80x25, V_INFO_COLOR, 80, 25, 8, 8, 4, 1, - CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0 }, - /* EGA */ - { M_ENH_B40x25, V_INFO_COLOR, 40, 25, 8, 14, 2, 1, - CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0 }, - { M_ENH_C40x25, V_INFO_COLOR, 40, 25, 8, 14, 4, 1, - CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0 }, - { M_ENH_B80x25, V_INFO_COLOR, 80, 25, 8, 14, 2, 1, - CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0 }, - { M_ENH_C80x25, V_INFO_COLOR, 80, 25, 8, 14, 4, 1, - CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0 }, - /* VGA */ - { M_VGA_C40x25, V_INFO_COLOR, 40, 25, 8, 16, 4, 1, - CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0 }, - { M_VGA_M80x25, 0, 80, 25, 8, 16, 2, 1, - MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE, 0, 0 }, - { M_VGA_C80x25, V_INFO_COLOR, 80, 25, 8, 16, 4, 1, - CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0 }, - /* MDA */ - { M_EGAMONO80x25, 0, 80, 25, 8, 14, 2, 1, - MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE, 0, 0 }, - /* EGA */ - { M_ENH_B80x43, V_INFO_COLOR, 80, 43, 8, 8, 2, 1, - CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0 }, - { M_ENH_C80x43, V_INFO_COLOR, 80, 43, 8, 8, 4, 1, - CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0 }, - /* VGA */ - { M_VGA_M80x30, 0, 80, 30, 8, 16, 2, 1, - MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE, 0, 0 }, - { M_VGA_C80x30, V_INFO_COLOR, 80, 30, 8, 16, 4, 1, - CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0 }, - { M_VGA_M80x50, 0, 80, 50, 8, 8, 2, 1, - MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE, 0, 0 }, - { M_VGA_C80x50, V_INFO_COLOR, 80, 50, 8, 8, 4, 1, - CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0 }, - { M_VGA_M80x60, 0, 80, 60, 8, 8, 2, 1, - MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE, 0, 0 }, - { M_VGA_C80x60, V_INFO_COLOR, 80, 60, 8, 8, 4, 1, - CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0 }, -#ifndef VGA_NO_MODE_CHANGE - /* CGA */ - { M_BG320, V_INFO_COLOR | V_INFO_GRAPHICS, 320, 200, 8, 8, 2, 1, - CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0 }, - { M_CG320, V_INFO_COLOR | V_INFO_GRAPHICS, 320, 200, 8, 8, 2, 1, - CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0 }, - { M_BG640, V_INFO_COLOR | V_INFO_GRAPHICS, 640, 200, 8, 8, 1, 1, - CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0 }, - /* EGA */ - { M_CG320_D, V_INFO_COLOR | V_INFO_GRAPHICS, 320, 200, 8, 8, 4, 4, - GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0 }, - { M_CG640_E, V_INFO_COLOR | V_INFO_GRAPHICS, 640, 200, 8, 8, 4, 4, - GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0 }, - { M_EGAMONOAPA, V_INFO_GRAPHICS, 640, 350, 8, 14, 4, 4, - GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, 64*1024, 0, 0 }, - { M_ENHMONOAPA2,V_INFO_GRAPHICS, 640, 350, 8, 14, 4, 4, - GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0 }, - { M_CG640x350, V_INFO_COLOR | V_INFO_GRAPHICS, 640, 350, 8, 14, 2, 2, - GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0 }, - { M_ENH_CG640, V_INFO_COLOR | V_INFO_GRAPHICS, 640, 350, 8, 14, 4, 4, - GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0 }, - /* VGA */ - { M_BG640x480, V_INFO_COLOR | V_INFO_GRAPHICS, 640, 480, 8, 16, 4, 4, - GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0 }, - { M_CG640x480, V_INFO_COLOR | V_INFO_GRAPHICS, 640, 480, 8, 16, 4, 4, - GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0 }, - { M_VGA_CG320, V_INFO_COLOR | V_INFO_GRAPHICS, 320, 200, 8, 8, 8, 1, - GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0 }, - { M_VGA_MODEX, V_INFO_COLOR | V_INFO_GRAPHICS, 320, 240, 8, 8, 8, 1, - GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0 }, -#endif /* VGA_NO_MODE_CHANGE */ - - { EOT }, -}; - -static int init_done = FALSE; -#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE) -static u_char *video_mode_ptr = NULL; /* EGA/VGA */ -static u_char *video_mode_ptr2 = NULL; /* CGA/MDA */ -#endif -static u_char *mode_map[V_MODE_MAP_SIZE]; -static adp_state_t adpstate; -static adp_state_t adpstate2; -static int rows_offset = 1; - -/* local macros and functions */ -#define BIOS_SADDRTOLADDR(p) ((((p) & 0xffff0000) >> 12) + ((p) & 0x0000ffff)) - -#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE) -static void map_mode_table(u_char *map[], u_char *table, int max); -#endif -static void clear_mode_map(video_adapter_t *adp, u_char *map[], int max, - int color); -#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE) -static int map_mode_num(int mode); -#endif -static int map_gen_mode_num(int type, int color, int mode); -static int map_bios_mode_num(int type, int color, int bios_mode); -static u_char *get_mode_param(int mode); -#ifndef VGA_NO_BIOS -static void fill_adapter_param(int code, video_adapter_t *adp); -#endif -static int verify_adapter(video_adapter_t *adp); -static void update_adapter_info(video_adapter_t *adp, video_info_t *info); -#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE) -#define COMP_IDENTICAL 0 -#define COMP_SIMILAR 1 -#define COMP_DIFFERENT 2 -static int comp_adpregs(u_char *buf1, u_char *buf2); -#endif -static int probe_adapters(void); - -#ifndef VGA_NO_FONT_LOADING -#define PARAM_BUFSIZE 6 -static void set_font_mode(video_adapter_t *adp, u_char *buf); -static void set_normal_mode(video_adapter_t *adp, u_char *buf); +#if experimental + device_add_child(dev, "fb", -1, NULL); + bus_generic_attach(dev); #endif -static void dump_buffer(u_char *buf, size_t len); - -#define ISMAPPED(pa, width) \ - (((pa) <= (u_long)0x1000 - (width)) \ - || ((pa) >= ISA_HOLE_START && (pa) <= 0x100000 - (width))) - -#define prologue(adp, flag, err) \ - if (!init_done || !((adp)->va_flags & (flag))) \ - return (err) - -/* a backdoor for the console driver */ -static int -vga_configure(int flags) -{ - int i; - - probe_adapters(); - for (i = 0; i < biosadapters; ++i) { - if (!probe_done(&biosadapter[i])) - continue; - biosadapter[i].va_flags |= V_ADP_INITIALIZED; - if (!config_done(&biosadapter[i])) { - if (vid_register(&biosadapter[i]) < 0) - continue; - biosadapter[i].va_flags |= V_ADP_REGISTERED; - } - } - if (vga_sub_configure != NULL) - (*vga_sub_configure)(flags); - - return biosadapters; -} - -/* local subroutines */ - -#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE) -/* construct the mode parameter map */ -static void -map_mode_table(u_char *map[], u_char *table, int max) -{ - int i; - - for(i = 0; i < max; ++i) - map[i] = table + i*V_MODE_PARAM_SIZE; - for(; i < V_MODE_MAP_SIZE; ++i) - map[i] = NULL; -} -#endif /* !VGA_NO_BIOS && !VGA_NO_MODE_CHANGE */ - -static void -clear_mode_map(video_adapter_t *adp, u_char *map[], int max, int color) -{ - video_info_t info; - int i; - - /* - * NOTE: we don't touch `bios_vmode[]' because it is shared - * by all adapters. - */ - for(i = 0; i < max; ++i) { - if (vga_get_info(adp, i, &info)) - continue; - if ((info.vi_flags & V_INFO_COLOR) != color) - map[i] = NULL; - } -} - -#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE) -/* map the non-standard video mode to a known mode number */ -static int -map_mode_num(int mode) -{ - static struct { - int from; - int to; - } mode_map[] = { - { M_ENH_B80x43, M_ENH_B80x25 }, - { M_ENH_C80x43, M_ENH_C80x25 }, - { M_VGA_M80x30, M_VGA_M80x25 }, - { M_VGA_C80x30, M_VGA_C80x25 }, - { M_VGA_M80x50, M_VGA_M80x25 }, - { M_VGA_C80x50, M_VGA_C80x25 }, - { M_VGA_M80x60, M_VGA_M80x25 }, - { M_VGA_C80x60, M_VGA_C80x25 }, - { M_VGA_MODEX, M_VGA_CG320 }, - }; - int i; - - for (i = 0; i < sizeof(mode_map)/sizeof(mode_map[0]); ++i) { - if (mode_map[i].from == mode) - return mode_map[i].to; - } - return mode; -} -#endif /* !VGA_NO_BIOS && !VGA_NO_MODE_CHANGE */ - -/* map a generic video mode to a known mode number */ -static int -map_gen_mode_num(int type, int color, int mode) -{ - static struct { - int from; - int to_color; - int to_mono; - } mode_map[] = { - { M_TEXT_80x30, M_VGA_C80x30, M_VGA_M80x30, }, - { M_TEXT_80x43, M_ENH_C80x43, M_ENH_B80x43, }, - { M_TEXT_80x50, M_VGA_C80x50, M_VGA_M80x50, }, - { M_TEXT_80x60, M_VGA_C80x60, M_VGA_M80x60, }, - }; - int i; - - if (mode == M_TEXT_80x25) { - switch (type) { - - case KD_VGA: - if (color) - return M_VGA_C80x25; - else - return M_VGA_M80x25; - break; - - case KD_EGA: - if (color) - return M_ENH_C80x25; - else - return M_EGAMONO80x25; - break; - - case KD_CGA: - return M_C80x25; - - case KD_MONO: - case KD_HERCULES: - return M_EGAMONO80x25; /* XXX: this name is confusing */ - - default: - return -1; - } - } - - for (i = 0; i < sizeof(mode_map)/sizeof(mode_map[0]); ++i) { - if (mode_map[i].from == mode) - return ((color) ? mode_map[i].to_color : mode_map[i].to_mono); - } - return mode; -} - -/* turn the BIOS video number into our video mode number */ -static int -map_bios_mode_num(int type, int color, int bios_mode) -{ - static int cga_modes[7] = { - M_B40x25, M_C40x25, /* 0, 1 */ - M_B80x25, M_C80x25, /* 2, 3 */ - M_BG320, M_CG320, - M_BG640, - }; - static int ega_modes[17] = { - M_ENH_B40x25, M_ENH_C40x25, /* 0, 1 */ - M_ENH_B80x25, M_ENH_C80x25, /* 2, 3 */ - M_BG320, M_CG320, - M_BG640, - M_EGAMONO80x25, /* 7 */ - 8, 9, 10, 11, 12, - M_CG320_D, - M_CG640_E, - M_ENHMONOAPA2, /* XXX: video momery > 64K */ - M_ENH_CG640, /* XXX: video momery > 64K */ - }; - static int vga_modes[20] = { - M_VGA_C40x25, M_VGA_C40x25, /* 0, 1 */ - M_VGA_C80x25, M_VGA_C80x25, /* 2, 3 */ - M_BG320, M_CG320, - M_BG640, - M_VGA_M80x25, /* 7 */ - 8, 9, 10, 11, 12, - M_CG320_D, - M_CG640_E, - M_ENHMONOAPA2, - M_ENH_CG640, - M_BG640x480, M_CG640x480, - M_VGA_CG320, - }; - - switch (type) { - - case KD_VGA: - if (bios_mode < sizeof(vga_modes)/sizeof(vga_modes[0])) - return vga_modes[bios_mode]; - else if (color) - return M_VGA_C80x25; - else - return M_VGA_M80x25; - break; - - case KD_EGA: - if (bios_mode < sizeof(ega_modes)/sizeof(ega_modes[0])) - return ega_modes[bios_mode]; - else if (color) - return M_ENH_C80x25; - else - return M_EGAMONO80x25; - break; - - case KD_CGA: - if (bios_mode < sizeof(cga_modes)/sizeof(cga_modes[0])) - return cga_modes[bios_mode]; - else - return M_C80x25; - break; - - case KD_MONO: - case KD_HERCULES: - return M_EGAMONO80x25; /* XXX: this name is confusing */ - - default: - break; - } - return -1; -} - -/* look up a parameter table entry */ -static u_char -*get_mode_param(int mode) -{ -#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE) - if (mode >= V_MODE_MAP_SIZE) - mode = map_mode_num(mode); -#endif - if ((mode >= 0) && (mode < V_MODE_MAP_SIZE)) - return mode_map[mode]; - else - return NULL; -} - -#ifndef VGA_NO_BIOS -static void -fill_adapter_param(int code, video_adapter_t *adp) -{ - static struct { - int primary; - int secondary; - } dcc[] = { - { DCC_MONO, DCC_EGA40 /* CGA monitor */ }, - { DCC_MONO, DCC_EGA80 /* CGA monitor */ }, - { DCC_MONO, DCC_EGA80 /* CGA emulation */ }, - { DCC_MONO, DCC_EGA80 }, - { DCC_CGA40, DCC_EGAMONO }, - { DCC_CGA80, DCC_EGAMONO }, - { DCC_EGA40 /* CGA monitor */, DCC_MONO}, - { DCC_EGA80 /* CGA monitor */, DCC_MONO}, - { DCC_EGA80 /* CGA emulation */,DCC_MONO }, - { DCC_EGA80, DCC_MONO }, - { DCC_EGAMONO, DCC_CGA40 }, - { DCC_EGAMONO, DCC_CGA40 }, - }; - - if ((code < 0) || (code >= sizeof(dcc)/sizeof(dcc[0]))) { - adp[V_ADP_PRIMARY] = adapter_init_value[DCC_MONO]; - adp[V_ADP_SECONDARY] = adapter_init_value[DCC_CGA80]; - } else { - adp[V_ADP_PRIMARY] = adapter_init_value[dcc[code].primary]; - adp[V_ADP_SECONDARY] = adapter_init_value[dcc[code].secondary]; - } -} -#endif /* VGA_NO_BIOS */ - -static int -verify_adapter(video_adapter_t *adp) -{ - vm_offset_t buf; - u_int16_t v; -#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE) - u_int32_t p; -#endif - - buf = BIOS_PADDRTOVADDR(adp->va_window); - v = readw(buf); - writew(buf, 0xA55A); - if (readw(buf) != 0xA55A) - return 1; - writew(buf, v); - - switch (adp->va_type) { - - case KD_EGA: - outb(adp->va_crtc_addr, 7); - if (inb(adp->va_crtc_addr) == 7) { - adp->va_type = KD_VGA; - adp->va_name = "vga"; - adp->va_flags |= V_ADP_STATESAVE | V_ADP_PALETTE; - } - adp->va_flags |= V_ADP_STATELOAD | V_ADP_BORDER; - /* the color adapter may be in the 40x25 mode... XXX */ - -#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE) - /* get the BIOS video mode pointer */ - p = *(u_int32_t *)BIOS_PADDRTOVADDR(0x4a8); - p = BIOS_SADDRTOLADDR(p); - if (ISMAPPED(p, sizeof(u_int32_t))) { - p = *(u_int32_t *)BIOS_PADDRTOVADDR(p); - p = BIOS_SADDRTOLADDR(p); - if (ISMAPPED(p, V_MODE_PARAM_SIZE)) - video_mode_ptr = (u_char *)BIOS_PADDRTOVADDR(p); - } -#endif - break; - - case KD_CGA: - adp->va_flags |= V_ADP_COLOR | V_ADP_BORDER; - /* may be in the 40x25 mode... XXX */ -#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE) - /* get the BIOS video mode pointer */ - p = *(u_int32_t *)BIOS_PADDRTOVADDR(0x1d*4); - p = BIOS_SADDRTOLADDR(p); - video_mode_ptr2 = (u_char *)BIOS_PADDRTOVADDR(p); -#endif - break; - - case KD_MONO: -#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE) - /* get the BIOS video mode pointer */ - p = *(u_int32_t *)BIOS_PADDRTOVADDR(0x1d*4); - p = BIOS_SADDRTOLADDR(p); - video_mode_ptr2 = (u_char *)BIOS_PADDRTOVADDR(p); -#endif - break; - } - - return 0; -} - -static void -update_adapter_info(video_adapter_t *adp, video_info_t *info) -{ - adp->va_flags &= ~V_ADP_COLOR; - adp->va_flags |= - (info->vi_flags & V_INFO_COLOR) ? V_ADP_COLOR : 0; - adp->va_crtc_addr = - (adp->va_flags & V_ADP_COLOR) ? COLOR_CRTC : MONO_CRTC; - adp->va_window = BIOS_PADDRTOVADDR(info->vi_window); - adp->va_window_size = info->vi_window_size; - adp->va_window_gran = info->vi_window_gran; - if (info->vi_buffer_size == 0) { - adp->va_buffer = 0; - adp->va_buffer_size = 0; - } else { - adp->va_buffer = BIOS_PADDRTOVADDR(info->vi_buffer); - adp->va_buffer_size = info->vi_buffer_size; - } - if (info->vi_flags & V_INFO_GRAPHICS) { - switch (info->vi_depth/info->vi_planes) { - case 1: - adp->va_line_width = info->vi_width/8; - break; - case 2: - adp->va_line_width = info->vi_width/4; - break; - case 4: - adp->va_line_width = info->vi_width/2; - break; - case 8: - default: /* shouldn't happen */ - adp->va_line_width = info->vi_width; - break; - } - } else { - adp->va_line_width = info->vi_width; - } - bcopy(info, &adp->va_info, sizeof(adp->va_info)); -} - -#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE) -/* compare two parameter table entries */ -static int -comp_adpregs(u_char *buf1, u_char *buf2) -{ - static struct { - u_char mask; - } params[V_MODE_PARAM_SIZE] = { - {0xff}, {0x00}, {0xff}, /* COLS, ROWS, POINTS */ - {0x00}, {0x00}, /* page length */ - {0xfe}, {0xff}, {0xff}, {0xff}, /* sequencer registers */ - {0xf3}, /* misc register */ - {0xff}, {0xff}, {0xff}, {0x7f}, {0xff}, /* CRTC */ - {0xff}, {0xff}, {0xff}, {0x7f}, {0xff}, - {0x00}, {0x00}, {0x00}, {0x00}, {0x00}, - {0x00}, {0xff}, {0x7f}, {0xff}, {0xff}, - {0x7f}, {0xff}, {0xff}, {0xef}, {0xff}, - {0xff}, {0xff}, {0xff}, {0xff}, {0xff}, /* attribute controller regs */ - {0xff}, {0xff}, {0xff}, {0xff}, {0xff}, - {0xff}, {0xff}, {0xff}, {0xff}, {0xff}, - {0xff}, {0xff}, {0xff}, {0xff}, {0xf0}, - {0xff}, {0xff}, {0xff}, {0xff}, {0xff}, /* GDC register */ - {0xff}, {0xff}, {0xff}, {0xff}, - }; - int identical = TRUE; - int i; - - if ((buf1 == NULL) || (buf2 == NULL)) - return COMP_DIFFERENT; - - for (i = 0; i < sizeof(params)/sizeof(params[0]); ++i) { - if (params[i].mask == 0) /* don't care */ - continue; - if ((buf1[i] & params[i].mask) != (buf2[i] & params[i].mask)) - return COMP_DIFFERENT; - if (buf1[i] != buf2[i]) - identical = FALSE; - } - return (identical) ? COMP_IDENTICAL : COMP_SIMILAR; -} -#endif /* !VGA_NO_BIOS && !VGA_NO_MODE_CHANGE */ - -/* probe video adapters and return the number of detected adapters */ -static int -probe_adapters(void) -{ - video_adapter_t *adp; - video_info_t info; - int i; - - /* do this test only once */ - if (init_done) - return biosadapters; - init_done = TRUE; - - /* - * Locate display adapters. - * The AT architecture supports upto two adapters. `syscons' allows - * the following combinations of adapters: - * 1) MDA + CGA - * 2) MDA + EGA/VGA color - * 3) CGA + EGA/VGA mono - * Note that `syscons' doesn't bother with MCGA as it is only - * avaiable for low end PS/2 models which has 80286 or earlier CPUs, - * thus, they are not running FreeBSD! - * When there are two adapaters in the system, one becomes `primary' - * and the other `secondary'. The EGA adapter has a set of DIP - * switches on board for this information and the EGA BIOS copies - * it in the BIOS data area BIOSDATA_VIDEOSWITCH (40:88). - * The VGA BIOS has more sophisticated mechanism and has this - * information in BIOSDATA_DCCINDEX (40:8a), but it also maintains - * compatibility with the EGA BIOS by updating BIOSDATA_VIDEOSWITCH. - */ - - /* - * Check rtc and BIOS data area. - * XXX: we don't use BIOSDATA_EQUIPMENT, since it is not a dead - * copy of RTC_EQUIPMENT. Bits 4 and 5 of ETC_EQUIPMENT are - * zeros for EGA and VGA. However, the EGA/VGA BIOS sets - * these bits in BIOSDATA_EQUIPMENT according to the monitor - * type detected. - */ -#ifndef VGA_NO_BIOS - switch ((rtcin(RTC_EQUIPMENT) >> 4) & 3) { /* bit 4 and 5 */ - case 0: - /* EGA/VGA */ - fill_adapter_param(readb(BIOS_PADDRTOVADDR(0x488)) & 0x0f, - biosadapter); - break; - case 1: - /* CGA 40x25 */ - /* FIXME: switch to the 80x25 mode? XXX */ - biosadapter[V_ADP_PRIMARY] = adapter_init_value[DCC_CGA40]; - biosadapter[V_ADP_SECONDARY] = adapter_init_value[DCC_MONO]; - break; - case 2: - /* CGA 80x25 */ - biosadapter[V_ADP_PRIMARY] = adapter_init_value[DCC_CGA80]; - biosadapter[V_ADP_SECONDARY] = adapter_init_value[DCC_MONO]; - break; - case 3: - /* MDA */ - biosadapter[V_ADP_PRIMARY] = adapter_init_value[DCC_MONO]; - biosadapter[V_ADP_SECONDARY] = adapter_init_value[DCC_CGA80]; - break; - } -#else - /* assume EGA/VGA? XXX */ - biosadapter[V_ADP_PRIMARY] = adapter_init_value[DCC_EGA80]; - biosadapter[V_ADP_SECONDARY] = adapter_init_value[DCC_MONO]; -#endif /* VGA_NO_BIOS */ - - biosadapters = 0; - if (verify_adapter(&biosadapter[V_ADP_SECONDARY]) == 0) { - ++biosadapters; - biosadapter[V_ADP_SECONDARY].va_flags |= V_ADP_PROBED; - biosadapter[V_ADP_SECONDARY].va_mode = - biosadapter[V_ADP_SECONDARY].va_initial_mode = - map_bios_mode_num(biosadapter[V_ADP_SECONDARY].va_type, - biosadapter[V_ADP_SECONDARY].va_flags - & V_ADP_COLOR, - biosadapter[V_ADP_SECONDARY].va_initial_bios_mode); - } else { - biosadapter[V_ADP_SECONDARY].va_type = -1; - } - if (verify_adapter(&biosadapter[V_ADP_PRIMARY]) == 0) { - ++biosadapters; - biosadapter[V_ADP_PRIMARY].va_flags |= V_ADP_PROBED; -#ifndef VGA_NO_BIOS - biosadapter[V_ADP_PRIMARY].va_initial_bios_mode = - readb(BIOS_PADDRTOVADDR(0x449)); -#else - biosadapter[V_ADP_PRIMARY].va_initial_bios_mode = 3; /* XXX */ -#endif - biosadapter[V_ADP_PRIMARY].va_mode = - biosadapter[V_ADP_PRIMARY].va_initial_mode = - map_bios_mode_num(biosadapter[V_ADP_PRIMARY].va_type, - biosadapter[V_ADP_PRIMARY].va_flags & V_ADP_COLOR, - biosadapter[V_ADP_PRIMARY].va_initial_bios_mode); - } else { - biosadapter[V_ADP_PRIMARY] = biosadapter[V_ADP_SECONDARY]; - biosadapter[V_ADP_SECONDARY].va_type = -1; - } - if (biosadapters == 0) - return biosadapters; - biosadapter[V_ADP_PRIMARY].va_unit = V_ADP_PRIMARY; - biosadapter[V_ADP_SECONDARY].va_unit = V_ADP_SECONDARY; - -#if 0 /* we don't need these... */ - fb_init_struct(&biosadapter[V_ADP_PRIMARY], ...); - fb_init_struct(&biosadapter[V_ADP_SECONDARY], ...); -#endif - -#if 0 - /* - * We cannot have two video adapter of the same type; there must be - * only one of color or mono adapter, or one each of them. - */ - if (biosadapters > 1) { - if (!((biosadapter[0].va_flags ^ biosadapter[1].va_flags) - & V_ADP_COLOR)) - /* we have two mono or color adapters!! */ - return (biosadapters = 0); - } -#endif - - /* - * Ensure a zero start address. This is mainly to recover after - * switching from pcvt using userconfig(). The registers are w/o - * for old hardware so it's too hard to relocate the active screen - * memory. - * This must be done before vga_save_state() for VGA. - */ - outb(biosadapter[V_ADP_PRIMARY].va_crtc_addr, 12); - outb(biosadapter[V_ADP_PRIMARY].va_crtc_addr + 1, 0); - outb(biosadapter[V_ADP_PRIMARY].va_crtc_addr, 13); - outb(biosadapter[V_ADP_PRIMARY].va_crtc_addr + 1, 0); - - /* the video mode parameter table in EGA/VGA BIOS */ - /* NOTE: there can be only one EGA/VGA, wheather color or mono, - * recognized by the video BIOS. - */ - if ((biosadapter[V_ADP_PRIMARY].va_type == KD_EGA) || - (biosadapter[V_ADP_PRIMARY].va_type == KD_VGA)) { - adp = &biosadapter[V_ADP_PRIMARY]; - } else if ((biosadapter[V_ADP_SECONDARY].va_type == KD_EGA) || - (biosadapter[V_ADP_SECONDARY].va_type == KD_VGA)) { - adp = &biosadapter[V_ADP_SECONDARY]; - } else { - adp = NULL; - } - bzero(mode_map, sizeof(mode_map)); - if (adp != NULL) { - if (adp->va_type == KD_VGA) { - vga_save_state(adp, &adpstate, sizeof(adpstate)); -#if defined(VGA_NO_BIOS) || defined(VGA_NO_MODE_CHANGE) - mode_map[adp->va_initial_mode] = adpstate.regs; - rows_offset = 1; -#else /* VGA_NO_BIOS || VGA_NO_MODE_CHANGE */ - if (video_mode_ptr == NULL) { - mode_map[adp->va_initial_mode] = adpstate.regs; - rows_offset = 1; - } else { - /* discard the table if we are not familiar with it... */ - u_char *mp; - map_mode_table(mode_map, video_mode_ptr, M_VGA_CG320 + 1); - mp = get_mode_param(adp->va_initial_mode); - if (mp != NULL) - bcopy(mp, adpstate2.regs, sizeof(adpstate2.regs)); - switch (comp_adpregs(adpstate.regs, mp)) { - case COMP_IDENTICAL: - /* - * OK, this parameter table looks reasonably familiar - * to us... - */ - /* - * This is a kludge for Toshiba DynaBook SS433 - * whose BIOS video mode table entry has the actual # - * of rows at the offset 1; BIOSes from other - * manufacturers store the # of rows - 1 there. XXX - */ - rows_offset = adpstate.regs[1] + 1 - mp[1]; - break; - - case COMP_SIMILAR: - /* - * Not exactly the same, but similar enough to be - * trusted. However, use the saved register values - * for the initial mode and other modes which are - * based on the initial mode. - */ - mode_map[adp->va_initial_mode] = adpstate.regs; - rows_offset = adpstate.regs[1] + 1 - mp[1]; - adpstate.regs[1] -= rows_offset - 1; - break; - - case COMP_DIFFERENT: - default: - /* - * Don't use the paramter table in BIOS. It doesn't - * look familiar to us. Video mode switching is allowed - * only if the new mode is the same as or based on - * the initial mode. - */ - video_mode_ptr = NULL; - bzero(mode_map, sizeof(mode_map)); - mode_map[adp->va_initial_mode] = adpstate.regs; - rows_offset = 1; - break; - } - } -#endif /* VGA_NO_BIOS || VGA_NO_MODE_CHANGE */ - -#ifndef VGA_NO_MODE_CHANGE - adp->va_flags |= V_ADP_MODECHANGE; -#endif -#ifndef VGA_NO_FONT_LOADING - adp->va_flags |= V_ADP_FONT; -#endif - } else if (adp->va_type == KD_EGA) { -#if defined(VGA_NO_BIOS) || defined(VGA_NO_MODE_CHANGE) - rows_offset = 1; -#else /* VGA_NO_BIOS || VGA_NO_MODE_CHANGE */ - if (video_mode_ptr == NULL) { - rows_offset = 1; - } else { - u_char *mp; - map_mode_table(mode_map, video_mode_ptr, M_ENH_C80x25 + 1); - /* XXX how can one validate the EGA table... */ - mp = get_mode_param(adp->va_initial_mode); - if (mp != NULL) { - adp->va_flags |= V_ADP_MODECHANGE; -#ifndef VGA_NO_FONT_LOADING - adp->va_flags |= V_ADP_FONT; -#endif - rows_offset = 1; - } else { - /* - * This is serious. We will not be able to switch video - * modes at all... - */ - video_mode_ptr = NULL; - bzero(mode_map, sizeof(mode_map)); - rows_offset = 1; - } - } -#endif /* VGA_NO_BIOS || VGA_NO_MODE_CHANGE */ - } - } - - /* remove conflicting modes if we have more than one adapter */ - if (biosadapters > 1) { - for (i = 0; i < biosadapters; ++i) { - if (!(biosadapter[i].va_flags & V_ADP_MODECHANGE)) - continue; - clear_mode_map(&biosadapter[i], mode_map, M_VGA_CG320 + 1, - (biosadapter[i].va_flags & V_ADP_COLOR) ? - V_INFO_COLOR : 0); - if ((biosadapter[i].va_type == KD_VGA) - || (biosadapter[i].va_type == KD_EGA)) { - biosadapter[i].va_io_base = - (biosadapter[i].va_flags & V_ADP_COLOR) ? - IO_VGA : IO_MDA; - biosadapter[i].va_io_size = 32; - } - } - } - - /* buffer address */ - vga_get_info(&biosadapter[V_ADP_PRIMARY], - biosadapter[V_ADP_PRIMARY].va_initial_mode, &info); - update_adapter_info(&biosadapter[V_ADP_PRIMARY], &info); - - if (biosadapters > 1) { - vga_get_info(&biosadapter[V_ADP_SECONDARY], - biosadapter[V_ADP_SECONDARY].va_initial_mode, &info); - update_adapter_info(&biosadapter[V_ADP_SECONDARY], &info); - } - - /* - * XXX: we should verify the following values for the primary adapter... - * crtc I/O port address: *(u_int16_t *)BIOS_PADDRTOVADDR(0x463); - * color/mono display: (*(u_int8_t *)BIOS_PADDRTOVADDR(0x487) & 0x02) - * ? 0 : V_ADP_COLOR; - * columns: *(u_int8_t *)BIOS_PADDRTOVADDR(0x44a); - * rows: *(u_int8_t *)BIOS_PADDRTOVADDR(0x484); - * font size: *(u_int8_t *)BIOS_PADDRTOVADDR(0x485); - * buffer size: *(u_int16_t *)BIOS_PADDRTOVADDR(0x44c); - */ - - return biosadapters; -} - -/* entry points */ - -static int -vga_nop(void) -{ - return 0; -} - -static int -vga_probe(int unit, video_adapter_t **adpp, void *arg, int flags) -{ - probe_adapters(); - if (unit >= biosadapters) - return ENXIO; - - *adpp = &biosadapter[unit]; - - return 0; -} - -static int -vga_init(int unit, video_adapter_t *adp, int flags) -{ - if ((unit >= biosadapters) || (adp == NULL) || !probe_done(adp)) - return ENXIO; - - if (!init_done(adp)) { - /* nothing to do really... */ - adp->va_flags |= V_ADP_INITIALIZED; - } - - if (!config_done(adp)) { - if (vid_register(adp) < 0) - return ENXIO; - adp->va_flags |= V_ADP_REGISTERED; - } - if (vga_sub_configure != NULL) - (*vga_sub_configure)(0); - - return 0; -} - -/* - * get_info(): - * Return the video_info structure of the requested video mode. - * - * all adapters - */ -static int -vga_get_info(video_adapter_t *adp, int mode, video_info_t *info) -{ - int i; - - if (!init_done) - return 1; - - mode = map_gen_mode_num(adp->va_type, adp->va_flags & V_ADP_COLOR, mode); -#ifndef VGA_NO_MODE_CHANGE - if (adp->va_flags & V_ADP_MODECHANGE) { - /* - * If the parameter table entry for this mode is not found, - * the mode is not supported... - */ - if (get_mode_param(mode) == NULL) - return 1; - } else -#endif /* VGA_NO_MODE_CHANGE */ - { - /* - * Even if we don't support video mode switching on this adapter, - * the information on the initial (thus current) video mode - * should be made available. - */ - if (mode != adp->va_initial_mode) - return 1; - } - - for (i = 0; bios_vmode[i].vi_mode != EOT; ++i) { - if (bios_vmode[i].vi_mode == NA) - continue; - if (mode == bios_vmode[i].vi_mode) { - *info = bios_vmode[i]; - return 0; - } - } - return 1; -} - -/* - * query_mode(): - * Find a video mode matching the requested parameters. - * Fields filled with 0 are considered "don't care" fields and - * match any modes. - * - * all adapters - */ -static int -vga_query_mode(video_adapter_t *adp, video_info_t *info) -{ - video_info_t buf; - int i; - - if (!init_done) - return -1; - - for (i = 0; bios_vmode[i].vi_mode != EOT; ++i) { - if (bios_vmode[i].vi_mode == NA) - continue; - - if ((info->vi_width != 0) - && (info->vi_width != bios_vmode[i].vi_width)) - continue; - if ((info->vi_height != 0) - && (info->vi_height != bios_vmode[i].vi_height)) - continue; - if ((info->vi_cwidth != 0) - && (info->vi_cwidth != bios_vmode[i].vi_cwidth)) - continue; - if ((info->vi_cheight != 0) - && (info->vi_cheight != bios_vmode[i].vi_cheight)) - continue; - if ((info->vi_depth != 0) - && (info->vi_depth != bios_vmode[i].vi_depth)) - continue; - if ((info->vi_planes != 0) - && (info->vi_planes != bios_vmode[i].vi_planes)) - continue; - /* XXX: should check pixel format, memory model */ - if ((info->vi_flags != 0) - && (info->vi_flags != bios_vmode[i].vi_flags)) - continue; - - /* verify if this mode is supported on this adapter */ - if (vga_get_info(adp, bios_vmode[i].vi_mode, &buf)) - continue; - return bios_vmode[i].vi_mode; - } - return -1; -} - -/* - * set_mode(): - * Change the video mode. - * - * EGA/VGA - */ -static int -vga_set_mode(video_adapter_t *adp, int mode) -{ -#ifndef VGA_NO_MODE_CHANGE - video_info_t info; - adp_state_t params; - - prologue(adp, V_ADP_MODECHANGE, 1); - - mode = map_gen_mode_num(adp->va_type, - adp->va_flags & V_ADP_COLOR, mode); - if (vga_get_info(adp, mode, &info)) - return 1; - params.sig = V_STATE_SIG; - bcopy(get_mode_param(mode), params.regs, sizeof(params.regs)); - - switch (mode) { - case M_VGA_C80x60: case M_VGA_M80x60: - params.regs[2] = 0x08; - params.regs[19] = 0x47; - goto special_480l; - - case M_VGA_C80x30: case M_VGA_M80x30: - params.regs[19] = 0x4f; -special_480l: - params.regs[9] |= 0xc0; - params.regs[16] = 0x08; - params.regs[17] = 0x3e; - params.regs[26] = 0xea; - params.regs[28] = 0xdf; - params.regs[31] = 0xe7; - params.regs[32] = 0x04; - goto setup_mode; - - case M_ENH_C80x43: case M_ENH_B80x43: - params.regs[28] = 87; - goto special_80x50; - - case M_VGA_C80x50: case M_VGA_M80x50: -special_80x50: - params.regs[2] = 8; - params.regs[19] = 7; - goto setup_mode; - - case M_VGA_C40x25: case M_VGA_C80x25: - case M_VGA_M80x25: - case M_B40x25: case M_C40x25: - case M_B80x25: case M_C80x25: - case M_ENH_B40x25: case M_ENH_C40x25: - case M_ENH_B80x25: case M_ENH_C80x25: - case M_EGAMONO80x25: - -setup_mode: - vga_load_state(adp, ¶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 <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> #include <sys/linker.h> - -#include <machine/console.h> +#include <sys/fbio.h> #include <dev/fb/fbreg.h> #include <dev/fb/splashreg.h> diff --git a/sys/modules/splash/pcx/splash_pcx.c b/sys/modules/splash/pcx/splash_pcx.c index 3066bb3..5423295 100644 --- a/sys/modules/splash/pcx/splash_pcx.c +++ b/sys/modules/splash/pcx/splash_pcx.c @@ -27,15 +27,14 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id$ + * $Id: splash_pcx.c,v 1.1 1999/04/12 13:39:11 des Exp $ */ #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> #include <sys/linker.h> - -#include <machine/console.h> +#include <sys/fbio.h> #include <dev/fb/fbreg.h> #include <dev/fb/splashreg.h> diff --git a/sys/modules/syscons/blank/blank_saver.c b/sys/modules/syscons/blank/blank_saver.c index 89dd199..2979c0d 100644 --- a/sys/modules/syscons/blank/blank_saver.c +++ b/sys/modules/syscons/blank/blank_saver.c @@ -25,82 +25,35 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: blank_saver.c,v 1.14 1998/11/04 03:49:38 peter Exp $ + * $Id: blank_saver.c,v 1.15 1999/01/11 03:18:44 yokota Exp $ */ #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> #include <sys/module.h> +#include <sys/consio.h> +#include <sys/fbio.h> -#include <dev/fb/vgareg.h> - -#include <i386/isa/isa.h> - -#include <saver.h> +#include <dev/fb/fbreg.h> +#include <dev/fb/splashreg.h> +#include <dev/syscons/syscons.h> static int blank_saver(video_adapter_t *adp, int blank) { - u_char val; - if (blank) { - switch (adp->va_type) { - case KD_VGA: - outb(TSIDX, 0x01); val = inb(TSREG); - outb(TSIDX, 0x01); outb(TSREG, val | 0x20); - break; - case KD_EGA: - /* not yet done XXX */ - break; - case KD_CGA: - outb(adp->va_crtc_addr + 4, 0x25); - break; - case KD_MONO: - case KD_HERCULES: - outb(adp->va_crtc_addr + 4, 0x21); - break; - default: - break; - } - } - else { - switch (adp->va_type) { - case KD_VGA: - outb(TSIDX, 0x01); val = inb(TSREG); - outb(TSIDX, 0x01); outb(TSREG, val & 0xDF); - break; - case KD_EGA: - /* not yet done XXX */ - break; - case KD_CGA: - outb(adp->va_crtc_addr + 4, 0x2d); - break; - case KD_MONO: - case KD_HERCULES: - outb(adp->va_crtc_addr + 4, 0x29); - break; - default: - break; - } - } + (*vidsw[adp->va_index]->blank_display)(adp, + (blank) ? V_DISPLAY_BLANK + : V_DISPLAY_ON); return 0; } static int blank_init(video_adapter_t *adp) { - switch (adp->va_type) { - case KD_MONO: - case KD_HERCULES: - case KD_CGA: - case KD_VGA: - break; - case KD_EGA: - /* EGA is yet to be supported */ - default: - return ENODEV; - } - return 0; + if ((*vidsw[adp->va_index]->blank_display)(adp, V_DISPLAY_ON) == 0) + return 0; + return ENODEV; } static int diff --git a/sys/modules/syscons/daemon/daemon_saver.c b/sys/modules/syscons/daemon/daemon_saver.c index 423e6c7..ebedfaa 100644 --- a/sys/modules/syscons/daemon/daemon_saver.c +++ b/sys/modules/syscons/daemon/daemon_saver.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: daemon_saver.c,v 1.14 1999/01/17 14:25:08 yokota Exp $ + * $Id: daemon_saver.c,v 1.15 1999/02/05 12:40:15 des Exp $ */ #include <sys/param.h> @@ -34,21 +34,20 @@ #include <sys/malloc.h> #include <sys/kernel.h> #include <sys/sysctl.h> +#include <sys/consio.h> +#include <sys/fbio.h> -#include <machine/md_var.h> #include <machine/pc/display.h> -#include <saver.h> - -#define CONSOLE_VECT(x, y) \ - (window + (y)*cur_console->xsize + (x)) +#include <dev/fb/fbreg.h> +#include <dev/fb/splashreg.h> +#include <dev/syscons/syscons.h> #define DAEMON_MAX_WIDTH 32 #define DAEMON_MAX_HEIGHT 19 static char *message; static int messagelen; -static u_short *window; static int blanked; /* Who is the author of this ASCII pic? */ @@ -119,20 +118,23 @@ xflip_symbol(char symbol) } static void -clear_daemon(int xpos, int ypos, int dxdir, int xoff, int yoff, +clear_daemon(sc_softc_t *sc, int xpos, int ypos, int dxdir, int xoff, int yoff, int xlen, int ylen) { int y; if (xlen <= 0) return; - for (y = yoff; y < ylen; y++) - fillw(((FG_LIGHTGREY|BG_BLACK) << 8) | scr_map[0x20], - CONSOLE_VECT(xpos + xoff, ypos + y), xlen - xoff); + for (y = yoff; y < ylen; y++) { + sc_vtb_erase(&sc->cur_scp->scr, + (ypos + y)*sc->cur_scp->xsize + xpos + xoff, + xlen - xoff, + sc->scr_map[0x20], (FG_LIGHTGREY | BG_BLACK) << 8); + } } static void -draw_daemon(int xpos, int ypos, int dxdir, int xoff, int yoff, +draw_daemon(sc_softc_t *sc, int xpos, int ypos, int dxdir, int xoff, int yoff, int xlen, int ylen) { int x, y; @@ -148,41 +150,60 @@ draw_daemon(int xpos, int ypos, int dxdir, int xoff, int yoff, continue; for (x = xoff; (x < xlen) && (daemon_pic[y][px] != '\0'); x++, px++) { switch (daemon_attr[y][px]) { +#ifndef PC98 case 'R': attr = (FG_LIGHTRED|BG_BLACK)<<8; break; case 'Y': attr = (FG_YELLOW|BG_BLACK)<<8; break; case 'B': attr = (FG_LIGHTBLUE|BG_BLACK)<<8; break; case 'W': attr = (FG_LIGHTGREY|BG_BLACK)<<8; break; case 'C': attr = (FG_CYAN|BG_BLACK)<<8; break; default: attr = (FG_WHITE|BG_BLACK)<<8; break; +#else /* PC98 */ + case 'R': attr = (FG_RED|BG_BLACK)<<8; break; + case 'Y': attr = (FG_BROWN|BG_BLACK)<<8; break; + case 'B': attr = (FG_BLUE|BG_BLACK)<<8; break; + case 'W': attr = (FG_LIGHTGREY|BG_BLACK)<<8; break; + case 'C': attr = (FG_CYAN|BG_BLACK)<<8; break; + default: attr = (FG_LIGHTGREY|BG_BLACK)<<8; break; +#endif /* PC98 */ } if (dxdir < 0) { /* Moving left */ - *CONSOLE_VECT(xpos + x, ypos + y) = - scr_map[daemon_pic[y][px]]|attr; + sc_vtb_putc(&sc->cur_scp->scr, + (ypos + y)*sc->cur_scp->xsize + + xpos + x, + sc->scr_map[daemon_pic[y][px]], + attr); } else { /* Moving right */ - *CONSOLE_VECT(xpos + DAEMON_MAX_WIDTH - px - 1, ypos + y) = - scr_map[xflip_symbol(daemon_pic[y][px])]|attr; + sc_vtb_putc(&sc->cur_scp->scr, + (ypos + y)*sc->cur_scp->xsize + + xpos + DAEMON_MAX_WIDTH + - px - 1, + sc->scr_map[xflip_symbol(daemon_pic[y][px])], + attr); } } } } static void -clear_string(int xpos, int ypos, int xoff, char *s, int len) +clear_string(sc_softc_t *sc, int xpos, int ypos, int xoff, char *s, int len) { if (len <= 0) return; - fillw(((FG_LIGHTGREY|BG_BLACK) << 8) | scr_map[0x20], - CONSOLE_VECT(xpos + xoff, ypos), len - xoff); + sc_vtb_erase(&sc->cur_scp->scr, + ypos*sc->cur_scp->xsize + xpos + xoff, len - xoff, + sc->scr_map[0x20], (FG_LIGHTGREY | BG_BLACK) << 8); } static void -draw_string(int xpos, int ypos, int xoff, char *s, int len) +draw_string(sc_softc_t *sc, int xpos, int ypos, int xoff, char *s, int len) { int x; - for (x = xoff; x < len; x++) - *CONSOLE_VECT(xpos + x, ypos) = - scr_map[s[x]]|(FG_LIGHTGREEN|BG_BLACK)<<8; + for (x = xoff; x < len; x++) { + sc_vtb_putc(&sc->cur_scp->scr, + ypos*sc->cur_scp->xsize + xpos + x, + sc->scr_map[s[x]], (FG_LIGHTGREEN | BG_BLACK) << 8); + } } static int @@ -195,17 +216,30 @@ daemon_saver(video_adapter_t *adp, int blank) static int moved_daemon = 0; static int xoff, yoff, toff; static int xlen, ylen, tlen; - scr_stat *scp = cur_console; + sc_softc_t *sc; + scr_stat *scp; int min, max; + sc = sc_find_softc(adp, NULL); + if (sc == NULL) + return EAGAIN; + scp = sc->cur_scp; + if (blank) { if (adp->va_info.vi_flags & V_INFO_GRAPHICS) return EAGAIN; if (blanked == 0) { - window = (u_short *)adp->va_window; +#ifdef PC98 + if (epson_machine_id == 0x20) { + outb(0x43f, 0x42); + outb(0x0c17, inb(0xc17) & ~0x08); + outb(0x43f, 0x40); + } +#endif /* PC98 */ /* clear the screen and set the border color */ - fillw(((FG_LIGHTGREY|BG_BLACK) << 8) | scr_map[0x20], - window, scp->xsize * scp->ysize); + sc_vtb_clear(&scp->scr, sc->scr_map[0x20], + (FG_LIGHTGREY | BG_BLACK) << 8); + (*vidsw[adp->va_index]->set_hw_cursor)(adp, -1, -1); set_border(scp, 0); xlen = ylen = tlen = 0; } @@ -213,8 +247,8 @@ daemon_saver(video_adapter_t *adp, int blank) return 0; blanked = 1; - clear_daemon(dxpos, dypos, dxdir, xoff, yoff, xlen, ylen); - clear_string(txpos, typos, toff, (char *)message, tlen); + clear_daemon(sc, dxpos, dypos, dxdir, xoff, yoff, xlen, ylen); + clear_string(sc, txpos, typos, toff, (char *)message, tlen); if (++moved_daemon) { /* @@ -319,9 +353,16 @@ daemon_saver(video_adapter_t *adp, int blank) else if (txpos + tlen > scp->xsize) tlen = scp->xsize - txpos; - draw_daemon(dxpos, dypos, dxdir, xoff, yoff, xlen, ylen); - draw_string(txpos, typos, toff, (char *)message, tlen); + draw_daemon(sc, dxpos, dypos, dxdir, xoff, yoff, xlen, ylen); + draw_string(sc, txpos, typos, toff, (char *)message, tlen); } else { +#ifdef PC98 + if (epson_machine_id == 0x20) { + outb(0x43f, 0x42); + outb(0x0c17, inb(0xc17) | 0x08); + outb(0x43f, 0x40); + } +#endif /* PC98 */ blanked = 0; } return 0; diff --git a/sys/modules/syscons/fade/fade_saver.c b/sys/modules/syscons/fade/fade_saver.c index 70d36c9..4a44c85 100644 --- a/sys/modules/syscons/fade/fade_saver.c +++ b/sys/modules/syscons/fade/fade_saver.c @@ -25,17 +25,19 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: fade_saver.c,v 1.15 1998/11/04 03:49:38 peter Exp $ + * $Id: fade_saver.c,v 1.16 1999/01/11 03:18:46 yokota Exp $ */ #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> #include <sys/module.h> +#include <sys/consio.h> +#include <sys/fbio.h> -#include <i386/isa/isa.h> - -#include <saver.h> +#include <dev/fb/fbreg.h> +#include <dev/fb/splashreg.h> +#include <dev/syscons/syscons.h> static u_char palette[256*3]; static int blanked; @@ -49,11 +51,10 @@ fade_saver(video_adapter_t *adp, int blank) if (blank) { blanked = TRUE; - switch (adp->va_type) { - case KD_VGA: + if (ISPALAVAIL(adp->va_flags)) { if (count <= 0) save_palette(adp, palette); - if (count < 64) { + if (count < 256) { pal[0] = pal[1] = pal[2] = 0; for (i = 3; i < 256*3; i++) { if (palette[i] - count > 60) @@ -64,39 +65,17 @@ fade_saver(video_adapter_t *adp, int blank) load_palette(adp, pal); count++; } - break; - case KD_EGA: - /* not yet done XXX */ - break; - case KD_CGA: - outb(adp->va_crtc_addr + 4, 0x25); - break; - case KD_MONO: - case KD_HERCULES: - outb(adp->va_crtc_addr + 4, 0x21); - break; - default: - break; + } else { + (*vidsw[adp->va_index]->blank_display)(adp, + V_DISPLAY_BLANK); } - } - else { - switch (adp->va_type) { - case KD_VGA: + } else { + if (ISPALAVAIL(adp->va_flags)) { load_palette(adp, palette); count = 0; - break; - case KD_EGA: - /* not yet done XXX */ - break; - case KD_CGA: - outb(adp->va_crtc_addr + 4, 0x2d); - break; - case KD_MONO: - case KD_HERCULES: - outb(adp->va_crtc_addr + 4, 0x29); - break; - default: - break; + } else { + (*vidsw[adp->va_index]->blank_display)(adp, + V_DISPLAY_ON); } blanked = FALSE; } @@ -106,21 +85,9 @@ fade_saver(video_adapter_t *adp, int blank) static int fade_init(video_adapter_t *adp) { - switch (adp->va_type) { - case KD_MONO: - case KD_HERCULES: - case KD_CGA: - /* - * `fade' saver is not fully implemented for MDA and CGA. - * It simply blanks the display instead. - */ - case KD_VGA: - break; - case KD_EGA: - /* EGA is yet to be supported */ - default: + if (!ISPALAVAIL(adp->va_flags) + && (*vidsw[adp->va_index]->blank_display)(adp, V_DISPLAY_ON) != 0) return ENODEV; - } blanked = FALSE; return 0; } diff --git a/sys/modules/syscons/fire/fire_saver.c b/sys/modules/syscons/fire/fire_saver.c index aea36a9..db4b80b 100644 --- a/sys/modules/syscons/fire/fire_saver.c +++ b/sys/modules/syscons/fire/fire_saver.c @@ -23,7 +23,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: fire_saver.c,v 1.2.2.1 1999/05/10 15:20:30 des Exp $ + * $Id: fire_saver.c,v 1.4 1999/05/10 15:25:50 des Exp $ */ /* @@ -38,11 +38,14 @@ #include <sys/kernel.h> #include <sys/module.h> #include <sys/syslog.h> +#include <sys/consio.h> +#include <sys/fbio.h> -#include <machine/md_var.h> #include <machine/random.h> -#include <saver.h> +#include <dev/fb/fbreg.h> +#include <dev/fb/splashreg.h> +#include <dev/syscons/syscons.h> #define X_SIZE 320 #define Y_SIZE 200 diff --git a/sys/modules/syscons/green/green_saver.c b/sys/modules/syscons/green/green_saver.c index 9decd72..103154b 100644 --- a/sys/modules/syscons/green/green_saver.c +++ b/sys/modules/syscons/green/green_saver.c @@ -25,93 +25,35 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: green_saver.c,v 1.14 1998/11/04 03:49:38 peter Exp $ + * $Id: green_saver.c,v 1.15 1999/01/11 03:18:48 yokota Exp $ */ #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> #include <sys/module.h> +#include <sys/consio.h> +#include <sys/fbio.h> -#include <dev/fb/vgareg.h> - -#include <i386/isa/isa.h> - -#include <saver.h> +#include <dev/fb/fbreg.h> +#include <dev/fb/splashreg.h> +#include <dev/syscons/syscons.h> static int green_saver(video_adapter_t *adp, int blank) { - int crtc_addr; - u_char val; - - crtc_addr = adp->va_crtc_addr; - if (blank) { - switch (adp->va_type) { - case KD_VGA: - outb(TSIDX, 0x01); val = inb(TSREG); - outb(TSIDX, 0x01); outb(TSREG, val | 0x20); - outb(crtc_addr, 0x17); val = inb(crtc_addr + 1); - outb(crtc_addr + 1, val & ~0x80); - break; - case KD_EGA: - /* not yet done XXX */ - break; - case KD_CGA: - outb(crtc_addr + 4, 0x25); - break; - case KD_MONO: - case KD_HERCULES: - outb(crtc_addr + 4, 0x21); - break; - default: - break; - } - } - else { - switch (adp->va_type) { - case KD_VGA: - outb(TSIDX, 0x01); val = inb(TSREG); - outb(TSIDX, 0x01); outb(TSREG, val & 0xDF); - outb(crtc_addr, 0x17); val = inb(crtc_addr + 1); - outb(crtc_addr + 1, val | 0x80); - break; - case KD_EGA: - /* not yet done XXX */ - break; - case KD_CGA: - outb(crtc_addr + 4, 0x2d); - break; - case KD_MONO: - case KD_HERCULES: - outb(crtc_addr + 4, 0x29); - break; - default: - break; - } - } + (*vidsw[adp->va_index]->blank_display)(adp, + (blank) ? V_DISPLAY_STAND_BY + : V_DISPLAY_ON); return 0; } static int green_init(video_adapter_t *adp) { - switch (adp->va_type) { - case KD_MONO: - case KD_HERCULES: - case KD_CGA: - /* - * `green' saver is not fully implemented for MDA and CGA. - * It simply blanks the display instead. - */ - case KD_VGA: - break; - case KD_EGA: - /* EGA is yet to be supported */ - default: - return ENODEV; - } - return 0; + if ((*vidsw[adp->va_index]->blank_display)(adp, V_DISPLAY_ON) == 0) + return 0; + return ENODEV; } static int diff --git a/sys/modules/syscons/logo/logo_saver.c b/sys/modules/syscons/logo/logo_saver.c index b6a46ac..24da964 100644 --- a/sys/modules/syscons/logo/logo_saver.c +++ b/sys/modules/syscons/logo/logo_saver.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: logo_saver.c,v 1.5 1999/02/05 12:40:15 des Exp $ + * $Id: logo_saver.c,v 1.6 1999/04/12 13:34:57 des Exp $ */ #include <sys/param.h> @@ -33,8 +33,12 @@ #include <sys/kernel.h> #include <sys/module.h> #include <sys/syslog.h> +#include <sys/consio.h> +#include <sys/fbio.h> -#include <saver.h> +#include <dev/fb/fbreg.h> +#include <dev/fb/splashreg.h> +#include <dev/syscons/syscons.h> static u_char *vid; static int banksize, scrmode, bpsl, scrw, scrh; @@ -104,6 +108,7 @@ logo_saver(video_adapter_t *adp, int blank) #endif blanked++; vid = (u_char *)adp->va_window; + banksize = adp->va_window_size; bpsl = adp->va_line_width; splx(pl); for (i = 0; i < bpsl*scrh; i += banksize) { @@ -132,7 +137,6 @@ logo_init(video_adapter_t *adp) return ENODEV; } - banksize = info.vi_window_size; scrw = info.vi_width; scrh = info.vi_height; blanked = 0; diff --git a/sys/modules/syscons/rain/rain_saver.c b/sys/modules/syscons/rain/rain_saver.c index 9aa7370..200dc59 100644 --- a/sys/modules/syscons/rain/rain_saver.c +++ b/sys/modules/syscons/rain/rain_saver.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: rain_saver.c,v 1.2 1999/01/11 03:18:50 yokota Exp $ + * $Id: rain_saver.c,v 1.3 1999/04/12 13:34:57 des Exp $ */ #include <sys/param.h> @@ -33,10 +33,14 @@ #include <sys/kernel.h> #include <sys/module.h> #include <sys/syslog.h> +#include <sys/consio.h> +#include <sys/fbio.h> #include <machine/random.h> -#include <saver.h> +#include <dev/fb/fbreg.h> +#include <dev/fb/splashreg.h> +#include <dev/syscons/syscons.h> static u_char *vid; diff --git a/sys/modules/syscons/saver.h b/sys/modules/syscons/saver.h deleted file mode 100644 index 748dfdd..0000000 --- a/sys/modules/syscons/saver.h +++ /dev/null @@ -1,39 +0,0 @@ -/*- - * Copyright (c) 1995-1998 Søren Schmidt - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer, - * without modification, immediately at the beginning of the file. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $Id: saver.h,v 1.16 1999/01/16 10:20:13 des Exp $ - */ -#include <machine/apm_bios.h> -#include <machine/console.h> - -#include <dev/fb/fbreg.h> -#include <dev/fb/splashreg.h> - -#include <dev/syscons/syscons.h> - -extern scr_stat *cur_console; -extern char scr_map[]; diff --git a/sys/modules/syscons/snake/snake_saver.c b/sys/modules/syscons/snake/snake_saver.c index ef64741..51e1746 100644 --- a/sys/modules/syscons/snake/snake_saver.c +++ b/sys/modules/syscons/snake/snake_saver.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: snake_saver.c,v 1.22 1999/01/17 14:25:19 yokota Exp $ + * $Id: snake_saver.c,v 1.23 1999/02/05 12:40:15 des Exp $ */ #include <sys/param.h> @@ -34,16 +34,18 @@ #include <sys/malloc.h> #include <sys/kernel.h> #include <sys/sysctl.h> +#include <sys/consio.h> +#include <sys/fbio.h> -#include <machine/md_var.h> #include <machine/pc/display.h> -#include <saver.h> +#include <dev/fb/fbreg.h> +#include <dev/fb/splashreg.h> +#include <dev/syscons/syscons.h> static char *message; -static u_char **messagep; +static int *messagep; static int messagelen; -static u_short *window; static int blanked; static int @@ -51,36 +53,50 @@ snake_saver(video_adapter_t *adp, int blank) { static int dirx, diry; int f; - scr_stat *scp = cur_console; + sc_softc_t *sc; + scr_stat *scp; /* XXX hack for minimal changes. */ #define save message #define savs messagep + sc = sc_find_softc(adp, NULL); + if (sc == NULL) + return EAGAIN; + scp = sc->cur_scp; + if (blank) { if (adp->va_info.vi_flags & V_INFO_GRAPHICS) return EAGAIN; if (blanked <= 0) { - window = (u_short *)adp->va_window; - fillw(((FG_LIGHTGREY|BG_BLACK)<<8) | scr_map[0x20], - window, scp->xsize * scp->ysize); +#ifdef PC98 + if (epson_machine_id == 0x20) { + outb(0x43f, 0x42); + outb(0x0c17, inb(0xc17) & ~0x08); + outb(0x43f, 0x40); + } +#endif /* PC98 */ + sc_vtb_clear(&scp->scr, sc->scr_map[0x20], + (FG_LIGHTGREY | BG_BLACK) << 8); + (*vidsw[adp->va_index]->set_hw_cursor)(adp, -1, -1); set_border(scp, 0); dirx = (scp->xpos ? 1 : -1); diry = (scp->ypos ? scp->xsize : -scp->xsize); for (f=0; f< messagelen; f++) - savs[f] = (u_char *)window + 2 * - (scp->xpos+scp->ypos*scp->xsize); - *(savs[0]) = scr_map[*save]; + savs[f] = scp->xpos + scp->ypos*scp->xsize; + sc_vtb_putc(&scp->scr, savs[0], sc->scr_map[*save], + (FG_LIGHTGREY | BG_BLACK) << 8); blanked = 1; } if (blanked++ < 4) return 0; blanked = 1; - *(savs[messagelen-1]) = scr_map[0x20]; + sc_vtb_putc(&scp->scr, savs[messagelen - 1], sc->scr_map[0x20], + (FG_LIGHTGREY | BG_BLACK) << 8); for (f=messagelen-1; f > 0; f--) savs[f] = savs[f-1]; - f = (savs[0] - (u_char *)window) / 2; + f = savs[0]; if ((f % scp->xsize) == 0 || (f % scp->xsize) == scp->xsize - 1 || (random() % 50) == 0) @@ -89,11 +105,19 @@ snake_saver(video_adapter_t *adp, int blank) (f / scp->xsize) == scp->ysize - 1 || (random() % 20) == 0) diry = -diry; - savs[0] += 2*dirx + 2*diry; + savs[0] += dirx + diry; for (f=messagelen-1; f>=0; f--) - *(savs[f]) = scr_map[save[f]]; + sc_vtb_putc(&scp->scr, savs[f], sc->scr_map[save[f]], + (FG_LIGHTGREY | BG_BLACK) << 8); } else { +#ifdef PC98 + if (epson_machine_id == 0x20) { + outb(0x43f, 0x42); + outb(0x0c17, inb(0xc17) | 0x08); + outb(0x43f, 0x40); + } +#endif /* PC98 */ blanked = 0; } return 0; diff --git a/sys/modules/syscons/star/star_saver.c b/sys/modules/syscons/star/star_saver.c index aaa23fb..56408dc 100644 --- a/sys/modules/syscons/star/star_saver.c +++ b/sys/modules/syscons/star/star_saver.c @@ -25,22 +25,24 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: star_saver.c,v 1.19 1999/01/17 14:25:19 yokota Exp $ + * $Id: star_saver.c,v 1.20 1999/02/05 12:40:16 des Exp $ */ #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> #include <sys/module.h> +#include <sys/consio.h> +#include <sys/fbio.h> -#include <machine/md_var.h> #include <machine/pc/display.h> -#include <saver.h> +#include <dev/fb/fbreg.h> +#include <dev/fb/splashreg.h> +#include <dev/syscons/syscons.h> #define NUM_STARS 50 -static u_short *window; static int blanked; /* @@ -50,21 +52,39 @@ static int blanked; static int star_saver(video_adapter_t *adp, int blank) { - scr_stat *scp = cur_console; + sc_softc_t *sc; + scr_stat *scp; int cell, i; char pattern[] = {"...........++++*** "}; +#ifndef PC98 char colors[] = {FG_DARKGREY, FG_LIGHTGREY, FG_WHITE, FG_LIGHTCYAN}; +#else + char colors[] = {FG_BLUE, FG_LIGHTGREY, + FG_LIGHTGREY, FG_CYAN}; +#endif /* PC98 */ static u_short stars[NUM_STARS][2]; + sc = sc_find_softc(adp, NULL); + if (sc == NULL) + return EAGAIN; + scp = sc->cur_scp; + if (blank) { if (adp->va_info.vi_flags & V_INFO_GRAPHICS) return EAGAIN; if (!blanked) { - window = (u_short *)adp->va_window; +#ifdef PC98 + if (epson_machine_id == 0x20) { + outb(0x43f, 0x42); + outb(0x0c17, inb(0xc17) & ~0x08); + outb(0x43f, 0x40); + } +#endif /* PC98 */ /* clear the screen and set the border color */ - fillw(((FG_LIGHTGREY|BG_BLACK) << 8) | scr_map[0x20], - window, scp->xsize * scp->ysize); + sc_vtb_clear(&scp->scr, sc->scr_map[0x20], + (FG_LIGHTGREY | BG_BLACK) << 8); + (*vidsw[adp->va_index]->set_hw_cursor)(adp, -1, -1); set_border(scp, 0); blanked = TRUE; for(i=0; i<NUM_STARS; i++) { @@ -74,15 +94,22 @@ star_saver(video_adapter_t *adp, int blank) } } cell = random() % NUM_STARS; - *((u_short*)(window + stars[cell][0])) = - scr_map[pattern[stars[cell][1]]] | - colors[random()%sizeof(colors)] << 8; + sc_vtb_putc(&scp->scr, stars[cell][0], + sc->scr_map[pattern[stars[cell][1]]], + colors[random()%sizeof(colors)] << 8); if ((stars[cell][1]+=(random()%4)) >= sizeof(pattern)-1) { stars[cell][0] = random() % (scp->xsize*scp->ysize); stars[cell][1] = 0; } } else { +#ifdef PC98 + if (epson_machine_id == 0x20) { + outb(0x43f, 0x42); + outb(0x0c17, inb(0xc17) | 0x08); + outb(0x43f, 0x40); + } +#endif /* PC98 */ blanked = FALSE; } return 0; diff --git a/sys/modules/syscons/warp/warp_saver.c b/sys/modules/syscons/warp/warp_saver.c index 3476c36..cd6f42b 100644 --- a/sys/modules/syscons/warp/warp_saver.c +++ b/sys/modules/syscons/warp/warp_saver.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: warp_saver.c,v 1.4 1999/01/11 03:18:55 yokota Exp $ + * $Id: warp_saver.c,v 1.5 1999/04/12 13:34:58 des Exp $ */ #include <sys/param.h> @@ -33,11 +33,14 @@ #include <sys/kernel.h> #include <sys/module.h> #include <sys/syslog.h> +#include <sys/consio.h> +#include <sys/fbio.h> -#include <machine/md_var.h> #include <machine/random.h> -#include <saver.h> +#include <dev/fb/fbreg.h> +#include <dev/fb/splashreg.h> +#include <dev/syscons/syscons.h> static u_char *vid; static int blanked; diff --git a/sys/sys/cons.h b/sys/sys/cons.h index 1656b12..ea84d7e 100644 --- a/sys/sys/cons.h +++ b/sys/sys/cons.h @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * from: @(#)cons.h 7.2 (Berkeley) 5/9/91 - * $Id: cons.h,v 1.18 1999/01/07 14:14:11 yokota Exp $ + * $Id: cons.h,v 1.19 1999/01/09 14:07:37 bde Exp $ */ #ifndef _MACHINE_CONS_H_ @@ -45,6 +45,7 @@ struct consdev; typedef void cn_probe_t __P((struct consdev *)); typedef void cn_init_t __P((struct consdev *)); +typedef void cn_term_t __P((struct consdev *)); typedef int cn_getc_t __P((dev_t)); typedef int cn_checkc_t __P((dev_t)); typedef void cn_putc_t __P((dev_t, int)); @@ -54,6 +55,8 @@ struct consdev { /* probe hardware and fill in consdev info */ cn_init_t *cn_init; /* turn on as console */ + cn_term_t *cn_term; + /* turn off as console */ cn_getc_t *cn_getc; /* kernel getchar interface */ cn_checkc_t *cn_checkc; @@ -75,10 +78,10 @@ struct consdev { extern struct linker_set cons_set; extern int cons_unavail; -#define CONS_DRIVER(name, probe, init, getc, checkc, putc) \ - static struct consdev name##_consdev = { \ - probe, init, getc, checkc, putc \ - }; \ +#define CONS_DRIVER(name, probe, init, term, getc, checkc, putc) \ + static struct consdev name##_consdev = { \ + probe, init, term, getc, checkc, putc \ + }; \ DATA_SET(cons_set, name##_consdev) /* Other kernel entry points. */ diff --git a/sys/sys/consio.h b/sys/sys/consio.h new file mode 100644 index 0000000..abc9c1f --- /dev/null +++ b/sys/sys/consio.h @@ -0,0 +1,385 @@ +/*- + * Copyright (c) 1991-1996 Søren Schmidt + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Id: console.h,v 1.45 1999/03/10 10:36:47 yokota Exp $ + */ + +#ifndef _SYS_CONSIO_H_ +#define _SYS_CONSIO_H_ + +#ifndef KERNEL +#include <sys/types.h> +#endif +#include <sys/ioccom.h> + +/* + * Console ioctl commands. Some commands are named as KDXXXX, GIO_XXX, and + * PIO_XXX, rather than CONS_XXX, for historical and compatibility reasons. + * Some other CONS_XXX commands are works as wrapper around frame buffer + * ioctl commands FBIO_XXX. Do not try to change all these commands, + * otherwise we shall have compatibility problems. + */ + +/* get/set video mode */ +#define KD_TEXT 0 /* set text mode restore fonts */ +#define KD_TEXT0 0 /* ditto */ +#define KD_GRAPHICS 1 /* set graphics mode */ +#define KD_TEXT1 2 /* set text mode !restore fonts */ +#define KD_PIXEL 3 /* set pixel mode */ +#define KDGETMODE _IOR('K', 9, int) +#define KDSETMODE _IO('K', 10 /*, int */) + +/* set border color */ +#define KDSBORDER _IO('K', 13 /*, int */) + +/* set up raster(pixel) text mode */ +struct scr_size { + int scr_size[3]; +}; +typedef struct scr_size scr_size_t; + +#define KDRASTER _IOW('K', 100, scr_size_t) + +/* get/set screen char map */ +struct scrmap { + char scrmap[256]; +}; +typedef struct scrmap scrmap_t; + +#define GIO_SCRNMAP _IOR('k', 2, scrmap_t) +#define PIO_SCRNMAP _IOW('k', 3, scrmap_t) + +/* get the current text attribute */ +#define GIO_ATTR _IOR('a', 0, int) + +/* get the current text color */ +#define GIO_COLOR _IOR('c', 0, int) + +/* get the adapter type (equivalent to FBIO_ADPTYPE) */ +#define CONS_CURRENT _IOR('c', 1, int) + +/* get the current video mode (equivalent to FBIO_GETMODE) */ +#define CONS_GET _IOR('c', 2, int) + +/* not supported? */ +#define CONS_IO _IO('c', 3) + +/* set blank time interval */ +#define CONS_BLANKTIME _IOW('c', 4, int) + +/* set/get the screen saver (these ioctls are current noop) */ +struct ssaver { +#define MAXSSAVER 16 + char name[MAXSSAVER]; + int num; + long time; +}; +typedef struct ssaver ssaver_t; + +#define CONS_SSAVER _IOW('c', 5, ssaver_t) +#define CONS_GSAVER _IOWR('c', 6, ssaver_t) + +/* set the text cursor shape */ +#define CONS_BLINK_CURSOR (1 << 0) +#define CONS_CHAR_CURSOR (1 << 1) +#define CONS_CURSORTYPE _IOW('c', 7, int) + +/* set the bell type to audible or visual */ +#define CONS_VISUAL_BELL (1 << 0) +#define CONS_QUIET_BELL (1 << 1) +#define CONS_BELLTYPE _IOW('c', 8, int) + +/* set the history (scroll back) buffer size (in lines) */ +#define CONS_HISTORY _IOW('c', 9, int) + +/* mouse cursor ioctl */ +struct mouse_data { + int x; + int y; + int z; + int buttons; +}; +typedef struct mouse_data mouse_data_t; + +struct mouse_mode { + int mode; + int signal; +}; +typedef struct mouse_mode mouse_mode_t; + +struct mouse_event { + int id; /* one based */ + int value; +}; +typedef struct mouse_event mouse_event_t; + +struct mouse_info { + int operation; +#define MOUSE_SHOW 0x01 +#define MOUSE_HIDE 0x02 +#define MOUSE_MOVEABS 0x03 +#define MOUSE_MOVEREL 0x04 +#define MOUSE_GETINFO 0x05 +#define MOUSE_MODE 0x06 +#define MOUSE_ACTION 0x07 +#define MOUSE_MOTION_EVENT 0x08 +#define MOUSE_BUTTON_EVENT 0x09 + union { + mouse_data_t data; + mouse_mode_t mode; + mouse_event_t event; + } u; +}; +typedef struct mouse_info mouse_info_t; + +#define CONS_MOUSECTL _IOWR('c', 10, mouse_info_t) + +/* see if the vty has been idle */ +#define CONS_IDLE _IOR('c', 11, int) + +/* set the screen saver mode */ +#define CONS_LKM_SAVER 0 +#define CONS_USR_SAVER 1 +#define CONS_SAVERMODE _IOW('c', 12, int) + +/* start the screen saver */ +#define CONS_SAVERSTART _IOW('c', 13, int) + +/* set/get font data */ +struct fnt8 { + char fnt8x8[8*256]; +}; +typedef struct fnt8 fnt8_t; + +struct fnt14 { + char fnt8x14[14*256]; +}; +typedef struct fnt14 fnt14_t; + +struct fnt16 { + char fnt8x16[16*256]; +}; +typedef struct fnt16 fnt16_t; + +#define PIO_FONT8x8 _IOW('c', 64, fnt8_t) +#define GIO_FONT8x8 _IOR('c', 65, fnt8_t) +#define PIO_FONT8x14 _IOW('c', 66, fnt14_t) +#define GIO_FONT8x14 _IOR('c', 67, fnt14_t) +#define PIO_FONT8x16 _IOW('c', 68, fnt16_t) +#define GIO_FONT8x16 _IOR('c', 69, fnt16_t) + +/* get video mode information */ +struct colors { + char fore; + char back; +}; + +struct vid_info { + short size; + short m_num; + u_short mv_row, mv_col; + u_short mv_rsz, mv_csz; + struct colors mv_norm, + mv_rev, + mv_grfc; + u_char mv_ovscan; + u_char mk_keylock; +}; +typedef struct vid_info vid_info_t; + +#define CONS_GETINFO _IOWR('c', 73, vid_info_t) + +/* get version */ +#define CONS_GETVERS _IOR('c', 74, int) + +/* get the video adapter index (equivalent to FBIO_ADAPTER) */ +#define CONS_CURRENTADP _IOR('c', 100, int) + +/* get the video adapter information (equivalent to FBIO_ADPINFO) */ +#define CONS_ADPINFO _IOWR('c', 101, video_adapter_info_t) + +/* get the video mode information (equivalent to FBIO_MODEINFO) */ +#define CONS_MODEINFO _IOWR('c', 102, video_info_t) + +/* find a video mode (equivalent to FBIO_FINDMODE) */ +#define CONS_FINDMODE _IOWR('c', 103, video_info_t) + +/* set the frame buffer window origin (equivalent to FBIO_SETWINORG) */ +#define CONS_SETWINORG _IO('c', 104 /*, u_int */) + +/* use the specified keyboard */ +#define CONS_SETKBD _IO('c', 110 /*, int */) + +/* release the current keyboard */ +#define CONS_RELKBD _IO('c', 111) + +#ifdef PC98 +#define ADJUST_CLOCK _IO('t',100) /* for 98note resume */ +#endif + +/* + * Vty switching ioctl commands. + */ + +/* get the next available vty */ +#define VT_OPENQRY _IOR('v', 1, int) + +/* set/get vty switching mode */ +#ifndef _VT_MODE_DECLARED +#define _VT_MODE_DECLARED +struct vt_mode { + char mode; +#define VT_AUTO 0 /* switching is automatic */ +#define VT_PROCESS 1 /* switching controlled by prog */ +#define VT_KERNEL 255 /* switching controlled in kernel */ + char waitv; /* not implemented yet SOS */ + short relsig; + short acqsig; + short frsig; /* not implemented yet SOS */ +}; +typedef struct vt_mode vtmode_t; +#endif /* !_VT_MODE_DECLARED */ + +#define VT_SETMODE _IOW('v', 2, vtmode_t) +#define VT_GETMODE _IOR('v', 3, vtmode_t) + +/* acknowledge release or acquisition of a vty */ +#define VT_FALSE 0 +#define VT_TRUE 1 +#define VT_ACKACQ 2 +#define VT_RELDISP _IO('v', 4 /*, int */) + +/* activate the specified vty */ +#define VT_ACTIVATE _IO('v', 5 /*, int */) + +/* wait until the specified vty is activate */ +#define VT_WAITACTIVE _IO('v', 6 /*, int */) + +/* get the currently active vty */ +#define VT_GETACTIVE _IOR('v', 7, int) + +/* get the index of the vty */ +#define VT_GETINDEX _IOR('v', 8, int) + +/* + * Video mode switching ioctl. See sys/fbio.h for mode numbers. + */ + +#define SW_B40x25 _IO('S', M_B40x25) +#define SW_C40x25 _IO('S', M_C40x25) +#define SW_B80x25 _IO('S', M_B80x25) +#define SW_C80x25 _IO('S', M_C80x25) +#define SW_BG320 _IO('S', M_BG320) +#define SW_CG320 _IO('S', M_CG320) +#define SW_BG640 _IO('S', M_BG640) +#define SW_EGAMONO80x25 _IO('S', M_EGAMONO80x25) +#define SW_CG320_D _IO('S', M_CG320_D) +#define SW_CG640_E _IO('S', M_CG640_E) +#define SW_EGAMONOAPA _IO('S', M_EGAMONOAPA) +#define SW_CG640x350 _IO('S', M_CG640x350) +#define SW_ENH_MONOAPA2 _IO('S', M_ENHMONOAPA2) +#define SW_ENH_CG640 _IO('S', M_ENH_CG640) +#define SW_ENH_B40x25 _IO('S', M_ENH_B40x25) +#define SW_ENH_C40x25 _IO('S', M_ENH_C40x25) +#define SW_ENH_B80x25 _IO('S', M_ENH_B80x25) +#define SW_ENH_C80x25 _IO('S', M_ENH_C80x25) +#define SW_ENH_B80x43 _IO('S', M_ENH_B80x43) +#define SW_ENH_C80x43 _IO('S', M_ENH_C80x43) +#define SW_MCAMODE _IO('S', M_MCA_MODE) +#define SW_VGA_C40x25 _IO('S', M_VGA_C40x25) +#define SW_VGA_C80x25 _IO('S', M_VGA_C80x25) +#define SW_VGA_C80x30 _IO('S', M_VGA_C80x30) +#define SW_VGA_C80x50 _IO('S', M_VGA_C80x50) +#define SW_VGA_C80x60 _IO('S', M_VGA_C80x60) +#define SW_VGA_M80x25 _IO('S', M_VGA_M80x25) +#define SW_VGA_M80x30 _IO('S', M_VGA_M80x30) +#define SW_VGA_M80x50 _IO('S', M_VGA_M80x50) +#define SW_VGA_M80x60 _IO('S', M_VGA_M80x60) +#define SW_VGA11 _IO('S', M_VGA11) +#define SW_BG640x480 _IO('S', M_VGA11) +#define SW_VGA12 _IO('S', M_VGA12) +#define SW_CG640x480 _IO('S', M_VGA12) +#define SW_VGA13 _IO('S', M_VGA13) +#define SW_VGA_CG320 _IO('S', M_VGA13) +#define SW_VGA_CG640 _IO('S', M_VGA_CG640) +#define SW_VGA_MODEX _IO('S', M_VGA_MODEX) + +#define SW_PC98_80x25 _IO('S', M_PC98_80x25) +#define SW_PC98_80x30 _IO('S', M_PC98_80x30) + +#define SW_VGA_C90x25 _IO('S', M_VGA_C90x25) +#define SW_VGA_M90x25 _IO('S', M_VGA_M90x25) +#define SW_VGA_C90x30 _IO('S', M_VGA_C90x30) +#define SW_VGA_M90x30 _IO('S', M_VGA_M90x30) +#define SW_VGA_C90x43 _IO('S', M_VGA_C90x43) +#define SW_VGA_M90x43 _IO('S', M_VGA_M90x43) +#define SW_VGA_C90x50 _IO('S', M_VGA_C90x50) +#define SW_VGA_M90x50 _IO('S', M_VGA_M90x50) +#define SW_VGA_C90x60 _IO('S', M_VGA_C90x60) +#define SW_VGA_M90x60 _IO('S', M_VGA_M90x60) + +#define SW_TEXT_80x25 _IO('S', M_TEXT_80x25) +#define SW_TEXT_80x30 _IO('S', M_TEXT_80x30) +#define SW_TEXT_80x43 _IO('S', M_TEXT_80x43) +#define SW_TEXT_80x50 _IO('S', M_TEXT_80x50) +#define SW_TEXT_80x60 _IO('S', M_TEXT_80x60) +#define SW_TEXT_132x25 _IO('S', M_TEXT_132x25) +#define SW_TEXT_132x30 _IO('S', M_TEXT_132x30) +#define SW_TEXT_132x43 _IO('S', M_TEXT_132x43) +#define SW_TEXT_132x50 _IO('S', M_TEXT_132x50) +#define SW_TEXT_132x60 _IO('S', M_TEXT_132x60) + +#define SW_VESA_CG640x400 _IO('V', M_VESA_CG640x400 - M_VESA_BASE) +#define SW_VESA_CG640x480 _IO('V', M_VESA_CG640x480 - M_VESA_BASE) +#define SW_VESA_800x600 _IO('V', M_VESA_800x600 - M_VESA_BASE) +#define SW_VESA_CG800x600 _IO('V', M_VESA_CG800x600 - M_VESA_BASE) +#define SW_VESA_1024x768 _IO('V', M_VESA_1024x768 - M_VESA_BASE) +#define SW_VESA_CG1024x768 _IO('V', M_VESA_CG1024x768 - M_VESA_BASE) +#define SW_VESA_1280x1024 _IO('V', M_VESA_1280x1024 - M_VESA_BASE) +#define SW_VESA_CG1280x1024 _IO('V', M_VESA_CG1280x1024 - M_VESA_BASE) +#define SW_VESA_C80x60 _IO('V', M_VESA_C80x60 - M_VESA_BASE) +#define SW_VESA_C132x25 _IO('V', M_VESA_C132x25 - M_VESA_BASE) +#define SW_VESA_C132x43 _IO('V', M_VESA_C132x43 - M_VESA_BASE) +#define SW_VESA_C132x50 _IO('V', M_VESA_C132x50 - M_VESA_BASE) +#define SW_VESA_C132x60 _IO('V', M_VESA_C132x60 - M_VESA_BASE) +#define SW_VESA_32K_320 _IO('V', M_VESA_32K_320 - M_VESA_BASE) +#define SW_VESA_64K_320 _IO('V', M_VESA_64K_320 - M_VESA_BASE) +#define SW_VESA_FULL_320 _IO('V', M_VESA_FULL_320 - M_VESA_BASE) +#define SW_VESA_32K_640 _IO('V', M_VESA_32K_640 - M_VESA_BASE) +#define SW_VESA_64K_640 _IO('V', M_VESA_64K_640 - M_VESA_BASE) +#define SW_VESA_FULL_640 _IO('V', M_VESA_FULL_640 - M_VESA_BASE) +#define SW_VESA_32K_800 _IO('V', M_VESA_32K_800 - M_VESA_BASE) +#define SW_VESA_64K_800 _IO('V', M_VESA_64K_800 - M_VESA_BASE) +#define SW_VESA_FULL_800 _IO('V', M_VESA_FULL_800 - M_VESA_BASE) +#define SW_VESA_32K_1024 _IO('V', M_VESA_32K_1024 - M_VESA_BASE) +#define SW_VESA_64K_1024 _IO('V', M_VESA_64K_1024 - M_VESA_BASE) +#define SW_VESA_FULL_1024 _IO('V', M_VESA_FULL_1024 - M_VESA_BASE) +#define SW_VESA_32K_1280 _IO('V', M_VESA_32K_1280 - M_VESA_BASE) +#define SW_VESA_64K_1280 _IO('V', M_VESA_64K_1280 - M_VESA_BASE) +#define SW_VESA_FULL_1280 _IO('V', M_VESA_FULL_1280 - M_VESA_BASE) + +#endif /* !_SYS_CONSIO_H_ */ diff --git a/sys/sys/fbio.h b/sys/sys/fbio.h index 5dca599..c4b5153 100644 --- a/sys/sys/fbio.h +++ b/sys/sys/fbio.h @@ -36,12 +36,17 @@ * * @(#)fbio.h 8.2 (Berkeley) 10/30/93 * - * $Id$ + * $Id: fbio.h,v 1.5 1997/02/22 09:45:12 peter Exp $ */ #ifndef _SYS_FBIO_H_ #define _SYS_FBIO_H_ +#ifndef KERNEL +#include <sys/types.h> +#endif +#include <sys/ioccom.h> + /* * Frame buffer ioctls (from Sprite, trimmed to essentials for X11). */ @@ -72,7 +77,15 @@ #define FBTYPE_RESERVED2 18 /* reserved, do not use */ #define FBTYPE_RESERVED1 19 /* reserved, do not use */ -#define FBTYPE_LASTPLUSONE 20 /* max number of fbs (change as add) */ +#define FBTYPE_MDA 20 +#define FBTYPE_HERCULES 21 +#define FBTYPE_CGA 22 +#define FBTYPE_EGA 23 +#define FBTYPE_VGA 24 +#define FBTYPE_PC98 25 +#define FBTYPE_TGA 26 + +#define FBTYPE_LASTPLUSONE 27 /* max number of fbs (change as add) */ /* * Frame buffer descriptor as returned by FBIOGTYPE. @@ -188,4 +201,274 @@ struct fbcursor { /* get maximum cursor size */ #define FBIOGCURMAX _IOR('F', 28, struct fbcurpos) -#endif +/* The new style frame buffer ioctls. */ + +/* video mode information block */ +struct video_info { + int vi_mode; /* mode number, see below */ + int vi_flags; +#define V_INFO_COLOR (1 << 0) +#define V_INFO_GRAPHICS (1 << 1) +#define V_INFO_LINEAR (1 << 2) +#define V_INFO_VESA (1 << 3) + int vi_width; + int vi_height; + int vi_cwidth; + int vi_cheight; + int vi_depth; + int vi_planes; + u_int vi_window; /* physical address */ + size_t vi_window_size; + size_t vi_window_gran; + u_int vi_buffer; /* physical address */ + size_t vi_buffer_size; + int vi_mem_model; +#define V_INFO_MM_OTHER (-1) +#define V_INFO_MM_TEXT 0 +#define V_INFO_MM_PLANAR 1 +#define V_INFO_MM_PACKED 2 +#define V_INFO_MM_DIRECT 3 +#define V_INFO_MM_CGA 100 +#define V_INFO_MM_HGC 101 + /* for MM_PACKED and MM_DIRECT only */ + int vi_pixel_size; /* in bytes */ + /* for MM_DIRECT only */ + int vi_pixel_fields[4]; /* RGB and reserved fields */ + int vi_pixel_fsizes[4]; + /* reserved */ + u_char vi_reserved[64]; +}; +typedef struct video_info video_info_t; + +/* adapter infromation block */ +struct video_adapter { + int va_index; + int va_type; +#define KD_OTHER 0 /* unknown */ +#define KD_MONO 1 /* monochrome adapter */ +#define KD_HERCULES 2 /* hercules adapter */ +#define KD_CGA 3 /* color graphics adapter */ +#define KD_EGA 4 /* enhanced graphics adapter */ +#define KD_VGA 5 /* video graphics adapter */ +#define KD_PC98 6 /* PC-98 display */ +#define KD_TGA 7 /* TGA */ + char *va_name; + int va_unit; + int va_minor; + int va_flags; +#define V_ADP_COLOR (1 << 0) +#define V_ADP_MODECHANGE (1 << 1) +#define V_ADP_STATESAVE (1 << 2) +#define V_ADP_STATELOAD (1 << 3) +#define V_ADP_FONT (1 << 4) +#define V_ADP_PALETTE (1 << 5) +#define V_ADP_BORDER (1 << 6) +#define V_ADP_VESA (1 << 7) +#define V_ADP_PROBED (1 << 16) +#define V_ADP_INITIALIZED (1 << 17) +#define V_ADP_REGISTERED (1 << 18) + int va_io_base; + int va_io_size; + int va_crtc_addr; + int va_mem_base; + int va_mem_size; + vm_offset_t va_window; /* virtual address */ + size_t va_window_size; + size_t va_window_gran; + u_int va_window_orig; + vm_offset_t va_buffer; /* virtual address */ + size_t va_buffer_size; + int va_initial_mode; + int va_initial_bios_mode; + int va_mode; + struct video_info va_info; + int va_line_width; + struct { + int x; + int y; + } va_disp_start; + void *va_token; +}; +typedef struct video_adapter video_adapter_t; + +struct video_adapter_info { + int va_index; + int va_type; + char va_name[16]; + int va_unit; + int va_flags; + int va_io_base; + int va_io_size; + int va_crtc_addr; + int va_mem_base; + int va_mem_size; + u_int va_window; /* virtual address */ + size_t va_window_size; + size_t va_window_gran; + u_int va_unused0; + size_t va_buffer_size; + int va_initial_mode; + int va_initial_bios_mode; + int va_mode; + int va_line_width; + struct { + int x; + int y; + } va_disp_start; + u_int va_window_orig; + /* reserved */ + u_char va_reserved[64]; +}; +typedef struct video_adapter_info video_adapter_info_t; + +/* some useful video adapter index */ +#define V_ADP_PRIMARY 0 +#define V_ADP_SECONDARY 1 + +/* video mode numbers */ + +#define M_B40x25 0 /* black & white 40 columns */ +#define M_C40x25 1 /* color 40 columns */ +#define M_B80x25 2 /* black & white 80 columns */ +#define M_C80x25 3 /* color 80 columns */ +#define M_BG320 4 /* black & white graphics 320x200 */ +#define M_CG320 5 /* color graphics 320x200 */ +#define M_BG640 6 /* black & white graphics 640x200 hi-res */ +#define M_EGAMONO80x25 7 /* ega-mono 80x25 */ +#define M_CG320_D 13 /* ega mode D */ +#define M_CG640_E 14 /* ega mode E */ +#define M_EGAMONOAPA 15 /* ega mode F */ +#define M_CG640x350 16 /* ega mode 10 */ +#define M_ENHMONOAPA2 17 /* ega mode F with extended memory */ +#define M_ENH_CG640 18 /* ega mode 10* */ +#define M_ENH_B40x25 19 /* ega enhanced black & white 40 columns */ +#define M_ENH_C40x25 20 /* ega enhanced color 40 columns */ +#define M_ENH_B80x25 21 /* ega enhanced black & white 80 columns */ +#define M_ENH_C80x25 22 /* ega enhanced color 80 columns */ +#define M_VGA_C40x25 23 /* vga 8x16 font on color */ +#define M_VGA_C80x25 24 /* vga 8x16 font on color */ +#define M_VGA_M80x25 25 /* vga 8x16 font on mono */ + +#define M_VGA11 26 /* vga 640x480 2 colors */ +#define M_BG640x480 26 +#define M_VGA12 27 /* vga 640x480 16 colors */ +#define M_CG640x480 27 +#define M_VGA13 28 /* vga 320x200 256 colors */ +#define M_VGA_CG320 28 + +#define M_VGA_C80x50 30 /* vga 8x8 font on color */ +#define M_VGA_M80x50 31 /* vga 8x8 font on color */ +#define M_VGA_C80x30 32 /* vga 8x16 font on color */ +#define M_VGA_M80x30 33 /* vga 8x16 font on color */ +#define M_VGA_C80x60 34 /* vga 8x8 font on color */ +#define M_VGA_M80x60 35 /* vga 8x8 font on color */ +#define M_VGA_CG640 36 /* vga 640x400 256 color */ +#define M_VGA_MODEX 37 /* vga 320x240 256 color */ + +#define M_VGA_C90x25 40 /* vga 8x16 font on color */ +#define M_VGA_M90x25 41 /* vga 8x16 font on mono */ +#define M_VGA_C90x30 42 /* vga 8x16 font on color */ +#define M_VGA_M90x30 43 /* vga 8x16 font on mono */ +#define M_VGA_C90x43 44 /* vga 8x8 font on color */ +#define M_VGA_M90x43 45 /* vga 8x8 font on mono */ +#define M_VGA_C90x50 46 /* vga 8x8 font on color */ +#define M_VGA_M90x50 47 /* vga 8x8 font on mono */ +#define M_VGA_C90x60 48 /* vga 8x8 font on color */ +#define M_VGA_M90x60 49 /* vga 8x8 font on mono */ + +#define M_ENH_B80x43 0x70 /* ega black & white 80x43 */ +#define M_ENH_C80x43 0x71 /* ega color 80x43 */ + +#define M_PC98_80x25 98 /* PC98 80x25 */ +#define M_PC98_80x30 99 /* PC98 80x30 */ + +#define M_HGC_P0 0xe0 /* hercules graphics - page 0 @ B0000 */ +#define M_HGC_P1 0xe1 /* hercules graphics - page 1 @ B8000 */ +#define M_MCA_MODE 0xff /* monochrome adapter mode */ + +#define M_TEXT_80x25 200 /* generic text modes */ +#define M_TEXT_80x30 201 +#define M_TEXT_80x43 202 +#define M_TEXT_80x50 203 +#define M_TEXT_80x60 204 +#define M_TEXT_132x25 205 +#define M_TEXT_132x30 206 +#define M_TEXT_132x43 207 +#define M_TEXT_132x50 208 +#define M_TEXT_132x60 209 + +#define M_VESA_BASE 0x100 /* VESA mode number base */ +#define M_VESA_CG640x400 0x100 /* 640x400, 256 color */ +#define M_VESA_CG640x480 0x101 /* 640x480, 256 color */ +#define M_VESA_800x600 0x102 /* 800x600, 16 color */ +#define M_VESA_CG800x600 0x103 /* 800x600, 256 color */ +#define M_VESA_1024x768 0x104 /* 1024x768, 16 color */ +#define M_VESA_CG1024x768 0x105 /* 1024x768, 256 color */ +#define M_VESA_1280x1024 0x106 /* 1280x1024, 16 color */ +#define M_VESA_CG1280x1024 0x107 /* 1280x1024, 256 color */ +#define M_VESA_C80x60 0x108 /* 8x8 font */ +#define M_VESA_C132x25 0x109 /* 8x16 font */ +#define M_VESA_C132x43 0x10a /* 8x14 font */ +#define M_VESA_C132x50 0x10b /* 8x8 font */ +#define M_VESA_C132x60 0x10c /* 8x8 font */ +#define M_VESA_32K_320 0x10d /* 320x200, 5:5:5 */ +#define M_VESA_64K_320 0x10e /* 320x200, 5:6:5 */ +#define M_VESA_FULL_320 0x10f /* 320x200, 8:8:8 */ +#define M_VESA_32K_640 0x110 /* 640x480, 5:5:5 */ +#define M_VESA_64K_640 0x111 /* 640x480, 5:6:5 */ +#define M_VESA_FULL_640 0x112 /* 640x480, 8:8:8 */ +#define M_VESA_32K_800 0x113 /* 800x600, 5:5:5 */ +#define M_VESA_64K_800 0x114 /* 800x600, 5:6:5 */ +#define M_VESA_FULL_800 0x115 /* 800x600, 8:8:8 */ +#define M_VESA_32K_1024 0x116 /* 1024x768, 5:5:5 */ +#define M_VESA_64K_1024 0x117 /* 1024x768, 5:6:5 */ +#define M_VESA_FULL_1024 0x118 /* 1024x768, 8:8:8 */ +#define M_VESA_32K_1280 0x119 /* 1280x1024, 5:5:5 */ +#define M_VESA_64K_1280 0x11a /* 1280x1024, 5:6:5 */ +#define M_VESA_FULL_1280 0x11b /* 1280x1024, 8:8:8 */ +#define M_VESA_MODE_MAX 0x1ff + +struct video_display_start { + int x; + int y; +}; +typedef struct video_display_start video_display_start_t; + +struct video_color_palette { + int index; /* first element (zero-based) */ + int count; /* number of elements */ + u_char *red; /* red */ + u_char *green; /* green */ + u_char *blue; /* blue */ + u_char *transparent; /* may be NULL */ +}; +typedef struct video_color_palette video_color_palette_t; + +/* adapter info. */ +#define FBIO_ADAPTER _IOR('F', 100, int) +#define FBIO_ADPTYPE _IOR('F', 101, int) +#define FBIO_ADPINFO _IOR('F', 102, struct video_adapter_info) + +/* video mode control */ +#define FBIO_MODEINFO _IOWR('F', 103, struct video_info) +#define FBIO_FINDMODE _IOWR('F', 104, struct video_info) +#define FBIO_GETMODE _IOR('F', 105, int) +#define FBIO_SETMODE _IOW('F', 106, int) + +/* get/set frame buffer window origin */ +#define FBIO_GETWINORG _IOR('F', 107, u_int) +#define FBIO_SETWINORG _IOW('F', 108, u_int) + +/* get/set display start address */ +#define FBIO_GETDISPSTART _IOR('F', 109, video_display_start_t) +#define FBIO_SETDISPSTART _IOW('F', 110, video_display_start_t) + +/* get/set scan line width */ +#define FBIO_GETLINEWIDTH _IOR('F', 111, u_int) +#define FBIO_SETLINEWIDTH _IOW('F', 112, u_int) + +/* color palette control */ +#define FBIO_GETPALETTE _IOW('F', 113, video_color_palette_t) +#define FBIO_SETPALETTE _IOW('F', 114, video_color_palette_t) + +#endif /* !_SYS_FBIO_H_ */ diff --git a/sys/sys/kbio.h b/sys/sys/kbio.h new file mode 100644 index 0000000..c8e9947 --- /dev/null +++ b/sys/sys/kbio.h @@ -0,0 +1,228 @@ +/*- + * $Id: $ + */ + +#ifndef _SYS_KBIO_H_ +#define _SYS_KBIO_H_ + +#ifndef KERNEL +#include <sys/types.h> +#endif +#include <sys/ioccom.h> + +/* get/set keyboard I/O mode */ +#define K_RAW 0 /* keyboard returns scancodes */ +#define K_XLATE 1 /* keyboard returns ascii */ +#define K_CODE 2 /* keyboard returns keycodes */ +#define KDGKBMODE _IOR('K', 6, int) +#define KDSKBMODE _IO('K', 7 /*, int */) + +/* make tone */ +#define KDMKTONE _IO('K', 8 /*, int */) + +/* see console.h for the definitions of the following ioctls */ +#if notdef +#define KDGETMODE _IOR('K', 9, int) +#define KDSETMODE _IO('K', 10 /*, int */) +#define KDSBORDER _IO('K', 13 /*, int */) +#endif + +/* get/set keyboard lock state */ +#define CLKED 1 /* Caps locked */ +#define NLKED 2 /* Num locked */ +#define SLKED 4 /* Scroll locked */ +#define ALKED 8 /* AltGr locked */ +#define LOCK_MASK (CLKED | NLKED | SLKED | ALKED) +#define KDGKBSTATE _IOR('K', 19, int) +#define KDSKBSTATE _IO('K', 20 /*, int */) + +/* enable/disable I/O access */ +#define KDENABIO _IO('K', 60) +#define KDDISABIO _IO('K', 61) + +/* make sound */ +#define KIOCSOUND _IO('K', 63 /*, int */) + +/* get keyboard model */ +#define KB_OTHER 0 /* keyboard not known */ +#define KB_84 1 /* 'old' 84 key AT-keyboard */ +#define KB_101 2 /* MF-101 or MF-102 keyboard */ +#define KDGKBTYPE _IOR('K', 64, int) + +/* get/set keyboard LED state */ +#define LED_CAP 1 /* Caps lock LED */ +#define LED_NUM 2 /* Num lock LED */ +#define LED_SCR 4 /* Scroll lock LED */ +#define LED_MASK (LED_CAP | LED_NUM | LED_SCR) +#define KDGETLED _IOR('K', 65, int) +#define KDSETLED _IO('K', 66 /*, int */) + +/* set keyboard repeat rate (obsolete, use KDSETREPEAT below) */ +#define KDSETRAD _IO('K', 67 /*, int */) + +/* see console.h for the definition of the following ioctl */ +#if notdef +#define KDRASTER _IOW('K', 100, scr_size_t) +#endif + +/* get keyboard information */ +struct keyboard_info { + int kb_index; /* kbdio index# */ + char kb_name[16]; /* driver name */ + int kb_unit; /* unit# */ + int kb_type; /* KB_84, KB_101, KB_OTHER,... */ + int kb_config; /* device configuration flags */ + int kb_flags; /* internal flags */ +}; +typedef struct keyboard_info keyboard_info_t; +#define KDGKBINFO _IOR('K', 101, keyboard_info_t) + +/* set keyboard repeat rate (new interface) */ +struct keyboard_repeat { + int kb_repeat[2]; +}; +typedef struct keyboard_repeat keyboard_repeat_t; +#define KDSETREPEAT _IOW('K', 102, keyboard_repeat_t) + +/* get/set key map/accent map/function key strings */ + +#define NUM_KEYS 256 /* number of keys in table */ +#define NUM_STATES 8 /* states per key */ +#define ALTGR_OFFSET 128 /* offset for altlock keys */ + +#define NUM_DEADKEYS 15 /* number of accent keys */ +#define NUM_ACCENTCHARS 52 /* max number of accent chars */ + +#define NUM_FKEYS 96 /* max number of function keys */ +#define MAXFK 16 /* max length of a function key str */ + +#ifndef _KEYMAP_DECLARED +#define _KEYMAP_DECLARED + +struct keyent_t { + u_char map[NUM_STATES]; + u_char spcl; + u_char flgs; +#define FLAG_LOCK_O 0 +#define FLAG_LOCK_C 1 +#define FLAG_LOCK_N 2 +}; + +struct keymap { + u_short n_keys; + struct keyent_t key[NUM_KEYS]; +}; +typedef struct keymap keymap_t; + +#endif /* !_KEYMAP_DECLARED */ + +/* defines for "special" keys (spcl bit set in keymap) */ +#define NOP 0x00 /* nothing (dead key) */ +#define LSH 0x02 /* left shift key */ +#define RSH 0x03 /* right shift key */ +#define CLK 0x04 /* caps lock key */ +#define NLK 0x05 /* num lock key */ +#define SLK 0x06 /* scroll lock key */ +#define LALT 0x07 /* left alt key */ +#define BTAB 0x08 /* backwards tab */ +#define LCTR 0x09 /* left control key */ +#define NEXT 0x0a /* switch to next screen */ +#define F_SCR 0x0b /* switch to first screen */ +#define L_SCR 0x1a /* switch to last screen */ +#define F_FN 0x1b /* first function key */ +#define L_FN 0x7a /* last function key */ +/* 0x7b-0x7f reserved do not use ! */ +#define RCTR 0x80 /* right control key */ +#define RALT 0x81 /* right alt (altgr) key */ +#define ALK 0x82 /* alt lock key */ +#define ASH 0x83 /* alt shift key */ +#define META 0x84 /* meta key */ +#define RBT 0x85 /* boot machine */ +#define DBG 0x86 /* call debugger */ +#define SUSP 0x87 /* suspend power (APM) */ +#define SPSC 0x88 /* toggle splash/text screen */ + +#define F_ACC DGRA /* first accent key */ +#define DGRA 0x89 /* grave */ +#define DACU 0x8a /* acute */ +#define DCIR 0x8b /* circumflex */ +#define DTIL 0x8c /* tilde */ +#define DMAC 0x8d /* macron */ +#define DBRE 0x8e /* breve */ +#define DDOT 0x8f /* dot */ +#define DUML 0x90 /* umlaut/diaresis */ +#define DDIA 0x90 /* diaresis */ +#define DSLA 0x91 /* slash */ +#define DRIN 0x92 /* ring */ +#define DCED 0x93 /* cedilla */ +#define DAPO 0x94 /* apostrophe */ +#define DDAC 0x95 /* double acute */ +#define DOGO 0x96 /* ogonek */ +#define DCAR 0x97 /* caron */ +#define L_ACC DCAR /* last accent key */ + +#define STBY 0x98 /* Go into standby mode (apm) */ +#define PREV 0x99 /* switch to previous screen */ + +#define F(x) ((x)+F_FN-1) +#define S(x) ((x)+F_SCR-1) +#define ACC(x) ((x)+F_ACC) + +struct acc_t { + u_char accchar; + u_char map[NUM_ACCENTCHARS][2]; +}; + +struct accentmap { + u_short n_accs; + struct acc_t acc[NUM_DEADKEYS]; +}; +typedef struct accentmap accentmap_t; + +struct keyarg { + u_short keynum; + struct keyent_t key; +}; +typedef struct keyarg keyarg_t; + +struct fkeytab { + u_char str[MAXFK]; + u_char len; +}; +typedef struct fkeytab fkeytab_t; + +struct fkeyarg { + u_short keynum; + char keydef[MAXFK]; + char flen; +}; +typedef struct fkeyarg fkeyarg_t; + +#define GETFKEY _IOWR('k', 0, fkeyarg_t) +#define SETFKEY _IOWR('k', 1, fkeyarg_t) +#if notdef /* see console.h */ +#define GIO_SCRNMAP _IOR('k', 2, scrmap_t) +#define PIO_SCRNMAP _IOW('k', 3, scrmap_t) +#endif +#define GIO_KEYMAP _IOR('k', 6, keymap_t) +#define PIO_KEYMAP _IOW('k', 7, keymap_t) +#define GIO_DEADKEYMAP _IOR('k', 8, accentmap_t) +#define PIO_DEADKEYMAP _IOW('k', 9, accentmap_t) +#define GIO_KEYMAPENT _IOWR('k', 10, keyarg_t) +#define PIO_KEYMAPENT _IOW('k', 11, keyarg_t) + +/* flags set to the return value in the KD_XLATE mode */ + +#define NOKEY 0x100 /* no key pressed marker */ +#define FKEY 0x200 /* function key marker */ +#define MKEY 0x400 /* meta key marker (prepend ESC)*/ +#define BKEY 0x800 /* backtab (ESC [ Z) */ + +#define SPCLKEY 0x8000 /* special key */ +#define RELKEY 0x4000 /* key released */ +#define ERRKEY 0x2000 /* error */ + +#define KEYCHAR(c) ((c) & 0x00ff) +#define KEYFLAGS(c) ((c) & ~0x00ff) + +#endif /* !_SYS_KBIO_H_ */ |