From 83e223ac3aaa15f444f462d48abc2e69856ae5bf Mon Sep 17 00:00:00 2001 From: kato Date: Wed, 16 Dec 1998 14:57:38 +0000 Subject: Sync with current sc driver in sys/i386/isa. Submitted by: Takahashi Yoshihiro --- sys/conf/files.pc98 | 4 +- sys/pc98/conf/files.pc98 | 4 +- sys/pc98/pc98/scvidctl.c | 529 ++++++++++ sys/pc98/pc98/syscons.c | 2445 +++++++++++++++++----------------------------- sys/pc98/pc98/syscons.h | 122 ++- 5 files changed, 1518 insertions(+), 1586 deletions(-) create mode 100644 sys/pc98/pc98/scvidctl.c diff --git a/sys/conf/files.pc98 b/sys/conf/files.pc98 index 5e3a69b..96dc13d 100644 --- a/sys/conf/files.pc98 +++ b/sys/conf/files.pc98 @@ -3,7 +3,7 @@ # # modified for PC-9801 # -# $Id: files.pc98,v 1.73 1998/12/02 08:15:17 kato Exp $ +# $Id: files.pc98,v 1.74 1998/12/15 15:56:37 kato Exp $ # # The long compile-with and dependency lines are required because of # limitations in config: backslash-newline doesn't work in strings, and @@ -249,7 +249,7 @@ i386/isa/spigot.c optional spigot device-driver pc98/pc98/spkr.c optional speaker device-driver i386/isa/stallion.c optional stl device-driver pc98/pc98/syscons.c optional sc device-driver -#i386/isa/scvidctl.c optional sc device-driver +pc98/pc98/scvidctl.c optional sc device-driver #i386/isa/scvesactl.c optional sc device-driver #i386/isa/videoio.c optional sc device-driver #i386/isa/vesa.c optional sc device-driver diff --git a/sys/pc98/conf/files.pc98 b/sys/pc98/conf/files.pc98 index 5e3a69b..96dc13d 100644 --- a/sys/pc98/conf/files.pc98 +++ b/sys/pc98/conf/files.pc98 @@ -3,7 +3,7 @@ # # modified for PC-9801 # -# $Id: files.pc98,v 1.73 1998/12/02 08:15:17 kato Exp $ +# $Id: files.pc98,v 1.74 1998/12/15 15:56:37 kato Exp $ # # The long compile-with and dependency lines are required because of # limitations in config: backslash-newline doesn't work in strings, and @@ -249,7 +249,7 @@ i386/isa/spigot.c optional spigot device-driver pc98/pc98/spkr.c optional speaker device-driver i386/isa/stallion.c optional stl device-driver pc98/pc98/syscons.c optional sc device-driver -#i386/isa/scvidctl.c optional sc device-driver +pc98/pc98/scvidctl.c optional sc device-driver #i386/isa/scvesactl.c optional sc device-driver #i386/isa/videoio.c optional sc device-driver #i386/isa/vesa.c optional sc device-driver diff --git a/sys/pc98/pc98/scvidctl.c b/sys/pc98/pc98/scvidctl.c new file mode 100644 index 0000000..2a5cecc --- /dev/null +++ b/sys/pc98/pc98/scvidctl.c @@ -0,0 +1,529 @@ +/*- + * Copyright (c) 1998 Kazutaka YOKOTA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer as + * the first lines of this file unmodified. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE 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: scvidctl.c,v 1.5 1998/10/01 11:39:18 yokota Exp $ + */ + +#include "sc.h" +#include "opt_syscons.h" + +#if NSC > 0 + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +/* video ioctl */ + +extern scr_stat *cur_console; +extern int fonts_loaded; +extern int sc_history_size; +extern u_char palette[]; +#ifdef PC98 +extern char crtc_type; +#endif /* PC98 */ + +#ifndef PC98 +int +sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, int xsize, int ysize, + int fontsize) +{ + video_adapter_t *adp; + video_info_t info; + int error; + int s; + int i; + + if ((*biosvidsw.get_info)(scp->adp, mode, &info)) + return ENODEV; + adp = get_adapter(scp); + + /* adjust argument values */ + if (fontsize <= 0) + fontsize = info.vi_cheight; + if (fontsize < 14) { + fontsize = 8; + if (!(fonts_loaded & FONT_8)) + return EINVAL; + } else if (fontsize >= 16) { + fontsize = 16; + if (!(fonts_loaded & FONT_16)) + return EINVAL; + } else { + fontsize = 14; + if (!(fonts_loaded & FONT_14)) + return EINVAL; + } + if ((xsize <= 0) || (xsize > info.vi_width)) + xsize = info.vi_width; + if ((ysize <= 0) || (ysize > info.vi_height)) + ysize = info.vi_height; + + /* stop screen saver, etc */ + s = spltty(); + if ((error = sc_clean_up(scp))) { + splx(s); + return error; + } + + /* set up scp */ + if (scp->history != NULL) + i = imax(scp->history_size / scp->xsize + - imax(sc_history_size, scp->ysize), 0); + else + i = 0; + /* + * This is a kludge to fend off scrn_update() while we + * muck around with scp. XXX + */ + scp->status |= UNKNOWN_MODE; + scp->status &= ~(GRAPHICS_MODE | PIXEL_MODE); + scp->mode = mode; + scp->font_size = fontsize; + scp->xsize = xsize; + scp->ysize = ysize; + scp->xpixel = scp->xsize*8; + scp->ypixel = scp->ysize*fontsize; + + /* allocate buffers */ + sc_alloc_scr_buffer(scp, TRUE, TRUE); + if (ISMOUSEAVAIL(adp->va_flags)) + sc_alloc_cut_buffer(scp, FALSE); + sc_alloc_history_buffer(scp, sc_history_size, i, FALSE); + splx(s); + + if (scp == cur_console) + set_mode(scp); + scp->status &= ~UNKNOWN_MODE; + + if (tp == NULL) + return 0; + if (tp->t_winsize.ws_col != scp->xsize + || tp->t_winsize.ws_row != scp->ysize) { + tp->t_winsize.ws_col = scp->xsize; + tp->t_winsize.ws_row = scp->ysize; + pgsignal(tp->t_pgrp, SIGWINCH, 1); + } + + return 0; +} +#endif /* PC98 */ + +#ifndef PC98 +int +sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode) +{ + video_adapter_t *adp; + video_info_t info; + int error; + int s; + + if ((*biosvidsw.get_info)(scp->adp, mode, &info)) + return ENODEV; + adp = get_adapter(scp); + + /* stop screen saver, etc */ + s = spltty(); + if ((error = sc_clean_up(scp))) { + splx(s); + return error; + } + + /* set up scp */ + scp->status |= (UNKNOWN_MODE | GRAPHICS_MODE); + scp->status &= ~PIXEL_MODE; + scp->mode = mode; + scp->xpixel = info.vi_width; + scp->ypixel = info.vi_height; + scp->xsize = info.vi_width/8; + scp->ysize = info.vi_height/info.vi_cheight; + scp->font_size = FONT_NONE; + /* move the mouse cursor at the center of the screen */ + sc_move_mouse(scp, scp->xpixel / 2, scp->ypixel / 2); + splx(s); + + if (scp == cur_console) + set_mode(scp); + /* clear_graphics();*/ + scp->status &= ~UNKNOWN_MODE; + + if (tp == NULL) + return 0; + if (tp->t_winsize.ws_xpixel != scp->xpixel + || tp->t_winsize.ws_ypixel != scp->ypixel) { + tp->t_winsize.ws_xpixel = scp->xpixel; + tp->t_winsize.ws_ypixel = scp->ypixel; + pgsignal(tp->t_pgrp, SIGWINCH, 1); + } + + return 0; +} +#endif /* PC98 */ + +#ifndef PC98 +int +sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize, + int fontsize) +{ + video_adapter_t *adp; + video_info_t info; + int error; + int s; + int i; + + if ((*biosvidsw.get_info)(scp->adp, scp->mode, &info)) + return ENODEV; /* this shouldn't happen */ + adp = get_adapter(scp); + +#ifdef SC_VIDEO_DEBUG + if (scp->scr_buf != NULL) { + printf("set_pixel_mode(): mode:%x, col:%d, row:%d, font:%d\n", + scp->mode, xsize, ysize, fontsize); + } +#endif + + /* adjust argument values */ + if ((fontsize <= 0) || (fontsize == FONT_NONE)) + fontsize = info.vi_cheight; + if (fontsize < 14) { + fontsize = 8; + if (!(fonts_loaded & FONT_8)) + return EINVAL; + } else if (fontsize >= 16) { + fontsize = 16; + if (!(fonts_loaded & FONT_16)) + return EINVAL; + } else { + fontsize = 14; + if (!(fonts_loaded & FONT_14)) + return EINVAL; + } + if (xsize <= 0) + xsize = info.vi_width/8; + if (ysize <= 0) + ysize = info.vi_height/fontsize; + +#ifdef SC_VIDEO_DEBUG + if (scp->scr_buf != NULL) { + printf("set_pixel_mode(): mode:%x, col:%d, row:%d, font:%d\n", + scp->mode, xsize, ysize, fontsize); + printf("set_pixel_mode(): window:%x, %dx%d, xoff:%d, yoff:%d\n", + adp->va_window, info.vi_width, info.vi_height, + (info.vi_width/8 - xsize)/2, + (info.vi_height/fontsize - ysize)/2); + } +#endif + + if ((info.vi_width < xsize*8) || (info.vi_height < ysize*fontsize)) + return EINVAL; + + /* only 16 color, 4 plane modes are supported XXX */ + if ((info.vi_depth != 4) || (info.vi_planes != 4)) + return ENODEV; + + /* + * set_pixel_mode() currently does not support video modes whose + * memory size is larger than 64K. Because such modes require + * bank switching to access the entire screen. XXX + */ + if (info.vi_width*info.vi_height/8 > info.vi_window_size) + return ENODEV; + + /* stop screen saver, etc */ + s = spltty(); + if ((error = sc_clean_up(scp))) { + splx(s); + return error; + } + + /* set up scp */ + if (scp->history != NULL) + i = imax(scp->history_size / scp->xsize + - imax(sc_history_size, scp->ysize), 0); + else + i = 0; + scp->status |= (UNKNOWN_MODE | PIXEL_MODE); + scp->status &= ~(GRAPHICS_MODE | MOUSE_ENABLED); + scp->xsize = xsize; + scp->ysize = ysize; + scp->font_size = fontsize; + scp->xoff = (scp->xpixel/8 - xsize)/2; + scp->yoff = (scp->ypixel/fontsize - ysize)/2; + + /* allocate buffers */ + sc_alloc_scr_buffer(scp, TRUE, TRUE); + if (ISMOUSEAVAIL(adp->va_flags)) + sc_alloc_cut_buffer(scp, FALSE); + sc_alloc_history_buffer(scp, sc_history_size, i, FALSE); + splx(s); + + if (scp == cur_console) + set_border(scp, scp->border); + + scp->status &= ~UNKNOWN_MODE; + +#ifdef SC_VIDEO_DEBUG + printf("set_pixel_mode(): status:%x\n", scp->status); +#endif + + if (tp == NULL) + return 0; + if (tp->t_winsize.ws_col != scp->xsize + || tp->t_winsize.ws_row != scp->ysize) { + tp->t_winsize.ws_col = scp->xsize; + tp->t_winsize.ws_row = scp->ysize; + pgsignal(tp->t_pgrp, SIGWINCH, 1); + } + + return 0; +} +#endif /* PC98 */ + +int +sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p) +{ + scr_stat *scp; +#ifndef PC98 + video_adapter_t *adp; +#endif + int error; + int s; + + scp = sc_get_scr_stat(tp->t_dev); + + switch (cmd) { + + case CONS_CURRENT: /* get current adapter type */ +#ifdef PC98 + *(int *)data = crtc_type; +#else /* PC98 */ + adp = get_adapter(scp); + *(int *)data = adp->va_type; +#endif /* PC98 */ + return 0; + +#ifndef PC98 + case CONS_CURRENTADP: /* get current adapter index */ + *(int *)data = scp->adp; + return 0; + + case CONS_ADPINFO: /* adapter information */ + adp = (*biosvidsw.adapter)(((video_adapter_t *)data)->va_index); + if (adp == NULL) + return ENODEV; + bcopy(adp, data, sizeof(*adp)); + return 0; +#endif /* PC98 */ + + case CONS_GET: /* get current video mode */ + *(int *)data = scp->mode; + return 0; + +#ifndef PC98 + case CONS_MODEINFO: /* get mode information */ + return ((*biosvidsw.get_info)(scp->adp, + ((video_info_t *)data)->vi_mode, (video_info_t *)data) + ? ENODEV : 0); + + case CONS_FINDMODE: /* find a matching video mode */ + return ((*biosvidsw.query_mode)(scp->adp, (video_info_t *)data) + ? ENODEV : 0); + + case CONS_SETWINORG: + return ((*biosvidsw.set_win_org)(scp->adp, *(u_int *)data) + ? ENODEV : 0); +#endif /* PC98 */ + +#ifndef PC98 + /* generic text modes */ + case SW_TEXT_80x25: case SW_TEXT_80x30: + case SW_TEXT_80x43: case SW_TEXT_80x50: + case SW_TEXT_80x60: + /* FALL THROUGH */ + + /* VGA TEXT MODES */ + case SW_VGA_C40x25: + case SW_VGA_C80x25: case SW_VGA_M80x25: + case SW_VGA_C80x30: case SW_VGA_M80x30: + case SW_VGA_C80x50: case SW_VGA_M80x50: + case SW_VGA_C80x60: case SW_VGA_M80x60: + case SW_B40x25: case SW_C40x25: + case SW_B80x25: case SW_C80x25: + case SW_ENH_B40x25: case SW_ENH_C40x25: + case SW_ENH_B80x25: case SW_ENH_C80x25: + case SW_ENH_B80x43: case SW_ENH_C80x43: + case SW_EGAMONO80x25: + adp = get_adapter(scp); + if (!(adp->va_flags & V_ADP_MODECHANGE)) + return ENODEV; + return sc_set_text_mode(scp, tp, cmd & 0xff, 0, 0, 0); + + /* GRAPHICS MODES */ + case SW_BG320: case SW_BG640: + case SW_CG320: case SW_CG320_D: case SW_CG640_E: + case SW_CG640x350: case SW_ENH_CG640: + case SW_BG640x480: case SW_CG640x480: case SW_VGA_CG320: + case SW_VGA_MODEX: + adp = get_adapter(scp); + if (!(adp->va_flags & V_ADP_MODECHANGE)) + return ENODEV; + return sc_set_graphics_mode(scp, tp, cmd & 0xff); + +#endif /* PC98 */ + case KDSETMODE: /* set current mode of this (virtual) console */ + switch (*(int *)data) { +#ifndef PC98 + case KD_TEXT: /* switch to TEXT (known) mode */ + /* + * If scp->mode is of graphics modes, we don't know which + * text mode to switch back to... + */ + if (scp->status & GRAPHICS_MODE) + return EINVAL; + /* restore fonts & palette ! */ +#if 0 + adp = get_adapter(scp); + if (ISFONTAVAIL(adp->va_flags) + && !(scp->status & (GRAPHICS_MODE | PIXEL_MODE))) + /* + * FONT KLUDGE + * Don't load fonts for now... XXX + */ + if (fonts_loaded & FONT_8) + copy_font(scp, LOAD, 8, font_8); + if (fonts_loaded & FONT_14) + copy_font(scp, LOAD, 14, font_14); + if (fonts_loaded & FONT_16) + copy_font(scp, LOAD, 16, font_16); + } +#endif + load_palette(scp, palette); + + /* move hardware cursor out of the way */ + (*biosvidsw.set_hw_cursor)(scp->adp, -1, -1); + + /* FALL THROUGH */ +#endif + case KD_TEXT1: /* switch to TEXT (known) mode */ + /* + * If scp->mode is of graphics modes, we don't know which + * text/pixel mode to switch back to... + */ + if (scp->status & GRAPHICS_MODE) + return EINVAL; + s = spltty(); + if ((error = sc_clean_up(scp))) { + splx(s); + return error; + } + scp->status |= UNKNOWN_MODE; + splx(s); + /* no restore fonts & palette */ +#ifdef PC98 + scp->status &= ~UNKNOWN_MODE; +#else + if (scp == cur_console) +#endif + set_mode(scp); + sc_clear_screen(scp); + scp->status &= ~UNKNOWN_MODE; + return 0; + +#ifndef PC98 + case KD_PIXEL: /* pixel (raster) display */ + if (!(scp->status & (GRAPHICS_MODE | PIXEL_MODE))) + return EINVAL; + if (scp->status & GRAPHICS_MODE) + return sc_set_pixel_mode(scp, tp, scp->xsize, scp->ysize, + scp->font_size); + s = spltty(); + if ((error = sc_clean_up(scp))) { + splx(s); + return error; + } + scp->status |= (UNKNOWN_MODE | PIXEL_MODE); + splx(s); + if (scp == cur_console) { + set_mode(scp); + load_palette(scp, palette); + } + sc_clear_screen(scp); + scp->status &= ~UNKNOWN_MODE; + return 0; +#endif /* PC98 */ + + case KD_GRAPHICS: /* switch to GRAPHICS (unknown) mode */ + s = spltty(); + if ((error = sc_clean_up(scp))) { + splx(s); + return error; + } + scp->status |= UNKNOWN_MODE; +#ifdef PC98 + set_mode(scp); +#endif + splx(s); + return 0; + + default: + return EINVAL; + } + /* NOT REACHED */ + +#ifndef PC98 + 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 /* PC98 */ + + case KDGETMODE: /* get current mode of this (virtual) console */ + /* + * From the user program's point of view, KD_PIXEL is the same + * as KD_TEXT... + */ + *data = ISGRAPHSC(scp) ? KD_GRAPHICS : KD_TEXT; + return 0; + + case KDSBORDER: /* set border color of this (virtual) console */ + scp->border = *data; + if (scp == cur_console) + set_border(cur_console, scp->border); + return 0; + } + + return ENOIOCTL; +} + +#endif /* NSC > 0 */ diff --git a/sys/pc98/pc98/syscons.c b/sys/pc98/pc98/syscons.c index 18e6515..f71f45d 100644 --- a/sys/pc98/pc98/syscons.c +++ b/sys/pc98/pc98/syscons.c @@ -1,18 +1,18 @@ /*- - * Copyright (c) 1992-1995 Sen Schmidt + * Copyright (c) 1992-1998 Sen Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. + * notice, this list of conditions and the following disclaimer, + * without modification, immediately at the beginning of the file. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products - * derived from this software withough specific prior written permission + * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES @@ -25,13 +25,15 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: syscons.c,v 1.102 1998/10/22 05:58:45 bde Exp $ + * $Id: syscons.c,v 1.103 1998/11/08 12:39:05 dfr Exp $ */ #include "sc.h" #include "apm.h" #include "opt_ddb.h" #include "opt_devfs.h" +#include "opt_vesa.h" +#include "opt_vm86.h" #include "opt_syscons.h" #if NSC > 0 @@ -57,9 +59,9 @@ #include #include #include +#include #include #include -#include #include #include @@ -73,6 +75,7 @@ #include #include #include +#include #include #else #include @@ -80,6 +83,7 @@ #include #include #include +#include #include #endif /* PC98 */ @@ -111,11 +115,6 @@ #define COLD 0 #define WARM 1 -#define VESA_MODE(x) ((x) >= M_VESA_BASE) - -#define MODE_MAP_SIZE (M_VGA_CG320 + 1) -#define MODE_PARAM_SIZE 64 - #define DEFAULT_BLANKTIME (5*60) /* 5 minutes */ #define MAX_BLANKTIME (7*24*60*60) /* 7 days!? */ @@ -138,6 +137,7 @@ typedef struct old_mouse_info { /* XXX use sc_bcopy where video memory is concerned */ extern void generic_bcopy(const void *, void *, size_t); +extern void generic_bzero(void *, size_t); static default_attr user_default = { (FG_LIGHTGREY | BG_BLACK) << 8, @@ -167,7 +167,7 @@ static void *sc_console_devfs_token; static scr_stat *new_scp, *old_scp; static term_stat kernel_console; static default_attr *current_default; -static int flags = 0; +static int sc_flags; static int sc_port = IO_KBD; static KBDC sc_kbdc = NULL; static char init_done = COLD; @@ -182,7 +182,8 @@ static int blinkrate = 0; u_int crtc_addr = MONO_BASE; #endif char crtc_type = KD_MONO; - char crtc_vga = FALSE; +static char crtc_vga = FALSE; +static int adp_flags; static u_char shfts = 0, ctls = 0, alts = 0, agrs = 0, metas = 0; static u_char accents = 0; #ifdef PC98 @@ -200,29 +201,28 @@ static int run_scrn_saver = FALSE; /* should run the saver? */ static int scrn_idle = FALSE; /* about to run the saver */ u_char scr_map[256]; u_char scr_rmap[256]; - char *video_mode_ptr = NULL; +#ifndef PC98 +static int initial_video_mode; /* initial video mode # */ static int bios_video_mode; /* video mode # set by BIOS */ +#endif int fonts_loaded = 0 #ifdef STD8X16FONT | FONT_16 #endif ; - char font_8[256*8]; - char font_14[256*14]; + u_char font_8[256*8]; + u_char font_14[256*14]; #ifdef STD8X16FONT extern #endif - unsigned char font_16[256*16]; - char palette[256*3]; -static char *mode_map[MODE_MAP_SIZE]; -static char vgaregs[MODE_PARAM_SIZE]; -static char vgaregs2[MODE_PARAM_SIZE]; -static int rows_offset = 1; -static char *cut_buffer; + 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 = 0; /* sysmouse protocol level */ +static int mouse_level; /* sysmouse protocol level */ static mousestatus_t mouse_status = { 0, 0, 0, 0, 0, 0 }; +#ifndef PC98 static u_short mouse_and_mask[16] = { 0xc000, 0xe000, 0xf000, 0xf800, 0xfc00, 0xfe00, 0xff00, 0xff80, @@ -235,15 +235,16 @@ static u_short mouse_or_mask[16] = { 0x0c00, 0x0c00, 0x0600, 0x0600, 0x0000, 0x0000, 0x0000, 0x0000 }; +#endif -static int extra_history_size = + int sc_history_size = SC_HISTORY_SIZE; +static int extra_history_size = SC_MAX_HISTORY_SIZE - SC_HISTORY_SIZE * MAXCONS; static void none_saver(int blank) { } static void (*current_saver)(int blank) = none_saver; static void (*default_saver)(int blank) = none_saver; -int (*sc_user_ioctl)(dev_t dev, int cmd, caddr_t data, - int flag, struct proc *p) = NULL; + d_ioctl_t *sc_user_ioctl; static int sticky_splash = FALSE; @@ -261,30 +262,23 @@ static struct tty sccons[MAXCONS+2]; #endif #define SC_MOUSE 128 #define SC_CONSOLE 255 -#ifdef PC98 -static u_char default_kanji = UJIS; u_short *Crtat; +#ifdef PC98 u_short *Atrat; -#else -#define MONO_BUF pa_to_va(0xB0000) -#define CGA_BUF pa_to_va(0xB8000) -u_short *Crtat; +static u_char default_kanji = UJIS; #endif static const int nsccons = MAXCONS+2; #define WRAPHIST(scp, pointer, offset)\ - ((scp->history) + ((((pointer) - (scp->history)) + (scp->history_size)\ - + (offset)) % (scp->history_size))) + ((scp)->history + ((((pointer) - (scp)->history) + (scp)->history_size \ + + (offset)) % (scp)->history_size)) #ifdef PC98 #define WRAPHIST_A(scp, pointer, offset)\ - ((scp->his_atr) + ((((pointer) - (scp->his_atr)) + (scp->history_size)\ - + (offset)) % (scp->history_size))) + ((scp->his_atr) + ((((pointer) - (scp->his_atr)) + (scp)->history_size \ + + (offset)) % (scp)->history_size)) #endif #define ISSIGVALID(sig) ((sig) > 0 && (sig) < NSIG) -/* this should really be in `rtc.h' */ -#define RTC_EQUIPMENT 0x14 - /* prototypes */ static int scattach(struct isa_device *dev); static ointhand2_t scintr; @@ -296,47 +290,35 @@ static void scstart(struct tty *tp); static void scmousestart(struct tty *tp); static void scinit(void); static void scshutdown(int howto, void *arg); -static void map_mode_table(char *map[], char *table, int max); -static int map_mode_num(int mode); -static char *get_mode_param(scr_stat *scp, int mode); static u_int scgetc(u_int flags); #define SCGETC_CN 1 #define SCGETC_NONBLOCK 2 static void sccnupdate(scr_stat *scp); -static scr_stat *get_scr_stat(dev_t dev); static scr_stat *alloc_scp(void); static void init_scp(scr_stat *scp); static void sc_bcopy(scr_stat *scp, u_short *p, int from, int to, int mark); static int get_scr_num(void); static timeout_t scrn_timer; static void scrn_update(scr_stat *scp, int show_cursor); +static void scrn_saver(void (*saver)(int), int blank); static void stop_scrn_saver(void (*saver)(int)); static int wait_scrn_saver_stop(void); -static void clear_screen(scr_stat *scp); static int switch_scr(scr_stat *scp, u_int next_scr); static void exchange_scr(void); -static void move_crsr(scr_stat *scp, int x, int y); static void scan_esc(scr_stat *scp, u_char c); +static void ansi_put(scr_stat *scp, u_char *buf, int len); static void draw_cursor_image(scr_stat *scp); static void remove_cursor_image(scr_stat *scp); -static void ansi_put(scr_stat *scp, u_char *buf, int len); +static void move_crsr(scr_stat *scp, int x, int y); static u_char *get_fstr(u_int c, u_int *len); static void history_to_screen(scr_stat *scp); static int history_up_line(scr_stat *scp); static int history_down_line(scr_stat *scp); static int mask2attr(struct term_stat *term); +#ifndef PC98 static void set_keyboard(int command, int data); +#endif static void update_leds(int which); -static void set_vgaregs(char *modetable); -static void read_vgaregs(char *buf); -#define COMP_IDENTICAL 0 -#define COMP_SIMILAR 1 -#define COMP_DIFFERENT 2 -static int comp_vgaregs(u_char *buf1, u_char *buf2); -static void dump_vgaregs(u_char *buf); -#define PARAM_BUFSIZE 6 -static void set_font_mode(u_char *buf); -static void set_normal_mode(u_char *buf); static void set_destructive_cursor(scr_stat *scp); static void set_mouse_pos(scr_stat *scp); static int skip_spc_right(scr_stat *scp, u_short *p); @@ -352,12 +334,12 @@ static void draw_mouse_image(scr_stat *scp); static void remove_mouse_image(scr_stat *scp); static void draw_cutmarking(scr_stat *scp); static void remove_cutmarking(scr_stat *scp); -static void save_palette(void); static void do_bell(scr_stat *scp, int pitch, int duration); static timeout_t blink_screen; #ifdef SC_SPLASH_SCREEN -static void scsplash_init(void); -static void scsplash(int show); +static void scsplash_init(scr_stat *scp); +static void scsplash_term(scr_stat *scp); +static void scsplash_saver(int show); #define scsplash_stick(stick) (sticky_splash = (stick)) #else #define scsplash_stick(stick) @@ -372,7 +354,6 @@ static d_close_t scclose; static d_read_t scread; static d_write_t scwrite; static d_ioctl_t scioctl; -static d_devtotty_t scdevtotty; static d_mmap_t scmmap; #define CDEV_MAJOR 12 @@ -421,14 +402,15 @@ at2pc98(unsigned int attr) } #endif -/* - * These functions need to be before calls to them so they can be inlined. - */ static void draw_cursor_image(scr_stat *scp) { - u_short cursor_image, *ptr; +#ifndef PC98 + u_short cursor_image; + u_short *ptr; u_short prev_image; +#endif + #ifdef PC98 int pos = scp->cursor_pos - scp->scr_buf; while((inb(TEXT_GDC + 0) & 0x04) == 0) {} @@ -436,16 +418,17 @@ draw_cursor_image(scr_stat *scp) outb(TEXT_GDC + 0, pos & 0xff); /* EADl */ outb(TEXT_GDC + 0, pos >> 8); /* EADh */ #else - ptr = Crtat + (scp->cursor_pos - scp->scr_buf); - - if (VESA_MODE(scp->mode)) { + if (ISPIXELSC(scp)) { sc_bcopy(scp, scp->scr_buf, scp->cursor_pos - scp->scr_buf, scp->cursor_pos - scp->scr_buf, 1); return; } + ptr = (u_short *)(get_adapter(scp)->va_window) + + (scp->cursor_pos - scp->scr_buf); + /* do we have a destructive cursor ? */ - if (flags & CHAR_CURSOR) { + if (sc_flags & CHAR_CURSOR) { prev_image = scp->cursor_saveunder; cursor_image = *ptr & 0x00ff; if (cursor_image == DEAD_CHAR) @@ -456,7 +439,7 @@ draw_cursor_image(scr_stat *scp) if (prev_image != cursor_image) set_destructive_cursor(scp); /* modify cursor_image */ - if (!(flags & BLINK_CURSOR)||((flags & BLINK_CURSOR)&&(blinkrate & 4))){ + 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 @@ -472,7 +455,7 @@ draw_cursor_image(scr_stat *scp) } else { cursor_image = (*(ptr) & 0x00ff) | *(scp->cursor_pos) & 0xff00; scp->cursor_saveunder = cursor_image; - if (!(flags & BLINK_CURSOR)||((flags & BLINK_CURSOR)&&(blinkrate & 4))){ + if (!(sc_flags & BLINK_CURSOR)||((sc_flags & BLINK_CURSOR)&&(blinkrate & 4))){ if ((cursor_image & 0x7000) == 0x7000) { cursor_image &= 0x8fff; if(!(cursor_image & 0x0700)) @@ -492,11 +475,13 @@ static void remove_cursor_image(scr_stat *scp) { #ifndef PC98 - if (VESA_MODE(scp->mode)) + if (ISPIXELSC(scp)) sc_bcopy(scp, scp->scr_buf, scp->cursor_oldpos - scp->scr_buf, - scp->cursor_oldpos - scp->scr_buf, 0); + scp->cursor_oldpos - scp->scr_buf, 0); else - *(Crtat + (scp->cursor_oldpos - scp->scr_buf)) = scp->cursor_saveunder; + *((u_short *)(get_adapter(scp)->va_window) + + (scp->cursor_oldpos - scp->scr_buf)) + = scp->cursor_saveunder; #endif } @@ -528,6 +513,15 @@ scprobe(struct isa_device *dev) return (0); } +#ifndef PC98 +#if defined(VESA) && defined(VM86) + if (vesa_load()) + return FALSE; +#endif + + (*biosvidsw.diag)(bootverbose); +#endif /* PC98 */ + sc_port = dev->id_iobase; if (sckbdprobe(dev->id_unit, dev->id_flags)) return (IO_KBDSIZE); @@ -539,104 +533,32 @@ scprobe(struct isa_device *dev) static int scvidprobe(int unit, int flags) { - /* - * XXX don't try to `printf' anything here, the console may not have - * been configured yet. - */ - u_short volatile *cp; - u_short was; - u_int pa; - u_int segoff; +#ifndef PC98 + video_adapter_t *adp; +#endif /* do this test only once */ if (init_done != COLD) - return (Crtat != 0); + return (crtc_type != -1); - /* - * Finish defaulting crtc variables for a mono screen. Crtat is a - * bogus common variable so that it can be shared with pcvt, so it - * can't be statically initialized. XXX. - */ #ifdef PC98 Crtat = (u_short *)TEXT_VRAM; Atrat = (u_short *)TEXT_VRAM + ATTR_OFFSET; crtc_type = KD_PC98; #else - Crtat = (u_short *)MONO_BUF; - crtc_type = KD_MONO; - /* If CGA memory seems to work, switch to color. */ - cp = (u_short *)CGA_BUF; - was = *cp; - *cp = (u_short) 0xA55A; - bios_video_mode = *(u_char *)pa_to_va(0x449); - if (bootinfo.bi_vesa == 0x102) { - bios_video_mode = bootinfo.bi_vesa; - Crtat = (u_short *)pa_to_va(0xA0000); - crtc_addr = COLOR_BASE; - crtc_type = KD_VGA; - bzero(Crtat, 800*600/8); - } else if (*cp == 0xA55A) { - Crtat = (u_short *)CGA_BUF; - crtc_addr = COLOR_BASE; - crtc_type = KD_CGA; - } else { - cp = Crtat; - was = *cp; - *cp = (u_short) 0xA55A; - if (*cp != 0xA55A) { - /* no screen at all, bail out */ - Crtat = 0; - return FALSE; - } - } - *cp = was; - - if (!VESA_MODE(bios_video_mode)) { - /* - * Check rtc and BIOS date area. - * XXX: don't use BIOSDATA_EQUIPMENT, it is not a dead copy - * of RTC_EQUIPMENT. The bit 4 and 5 of the ETC_EQUIPMENT are - * zeros for EGA and VGA. However, the EGA/VGA BIOS will set - * these bits in BIOSDATA_EQUIPMENT according to the monitor - * type detected. - */ - switch ((rtcin(RTC_EQUIPMENT) >> 4) & 3) { /* bit 4 and 5 */ - case 0: /* EGA/VGA, or nothing */ - crtc_type = KD_EGA; - /* the color adapter may be in the 40x25 mode... XXX */ - break; - case 1: /* CGA 40x25 */ - /* switch to the 80x25 mode? XXX */ - /* FALL THROUGH */ - case 2: /* CGA 80x25 */ - /* `crtc_type' has already been set... */ - /* crtc_type = KD_CGA; */ - break; - case 3: /* MDA */ - /* `crtc_type' has already been set... */ - /* crtc_type = KD_MONO; */ - break; - } + if ((*biosvidsw.init)() <= 0) + return FALSE; + if ((adp = (*biosvidsw.adapter)(V_ADP_PRIMARY)) == NULL) + return FALSE; + + crtc_type = adp->va_type; + crtc_vga = (crtc_type == KD_VGA); + crtc_addr = adp->va_crtc_addr; + Crtat = (u_short *)adp->va_window; + adp_flags = adp->va_flags; + initial_video_mode = adp->va_initial_mode; + bios_video_mode = adp->va_initial_bios_mode; - /* is this a VGA or higher ? */ - outb(crtc_addr, 7); - if (inb(crtc_addr) == 7) { - - crtc_type = KD_VGA; - crtc_vga = TRUE; - read_vgaregs(vgaregs); - - /* Get the BIOS video mode pointer */ - segoff = *(u_int *)pa_to_va(0x4a8); - pa = ((segoff & 0xffff0000) >> 12) + (segoff & 0xffff); - if (ISMAPPED(pa, sizeof(u_int))) { - segoff = *(u_int *)pa_to_va(pa); - pa = ((segoff & 0xffff0000) >> 12) + (segoff & 0xffff); - if (ISMAPPED(pa, MODE_PARAM_SIZE)) - video_mode_ptr = (char *)pa_to_va(pa); - } - } - } #endif /* PC98 */ return TRUE; } @@ -645,10 +567,12 @@ scvidprobe(int unit, int flags) static int sckbdprobe(int unit, int flags) { +#ifndef PC98 int codeset; int c = -1; int m; int res, id; +#endif sc_kbdc = kbdc_open(sc_port); #ifndef PC98 @@ -658,7 +582,7 @@ sckbdprobe(int unit, int flags) return ((flags & DETECT_KBD) ? FALSE : TRUE); } - /* discard anything left after UserConfig */ + /* flush any noise in the buffer */ empty_both_buffers(sc_kbdc, 10); /* save the current keyboard controller command byte */ @@ -826,68 +750,59 @@ static int scattach(struct isa_device *dev) { scr_stat *scp; +#ifndef PC98 + video_info_t info; +#endif dev_t cdev = makedev(CDEV_MAJOR, 0); - char *p; #ifdef DEVFS int vc; #endif dev->id_ointr = scintr; scinit(); - flags = dev->id_flags; - if (crtc_type != KD_VGA || VESA_MODE(bios_video_mode)) - flags &= ~CHAR_CURSOR; + sc_flags = dev->id_flags; + if (!ISFONTAVAIL(adp_flags)) + sc_flags &= ~CHAR_CURSOR; scp = console[0]; - if (crtc_type == KD_VGA) { - cut_buffer_size = scp->xsize * scp->ysize + 1; - cut_buffer = (char *)malloc(cut_buffer_size, M_DEVBUF, M_NOWAIT); - if (cut_buffer != NULL) - cut_buffer[0] = '\0'; - } - - scp->scr_buf = (u_short *)malloc(scp->xsize*scp->ysize*sizeof(u_short), - M_DEVBUF, M_NOWAIT); -#ifdef PC98 - scp->atr_buf = (u_short *)malloc(scp->xsize*scp->ysize*sizeof(u_short), - M_DEVBUF, M_NOWAIT); -#endif - /* copy temporary buffer to final buffer */ - bcopy(sc_buffer, scp->scr_buf, scp->xsize * scp->ysize * sizeof(u_short)); - + scp->scr_buf = NULL; #ifdef PC98 - bcopy(Atrat, scp->atr_buf, scp->xsize * scp->ysize * sizeof(u_short)); + scp->atr_buf = NULL; #endif - scp->cursor_pos = scp->cursor_oldpos = - scp->scr_buf + scp->xpos + scp->ypos * scp->xsize; + sc_alloc_scr_buffer(scp, FALSE, FALSE); + bcopy(sc_buffer, scp->scr_buf, scp->xsize*scp->ysize*sizeof(u_short)); #ifdef PC98 - scp->cursor_atr = - scp->atr_buf + scp->xpos + scp->ypos * scp->xsize; + bcopy(Atrat, scp->atr_buf, scp->xsize*scp->ysize*sizeof(u_short)); #endif - scp->mouse_pos = scp->mouse_oldpos = - scp->scr_buf + ((scp->mouse_ypos/scp->font_size)*scp->xsize + - scp->mouse_xpos/8); + + /* cut buffer is available only when the mouse pointer is used */ + if (ISMOUSEAVAIL(adp_flags)) + sc_alloc_cut_buffer(scp, FALSE); /* initialize history buffer & pointers */ - scp->history_head = scp->history_pos = - (u_short *)malloc(scp->history_size*sizeof(u_short), - M_DEVBUF, M_NOWAIT); - if (scp->history_head != NULL) - bzero(scp->history_head, scp->history_size*sizeof(u_short)); - scp->history = scp->history_head; -#ifdef PC98 - scp->his_atr_head = scp->his_atr_pos = - (u_short *)malloc(scp->history_size*sizeof(u_short), - M_DEVBUF, M_NOWAIT); - if (scp->his_atr_head != NULL) - bzero(scp->his_atr_head, scp->history_size*sizeof(u_short)); - scp->his_atr = scp->his_atr_pos; + sc_alloc_history_buffer(scp, sc_history_size, 0, FALSE); + +#ifndef PC98 +#if defined(VESA) && defined(VM86) + if ((sc_flags & VESA800X600) + && ((*biosvidsw.get_info)(scp->adp, M_VESA_800x600, &info) == 0)) { +#ifdef SC_SPLASH_SCREEN + scsplash_term(scp); #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; +#ifdef SC_SPLASH_SCREEN + scsplash_init(scp); +#endif + } +#endif /* VESA && VM86 */ +#endif /* PC98 */ /* initialize cursor stuff */ - if (!(scp->status & UNKNOWN_MODE)) + if (!ISGRAPHSC(scp)) draw_cursor_image(scp); /* get screen update going */ @@ -895,29 +810,6 @@ scattach(struct isa_device *dev) update_leds(scp->status); -#ifndef PC98 - if ((crtc_type == KD_VGA) && bootverbose) { - printf("sc%d: BIOS video mode:%d\n", dev->id_unit, bios_video_mode); - printf("sc%d: VGA registers upon power-up\n", dev->id_unit); - dump_vgaregs(vgaregs); - printf("sc%d: video mode:%d\n", dev->id_unit, scp->mode); - printf("sc%d: VGA registers in BIOS for mode:%d\n", - dev->id_unit, scp->mode); - dump_vgaregs(vgaregs2); - p = get_mode_param(scp, scp->mode); - if (p != NULL) { - printf("sc%d: VGA registers to be used for mode:%d\n", - dev->id_unit, scp->mode); - dump_vgaregs(p); - } - printf("sc%d: rows_offset:%d\n", dev->id_unit, rows_offset); - } - if ((crtc_type == KD_VGA) && !VESA_MODE(bios_video_mode) - && (video_mode_ptr == NULL)) - printf("sc%d: WARNING: video mode switching is only partially supported\n", - dev->id_unit); -#endif - printf("sc%d: ", dev->id_unit); switch(crtc_type) { #ifdef PC98 @@ -926,18 +818,10 @@ scattach(struct isa_device *dev) break; #else case KD_VGA: - if (VESA_MODE(bios_video_mode)) - printf("Graphics display (VESA mode = 0x%x)", bios_video_mode); - else if (crtc_addr == MONO_BASE) - printf("VGA mono"); - else - printf("VGA color"); + printf("VGA %s", (adp_flags & V_ADP_COLOR) ? "color" : "mono"); break; case KD_EGA: - if (crtc_addr == MONO_BASE) - printf("EGA mono"); - else - printf("EGA color"); + printf("EGA %s", (adp_flags & V_ADP_COLOR) ? "color" : "mono"); break; case KD_CGA: printf("CGA"); @@ -945,11 +829,11 @@ scattach(struct isa_device *dev) case KD_MONO: case KD_HERCULES: default: - printf("MDA/hercules"); + printf("MDA/Hercules"); break; #endif /* PC98 */ } - printf(" <%d virtual consoles, flags=0x%x>\n", MAXCONS, flags); + printf(" <%d virtual consoles, flags=0x%x>\n", MAXCONS, sc_flags); #if NAPM > 0 scp->r_hook.ah_fun = scresume; @@ -1022,6 +906,10 @@ scopen(dev_t dev, int flag, int mode, struct proc *p) return(EBUSY); if (minor(dev) < MAXCONS && !console[minor(dev)]) { console[minor(dev)] = alloc_scp(); +#ifndef PC98 + if (ISGRAPHSC(console[minor(dev)])) + sc_set_pixel_mode(console[minor(dev)], NULL, COL, ROW, 16); +#endif /* PC98 */ } if (minor(dev)t_winsize.ws_col && !tp->t_winsize.ws_row) { tp->t_winsize.ws_col = console[minor(dev)]->xsize; @@ -1039,7 +927,7 @@ scclose(dev_t dev, int flag, int mode, struct proc *p) if (!tp) return(ENXIO); if (minor(dev) < MAXCONS) { - scp = get_scr_stat(tp->t_dev); + scp = sc_get_scr_stat(tp->t_dev); if (scp->status & SWITCH_WAIT_ACQ) wakeup((caddr_t)&scp->smode); #if not_yet_done @@ -1058,9 +946,9 @@ scclose(dev_t dev, int flag, int mode, struct proc *p) if (scp->history != NULL) { free(scp->history, M_DEVBUF); if (scp->history_size / scp->xsize - > imax(SC_HISTORY_SIZE, scp->ysize)) + > imax(sc_history_size, scp->ysize)) extra_history_size += scp->history_size / scp->xsize - - imax(SC_HISTORY_SIZE, scp->ysize); + - imax(sc_history_size, scp->ysize); } free(scp, M_DEVBUF); console[minor(dev)] = NULL; @@ -1139,10 +1027,17 @@ scintr(int unit) } } +#if 0 if (cur_console->status & MOUSE_ENABLED) { cur_console->status &= ~MOUSE_VISIBLE; remove_mouse_image(cur_console); } +#else + if (cur_console->status & MOUSE_VISIBLE) { + remove_mouse_image(cur_console); + cur_console->status &= ~MOUSE_VISIBLE; + } +#endif } static int @@ -1157,28 +1052,32 @@ 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; - u_int i; + int i; struct tty *tp; scr_stat *scp; - u_short *usp; -#ifdef PC98 - u_short *atr_usp; +#ifndef PC98 + video_adapter_t *adp; #endif - char *mp; int s; tp = scdevtotty(dev); if (!tp) return ENXIO; - scp = get_scr_stat(tp->t_dev); + scp = sc_get_scr_stat(tp->t_dev); /* If there is a user_ioctl function call that first */ if (sc_user_ioctl) { - if (error = (*sc_user_ioctl)(dev, cmd, data, flag, p)) + error = (*sc_user_ioctl)(dev, cmd, data, flag, p); + if (error != ENOIOCTL) return error; } + error = sc_vid_ioctl(tp, cmd, data, flag, p); + if (error != ENOIOCTL) + return error; + switch (cmd) { /* process console hardware related ioctl's */ case GIO_ATTR: /* get current attributes */ @@ -1189,21 +1088,10 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) #ifdef PC98 *(int*)data = 0; #else - if (crtc_addr == COLOR_BASE) - *(int*)data = 1; - else - *(int*)data = 0; + *(int *)data = (adp_flags & V_ADP_COLOR) ? 1 : 0; #endif return 0; - case CONS_CURRENT: /* get current adapter type */ - *(int *)data = crtc_type; - return 0; - - case CONS_GET: /* get current video mode */ - *(int*)data = scp->mode; - return 0; - case CONS_BLANKTIME: /* set screen saver timeout (0 = no saver) */ if (*(int *)data < 0 || *(int *)data > MAX_BLANKTIME) return EINVAL; @@ -1215,22 +1103,24 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) case CONS_CURSORTYPE: /* set cursor type blink/noblink */ if ((*(int*)data) & 0x01) - flags |= BLINK_CURSOR; + sc_flags |= BLINK_CURSOR; else - flags &= ~BLINK_CURSOR; + sc_flags &= ~BLINK_CURSOR; if ((*(int*)data) & 0x02) { - if (crtc_type != KD_VGA || VESA_MODE(bios_video_mode)) +#ifndef PC98 + if (!ISFONTAVAIL(get_adapter(scp)->va_flags)) return ENXIO; - flags |= CHAR_CURSOR; +#endif /* PC98 */ + sc_flags |= CHAR_CURSOR; } else - flags &= ~CHAR_CURSOR; + sc_flags &= ~CHAR_CURSOR; /* * The cursor shape is global property; all virtual consoles * are affected. Update the cursor in the current console... */ - if (!(cur_console->status & UNKNOWN_MODE)) { + if (!ISGRAPHSC(cur_console)) { remove_cursor_image(cur_console); - if (flags & CHAR_CURSOR) + if (sc_flags & CHAR_CURSOR) set_destructive_cursor(cur_console); draw_cursor_image(cur_console); } @@ -1238,13 +1128,13 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) case CONS_BELLTYPE: /* set bell type sound/visual */ if ((*(int *)data) & 0x01) - flags |= VISUAL_BELL; + sc_flags |= VISUAL_BELL; else - flags &= ~VISUAL_BELL; + sc_flags &= ~VISUAL_BELL; if ((*(int *)data) & 0x02) - flags |= QUIET_BELL; + sc_flags |= QUIET_BELL; else - flags &= ~QUIET_BELL; + sc_flags &= ~QUIET_BELL; return 0; case CONS_HISTORY: /* set history size */ @@ -1255,50 +1145,22 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) lines = imax(*(int *)data, scp->ysize); lines0 = (scp->history != NULL) ? scp->history_size / scp->xsize : scp->ysize; + if (lines0 > imax(sc_history_size, scp->ysize)) + 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(lines0, SC_HISTORY_SIZE) + extra_history_size) - return EINVAL; + if (lines > imax(sc_history_size, scp->ysize)) + if (lines - imax(sc_history_size, scp->ysize) > + extra_history_size + delta_ehs) + return EINVAL; if (cur_console->status & BUFFER_SAVED) return EBUSY; - usp = scp->history; - scp->history = NULL; - if (usp != NULL) - free(usp, M_DEVBUF); -#ifdef PC98 - atr_usp = scp->his_atr; - scp->his_atr = NULL; - if (atr_usp != NULL) - free(atr_usp, M_DEVBUF); -#endif - scp->history_size = lines * scp->xsize; - /* - * extra_history_size += - * (lines0 > imax(SC_HISTORY_SIZE, scp->ysize)) ? - * lines0 - imax(SC_HISTORY_SIZE, scp->ysize)) : 0; - * extra_history_size -= - * (lines > imax(SC_HISTORY_SIZE, scp->ysize)) ? - * lines - imax(SC_HISTORY_SIZE, scp->ysize)) : 0; - * lines0 >= ysize && lines >= ysize... Hey, the above can be - * reduced to the following... - */ - extra_history_size += - imax(lines0, SC_HISTORY_SIZE) - imax(lines, SC_HISTORY_SIZE); - usp = (u_short *)malloc(scp->history_size * sizeof(u_short), - M_DEVBUF, M_WAITOK); - bzero(usp, scp->history_size * sizeof(u_short)); - scp->history_head = scp->history_pos = usp; - scp->history = usp; -#ifdef PC98 - atr_usp = (u_short *)malloc(scp->history_size * sizeof(u_short), - M_DEVBUF, M_WAITOK); - bzero(atr_usp, scp->history_size * sizeof(u_short)); - scp->his_atr_head = scp->his_atr_pos = atr_usp; - scp->his_atr = atr_usp; -#endif + sc_alloc_history_buffer(scp, lines, delta_ehs, TRUE); return 0; } else @@ -1308,9 +1170,8 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) case OLD_CONS_MOUSECTL: { /* MOUSE_BUTTON?DOWN -> MOUSE_MSC_BUTTON?UP */ - static butmap[8] = { - MOUSE_MSC_BUTTON1UP | MOUSE_MSC_BUTTON2UP - | MOUSE_MSC_BUTTON3UP, + 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, @@ -1322,11 +1183,14 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) mouse_info_t *mouse = (mouse_info_t*)data; mouse_info_t buf; - if (crtc_type != KD_VGA || VESA_MODE(bios_video_mode)) + /* FIXME: */ +#ifndef PC98 + if (!ISMOUSEAVAIL(get_adapter(scp)->va_flags)) return ENODEV; +#endif /* PC98 */ if (cmd == OLD_CONS_MOUSECTL) { - static unsigned char swapb[] = { 0, 4, 2, 6, 1, 5, 3, 7 }; + 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; @@ -1371,7 +1235,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) return 0; case MOUSE_SHOW: - if (!(scp->status & MOUSE_ENABLED)) { + if (ISTEXTSC(scp) && !(scp->status & MOUSE_ENABLED)) { scp->status |= (MOUSE_ENABLED | MOUSE_VISIBLE); scp->mouse_oldpos = scp->mouse_pos; mark_all(scp); @@ -1382,7 +1246,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) break; case MOUSE_HIDE: - if (scp->status & MOUSE_ENABLED) { + if (ISTEXTSC(scp) && (scp->status & MOUSE_ENABLED)) { scp->status &= ~(MOUSE_ENABLED | MOUSE_VISIBLE); mark_all(scp); return 0; @@ -1427,7 +1291,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) if (mouse_status.flags == 0) return 0; - if (cur_console->status & MOUSE_ENABLED) + if (ISTEXTSC(cur_console) && (cur_console->status & MOUSE_ENABLED)) cur_console->status |= MOUSE_VISIBLE; if ((MOUSE_TTY)->t_state & TS_ISOPEN) { @@ -1472,7 +1336,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) else if (mouse->operation == MOUSE_ACTION && cut_buffer != NULL) { /* process button presses */ if ((cur_console->mouse_buttons ^ mouse->u.data.buttons) && - !(cur_console->status & UNKNOWN_MODE)) { + ISTEXTSC(cur_console)) { cur_console->mouse_buttons = mouse->u.data.buttons; if (cur_console->mouse_buttons & MOUSE_BUTTON1DOWN) mouse_cut_start(cur_console); @@ -1509,7 +1373,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) if (mouse_status.flags == 0) return 0; - if (cur_console->status & MOUSE_ENABLED) + if (ISTEXTSC(cur_console) && (cur_console->status & MOUSE_ENABLED)) cur_console->status |= MOUSE_VISIBLE; if ((MOUSE_TTY)->t_state & TS_ISOPEN) { @@ -1538,7 +1402,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) break; } - if ((cur_console->status & UNKNOWN_MODE) || (cut_buffer == NULL)) + if (!ISTEXTSC(cur_console) || (cut_buffer == NULL)) break; switch (mouse->u.event.id) { @@ -1718,18 +1582,41 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) return 0; case CONS_IDLE: /* see if the screen has been idle */ - *(int *)data = (scrn_idle && !(cur_console->status & UNKNOWN_MODE)); + /* + * When the screen is in the GRAPHICS_MODE or UNKNOWN_MODE, + * the user process may have been writing something on the + * screen and syscons is not aware of it. Declare the screen + * is NOT idle if it is in one of these modes. But there is + * an exception to it; if a screen saver is running in the + * graphics mode in the current screen, we should say that the + * screen has been idle. + */ + *(int *)data = scrn_idle + && (!ISGRAPHSC(cur_console) + || (cur_console->status & SAVER_RUNNING)); return 0; case CONS_SAVERMODE: /* set saver mode */ switch(*(int *)data) { case CONS_USR_SAVER: - /* if a LKM screen saver is running, it will eventually stop... */ + /* if a LKM screen saver is running, stop it first. */ + scsplash_stick(FALSE); saver_mode = *(int *)data; + s = spltty(); + if ((error = wait_scrn_saver_stop())) { + splx(s); + return error; + } + scp->status |= SAVER_RUNNING; scsplash_stick(TRUE); + splx(s); break; case CONS_LKM_SAVER: + s = spltty(); + if ((saver_mode == CONS_USR_SAVER) && (scp->status & SAVER_RUNNING)) + scp->status &= ~SAVER_RUNNING; saver_mode = *(int *)data; + splx(s); break; default: return EINVAL; @@ -1754,7 +1641,6 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) if (!crtc_vga) return ENXIO; scp->xsize = 80; - scp->status &= ~MOUSE_VISIBLE; remove_cutmarking(scp); s = spltty(); @@ -1779,247 +1665,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) default: return EINVAL; } -#else /* IBM-PC */ - /* VGA TEXT MODES */ - case SW_VGA_C40x25: - case SW_VGA_C80x25: case SW_VGA_M80x25: - case SW_VGA_C80x30: case SW_VGA_M80x30: - case SW_VGA_C80x50: case SW_VGA_M80x50: - case SW_VGA_C80x60: case SW_VGA_M80x60: - case SW_B40x25: case SW_C40x25: - case SW_B80x25: case SW_C80x25: - case SW_ENH_B40x25: case SW_ENH_C40x25: - case SW_ENH_B80x25: case SW_ENH_C80x25: - case SW_ENH_B80x43: case SW_ENH_C80x43: - case SW_EGAMONO80x25: - - if (crtc_type != KD_VGA) - return ENODEV; - mp = get_mode_param(scp, cmd & 0xff); - if (mp == NULL) - return ENODEV; - - s = spltty(); - if ((error = wait_scrn_saver_stop())) { - splx(s); - return error; - } - - scp->status &= ~MOUSE_VISIBLE; - remove_cutmarking(scp); - if (scp->history != NULL) - i = imax(scp->history_size / scp->xsize - - imax(SC_HISTORY_SIZE, scp->ysize), 0); - else - i = 0; - switch (cmd & 0xff) { - case M_VGA_C80x60: case M_VGA_M80x60: - if (!(fonts_loaded & FONT_8)) { - splx(s); - return EINVAL; - } - /* - * This is a kludge to fend off scrn_update() while we - * muck around with scp. XXX - */ - scp->status |= UNKNOWN_MODE; - scp->xsize = 80; - scp->ysize = 60; - scp->font_size = 8; - break; - case M_VGA_C80x50: case M_VGA_M80x50: - if (!(fonts_loaded & FONT_8)) { - splx(s); - return EINVAL; - } - scp->status |= UNKNOWN_MODE; - scp->xsize = 80; - scp->ysize = 50; - scp->font_size = 8; - break; - case M_ENH_B80x43: case M_ENH_C80x43: - if (!(fonts_loaded & FONT_8)) { - splx(s); - return EINVAL; - } - scp->status |= UNKNOWN_MODE; - scp->xsize = 80; - scp->ysize = 43; - scp->font_size = 8; - break; - case M_VGA_C80x30: case M_VGA_M80x30: - scp->status |= UNKNOWN_MODE; - scp->xsize = 80; - scp->ysize = 30; - scp->font_size = mp[2]; - break; - case M_ENH_C40x25: case M_ENH_B40x25: - case M_ENH_C80x25: case M_ENH_B80x25: - case M_EGAMONO80x25: - if (!(fonts_loaded & FONT_14)) { - splx(s); - return EINVAL; - } - /* FALL THROUGH */ - default: - if ((cmd & 0xff) > M_VGA_CG320) { - splx(s); - return EINVAL; - } - scp->status |= UNKNOWN_MODE; - scp->xsize = mp[0]; - scp->ysize = mp[1] + rows_offset; - scp->font_size = mp[2]; - break; - } -#endif - - scp->mode = cmd & 0xff; - scp->xpixel = scp->xsize * 8; - scp->ypixel = scp->ysize * scp->font_size; - free(scp->scr_buf, M_DEVBUF); - scp->scr_buf = (u_short *) - malloc(scp->xsize*scp->ysize*sizeof(u_short), M_DEVBUF, M_WAITOK); -#ifdef PC98 - free(scp->atr_buf, M_DEVBUF); - scp->atr_buf = (u_short *) - malloc(scp->xsize*scp->ysize*sizeof(u_short),M_DEVBUF, M_WAITOK); -#endif - /* move the text cursor to the home position */ - move_crsr(scp, 0, 0); - /* move the mouse cursor at the center of the screen */ - scp->mouse_xpos = scp->xpixel / 2; - scp->mouse_ypos = scp->ypixel / 2; - scp->mouse_pos = scp->mouse_oldpos = - scp->scr_buf + (scp->mouse_ypos / scp->font_size) * scp->xsize - + scp->mouse_xpos / 8; - /* allocate a larger cut buffer if necessary */ - if ((cut_buffer == NULL) - || (cut_buffer_size < scp->xsize * scp->ysize + 1)) { - if (cut_buffer != NULL) - free(cut_buffer, M_DEVBUF); - cut_buffer_size = scp->xsize * scp->ysize + 1; - cut_buffer = (char *)malloc(cut_buffer_size, M_DEVBUF, M_NOWAIT); - if (cut_buffer != NULL) - cut_buffer[0] = '\0'; - } - splx(s); - - usp = scp->history; - scp->history = NULL; - if (usp != NULL) { - free(usp, M_DEVBUF); - extra_history_size += i; - } -#ifdef PC98 - atr_usp = scp->his_atr; - scp->his_atr = NULL; - if (atr_usp != NULL) - free(atr_usp, M_DEVBUF); -#endif - scp->history_size = imax(SC_HISTORY_SIZE, scp->ysize) * scp->xsize; - usp = (u_short *)malloc(scp->history_size * sizeof(u_short), - M_DEVBUF, M_NOWAIT); - if (usp != NULL) - bzero(usp, scp->history_size * sizeof(u_short)); - scp->history_head = scp->history_pos = usp; - scp->history = usp; -#ifdef PC98 - atr_usp = (u_short *)malloc(scp->history_size * sizeof(u_short), - M_DEVBUF, M_NOWAIT); - if (atr_usp != NULL) - bzero(atr_usp, scp->history_size * sizeof(u_short)); - scp->his_atr_head = scp->his_atr_pos = atr_usp; - scp->his_atr = atr_usp; #endif - if (scp == cur_console) - set_mode(scp); - clear_screen(scp); - scp->status &= ~UNKNOWN_MODE; - - if (tp->t_winsize.ws_col != scp->xsize - || tp->t_winsize.ws_row != scp->ysize) { - tp->t_winsize.ws_col = scp->xsize; - tp->t_winsize.ws_row = scp->ysize; - pgsignal(tp->t_pgrp, SIGWINCH, 1); - } - return 0; -#ifndef PC98 - /* GRAPHICS MODES */ - case SW_BG320: case SW_BG640: - case SW_CG320: case SW_CG320_D: case SW_CG640_E: - case SW_CG640x350: case SW_ENH_CG640: - case SW_BG640x480: case SW_CG640x480: case SW_VGA_CG320: - - if (crtc_type != KD_VGA) - return ENODEV; - mp = get_mode_param(scp, cmd & 0xff); - if (mp == NULL) - return ENODEV; - - s = spltty(); - if ((error = wait_scrn_saver_stop())) { - splx(s); - return error; - } - - scp->status &= ~MOUSE_VISIBLE; - remove_cutmarking(scp); - scp->status |= UNKNOWN_MODE; /* graphics mode */ - scp->mode = cmd & 0xFF; - scp->xpixel = mp[0] * 8; - scp->ypixel = (mp[1] + rows_offset) * mp[2]; - scp->font_size = FONT_NONE; - /* move the mouse cursor at the center of the screen */ - scp->mouse_xpos = scp->xpixel / 2; - scp->mouse_ypos = scp->ypixel / 2; - splx(s); - - if (scp == cur_console) - set_mode(scp); - /* clear_graphics();*/ - - if (tp->t_winsize.ws_xpixel != scp->xpixel - || tp->t_winsize.ws_ypixel != scp->ypixel) { - tp->t_winsize.ws_xpixel = scp->xpixel; - tp->t_winsize.ws_ypixel = scp->ypixel; - pgsignal(tp->t_pgrp, SIGWINCH, 1); - } - return 0; - - case SW_VGA_MODEX: - if (crtc_type != KD_VGA) - return ENODEV; - mp = get_mode_param(scp, cmd & 0xff); - if (mp == NULL) - return ENODEV; - - s = spltty(); - if ((error = wait_scrn_saver_stop())) { - splx(s); - return error; - } - - scp->status &= ~MOUSE_VISIBLE; - remove_cutmarking(scp); - scp->status |= UNKNOWN_MODE; /* graphics mode */ - scp->mode = cmd & 0xFF; - scp->xpixel = 320; - scp->ypixel = 240; - scp->font_size = FONT_NONE; - splx(s); - - if (scp == cur_console) - set_mode(scp); - /* clear_graphics();*/ - if (tp->t_winsize.ws_xpixel != scp->xpixel - || tp->t_winsize.ws_ypixel != scp->ypixel) { - tp->t_winsize.ws_xpixel = scp->xpixel; - tp->t_winsize.ws_ypixel = scp->ypixel; - pgsignal(tp->t_pgrp, SIGWINCH, 1); - } - return 0; -#endif /* PC98 */ case VT_SETMODE: /* set screen switcher mode */ { @@ -2043,7 +1689,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) return 0; case VT_RELDISP: /* screen switcher ioctl */ - switch(*data) { + switch(*(int *)data) { case VT_FALSE: /* user refuses to release screen, abort */ if (scp == old_scp && (scp->status & SWITCH_WAIT_REL)) { old_scp->status &= ~SWITCH_WAIT_REL; @@ -2083,32 +1729,32 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) for (i = 0; i < MAXCONS; i++) { tp = VIRTUAL_TTY(i); if (!(tp->t_state & TS_ISOPEN)) { - *data = i + 1; + *(int *)data = i + 1; return 0; } } return EINVAL; case VT_ACTIVATE: /* switch to screen *data */ - return switch_scr(scp, (*data) - 1); + return switch_scr(scp, *(int *)data - 1); case VT_WAITACTIVE: /* wait for switch to occur */ - if (*data > MAXCONS || *data < 0) + if (*(int *)data > MAXCONS || *(int *)data < 0) return EINVAL; - if (minor(dev) == (*data) - 1) + if (minor(dev) == *(int *)data - 1) return 0; - if (*data == 0) { + if (*(int *)data == 0) { if (scp == cur_console) return 0; } else - scp = console[(*data) - 1]; + scp = console[*(int *)data - 1]; while ((error=tsleep((caddr_t)&scp->smode, PZERO|PCATCH, "waitvt", 0)) == ERESTART) ; return error; case VT_GETACTIVE: - *data = get_scr_num()+1; + *(int *)data = get_scr_num()+1; return 0; case KDENABIO: /* allow io operations */ @@ -2124,120 +1770,38 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) p->p_md.md_regs->tf_eflags &= ~PSL_IOPL; return 0; - case KDSETMODE: /* set current mode of this (virtual) console */ - switch (*data) { - case KD_TEXT: /* switch to TEXT (known) mode */ + case KDSKBSTATE: /* set keyboard state (locks) */ + if (*(int *)data & ~LOCK_KEY_MASK) + return EINVAL; + scp->status &= ~LOCK_KEY_MASK; + scp->status |= *(int *)data; + if (scp == cur_console) + update_leds(scp->status); + return 0; + + case KDGKBSTATE: /* get keyboard state (locks) */ + *(int *)data = scp->status & LOCK_KEY_MASK; + return 0; + + case KDSETRAD: /* set keyboard repeat & delay rates */ #ifndef PC98 - /* restore fonts & palette ! */ - if (crtc_type == KD_VGA) { - if (!VESA_MODE(scp->mode)) { -#if 0 - /* - * FONT KLUDGE - * Don't load fonts for now... XXX - */ - if (fonts_loaded & FONT_8) - copy_font(LOAD, FONT_8, font_8); - if (fonts_loaded & FONT_14) - copy_font(LOAD, FONT_14, font_14); - if (fonts_loaded & FONT_16) - copy_font(LOAD, FONT_16, font_16); + if (*(int *)data & ~0x7f) + return EINVAL; + if (sc_kbdc != NULL) + set_keyboard(KBDC_SET_TYPEMATIC, *(int *)data); #endif - } - load_palette(palette); - } + return 0; - /* move hardware cursor out of the way */ - outb(crtc_addr, 14); - outb(crtc_addr + 1, 0xff); - outb(crtc_addr, 15); - outb(crtc_addr + 1, 0xff); + case KDSKBMODE: /* set keyboard mode */ + switch (*(int *)data) { + case K_RAW: /* switch to RAW scancode mode */ + scp->status &= ~KBD_CODE_MODE; + scp->status |= KBD_RAW_MODE; + return 0; - /* FALL THROUGH */ -#endif - case KD_TEXT1: /* switch to TEXT (known) mode */ - s = spltty(); - if ((error = wait_scrn_saver_stop())) { - splx(s); - return error; - } - scp->status &= ~MOUSE_VISIBLE; - remove_cutmarking(scp); - scp->status |= UNKNOWN_MODE; - splx(s); - /* no restore fonts & palette */ -#ifdef PC98 - scp->status &= ~UNKNOWN_MODE; -#else - if (crtc_type == KD_VGA) -#endif - set_mode(scp); - scp->status &= ~UNKNOWN_MODE; - clear_screen(scp); - return 0; - - case KD_GRAPHICS: /* switch to GRAPHICS (unknown) mode */ - s = spltty(); - if ((error = wait_scrn_saver_stop())) { - splx(s); - return error; - } - scp->status &= ~MOUSE_VISIBLE; - remove_cutmarking(scp); - scp->status |= UNKNOWN_MODE; -#ifdef PC98 - set_mode(scp); -#endif - splx(s); - return 0; - default: - return EINVAL; - } - /* NOT REACHED */ - - case KDGETMODE: /* get current mode of this (virtual) console */ - *data = (scp->status & UNKNOWN_MODE) ? KD_GRAPHICS : KD_TEXT; - return 0; - - case KDSBORDER: /* set border color of this (virtual) console */ - scp->border = *data; - if (scp == cur_console) - set_border(scp->border); - return 0; - - case KDSKBSTATE: /* set keyboard state (locks) */ - if (*data >= 0 && *data <= LOCK_KEY_MASK) { - scp->status &= ~LOCK_KEY_MASK; - scp->status |= *data; - if (scp == cur_console) - update_leds(scp->status); - return 0; - } - return EINVAL; - - case KDGKBSTATE: /* get keyboard state (locks) */ - *data = scp->status & LOCK_KEY_MASK; - return 0; - - case KDSETRAD: /* set keyboard repeat & delay rates */ -#ifndef PC98 - if (*data & 0x80) - return EINVAL; - if (sc_kbdc != NULL) - set_keyboard(KBDC_SET_TYPEMATIC, *data); -#endif - return 0; - - case KDSKBMODE: /* set keyboard mode */ - switch (*data) { - case K_RAW: /* switch to RAW scancode mode */ - scp->status &= ~KBD_CODE_MODE; - scp->status |= KBD_RAW_MODE; - return 0; - - case K_CODE: /* switch to CODE mode */ - scp->status &= ~KBD_RAW_MODE; - scp->status |= KBD_CODE_MODE; + case K_CODE: /* switch to CODE mode */ + scp->status &= ~KBD_RAW_MODE; + scp->status |= KBD_CODE_MODE; return 0; case K_XLATE: /* switch to XLT ascii mode */ @@ -2251,7 +1815,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) /* NOT REACHED */ case KDGKBMODE: /* get keyboard mode */ - *data = (scp->status & KBD_RAW_MODE) ? K_RAW : + *(int *)data = (scp->status & KBD_RAW_MODE) ? K_RAW : ((scp->status & KBD_CODE_MODE) ? K_CODE : K_XLATE); return 0; @@ -2306,21 +1870,20 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) return 0; case KDGKBTYPE: /* get keyboard type */ - *data = 0; /* type not known (yet) */ + *(int *)data = 0; /* type not known (yet) */ return 0; case KDSETLED: /* set keyboard LED status */ - if (*data >= 0 && *data <= LED_MASK) { - scp->status &= ~LED_MASK; - scp->status |= *data; - if (scp == cur_console) - update_leds(scp->status); - return 0; - } - return EINVAL; + if (*(int *)data & ~LED_MASK) + return EINVAL; + scp->status &= ~LED_MASK; + scp->status |= *(int *)data; + if (scp == cur_console) + update_leds(scp->status); + return 0; case KDGETLED: /* get keyboard LED status */ - *data = scp->status & LED_MASK; + *(int *)data = scp->status & LED_MASK; return 0; case GETFKEY: /* get functionkey string */ @@ -2384,7 +1947,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) return ENXIO; #else case PIO_FONT8x8: /* set 8x8 dot font */ - if (crtc_type != KD_VGA) + if (!ISFONTAVAIL(get_adapter(scp)->va_flags)) return ENXIO; bcopy(data, font_8, 8*256); fonts_loaded |= FONT_8; @@ -2393,17 +1956,12 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) * Always use the font page #0. XXX * Don't load if the current font size is not 8x8. */ - if (!VESA_MODE(cur_console->mode) - && !(cur_console->status & UNKNOWN_MODE) - && (cur_console->font_size < 14)) { - copy_font(LOAD, FONT_8, font_8); - if (flags & CHAR_CURSOR) - set_destructive_cursor(cur_console); - } + if (ISTEXTSC(cur_console) && (cur_console->font_size < 14)) + copy_font(cur_console, LOAD, 8, font_8); return 0; case GIO_FONT8x8: /* get 8x8 dot font */ - if (crtc_type != KD_VGA) + if (!ISFONTAVAIL(get_adapter(scp)->va_flags)) return ENXIO; if (fonts_loaded & FONT_8) { bcopy(font_8, data, 8*256); @@ -2413,7 +1971,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) return ENXIO; case PIO_FONT8x14: /* set 8x14 dot font */ - if (crtc_type != KD_VGA) + if (!ISFONTAVAIL(get_adapter(scp)->va_flags)) return ENXIO; bcopy(data, font_14, 14*256); fonts_loaded |= FONT_14; @@ -2422,17 +1980,13 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) * Always use the font page #0. XXX * Don't load if the current font size is not 8x14. */ - if (!VESA_MODE(cur_console->mode) - && !(cur_console->status & UNKNOWN_MODE) - && (cur_console->font_size >= 14) && (cur_console->font_size < 16)) { - copy_font(LOAD, FONT_14, font_14); - if (flags & CHAR_CURSOR) - set_destructive_cursor(cur_console); - } + if (ISTEXTSC(cur_console) + && (cur_console->font_size >= 14) && (cur_console->font_size < 16)) + copy_font(cur_console, LOAD, 14, font_14); return 0; case GIO_FONT8x14: /* get 8x14 dot font */ - if (crtc_type != KD_VGA) + if (!ISFONTAVAIL(get_adapter(scp)->va_flags)) return ENXIO; if (fonts_loaded & FONT_14) { bcopy(font_14, data, 14*256); @@ -2442,7 +1996,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) return ENXIO; case PIO_FONT8x16: /* set 8x16 dot font */ - if (crtc_type != KD_VGA) + if (!ISFONTAVAIL(get_adapter(scp)->va_flags)) return ENXIO; bcopy(data, font_16, 16*256); fonts_loaded |= FONT_16; @@ -2451,17 +2005,12 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) * Always use the font page #0. XXX * Don't load if the current font size is not 8x16. */ - if (!VESA_MODE(cur_console->mode) - && !(cur_console->status & UNKNOWN_MODE) - && (cur_console->font_size >= 16)) { - copy_font(LOAD, FONT_16, font_16); - if (flags & CHAR_CURSOR) - set_destructive_cursor(cur_console); - } + if (ISTEXTSC(cur_console) && (cur_console->font_size >= 16)) + copy_font(cur_console, LOAD, 16, font_16); return 0; case GIO_FONT8x16: /* get 8x16 dot font */ - if (crtc_type != KD_VGA) + if (!ISFONTAVAIL(get_adapter(scp)->va_flags)) return ENXIO; if (fonts_loaded & FONT_16) { bcopy(font_16, data, 16*256); @@ -2495,7 +2044,7 @@ scstart(struct tty *tp) struct clist *rbp; int s, len; u_char buf[PCBURST]; - scr_stat *scp = get_scr_stat(tp->t_dev); + scr_stat *scp = sc_get_scr_stat(tp->t_dev); if (scp->status & SLKED || blink_in_progress) return; /* XXX who repeats the call when the above flags are cleared? */ @@ -2577,7 +2126,7 @@ sccnputc(dev_t dev, int c) scp->term = kernel_console; current_default = &kernel_default; - if (scp == cur_console && !(scp->status & UNKNOWN_MODE)) + if (scp == cur_console && !ISGRAPHSC(scp)) remove_cursor_image(scp); buf[0] = c; ansi_put(scp, buf, 1); @@ -2632,25 +2181,28 @@ sccnupdate(scr_stat *scp) if (font_loading_in_progress) return; - if (panicstr) { + if (panicstr || shutdown_in_progress) { scsplash_stick(FALSE); run_scrn_saver = FALSE; + } else if (scp != cur_console) { + return; } + if (!run_scrn_saver) scrn_idle = FALSE; if ((saver_mode != CONS_LKM_SAVER) || !scrn_idle) - if (scrn_blanked > 0) + if (scp->status & SAVER_RUNNING) stop_scrn_saver(current_saver); if (scp != cur_console || blink_in_progress || switch_in_progress) return; - if ((scp->status & UNKNOWN_MODE) == 0 && scrn_blanked <= 0) + if (!ISGRAPHSC(scp) && !(scp->status & SAVER_RUNNING)) scrn_update(scp, TRUE); } -static scr_stat -*get_scr_stat(dev_t dev) +scr_stat +*sc_get_scr_stat(dev_t dev) { int unit = minor(dev); @@ -2709,6 +2261,8 @@ scrn_timer(void *arg) scintr(0); } + scp = cur_console; + /* should we stop the screen saver? */ getmicrouptime(&tv); if (panicstr || shutdown_in_progress) { @@ -2724,7 +2278,7 @@ scrn_timer(void *arg) run_scrn_saver = TRUE; } if ((saver_mode != CONS_LKM_SAVER) || !scrn_idle) - if (scrn_blanked > 0) + if (scp->status & SAVER_RUNNING) stop_scrn_saver(current_saver); /* should we just return ? */ @@ -2736,14 +2290,13 @@ scrn_timer(void *arg) } /* Update the screen */ - scp = cur_console; - if ((scp->status & UNKNOWN_MODE) == 0 && scrn_blanked <= 0) + if (!ISGRAPHSC(scp) && !(scp->status & SAVER_RUNNING)) scrn_update(scp, TRUE); /* should we activate the screen saver? */ if ((saver_mode == CONS_LKM_SAVER) && scrn_idle) - if ((scp->status & UNKNOWN_MODE) == 0 || scrn_blanked > 0) - (*current_saver)(TRUE); + if (!ISGRAPHSC(scp) || (scp->status & SAVER_RUNNING)) + scrn_saver(current_saver, TRUE); if (arg) timeout(scrn_timer, (void *)TRUE, hz / 25); @@ -2810,7 +2363,7 @@ scrn_update(scr_stat *scp, int show_cursor) draw_cursor_image(scp); } else { /* if its a blinking cursor, we may have to update it */ - if (flags & BLINK_CURSOR) + if (sc_flags & BLINK_CURSOR) draw_cursor_image(scp); } } @@ -2836,9 +2389,9 @@ add_scrn_saver(void (*this_saver)(int)) if (current_saver != default_saver) return EBUSY; - current_saver = this_saver; + run_scrn_saver = FALSE; saver_mode = CONS_LKM_SAVER; - run_scrn_saver = (scrn_blank_time > 0); + current_saver = this_saver; return 0; } @@ -2866,9 +2419,21 @@ remove_scrn_saver(void (*this_saver)(int)) } static void +scrn_saver(void (*saver)(int), int blank) +{ + static int busy = FALSE; + + if (busy) + return; + busy = TRUE; + (*saver)(blank); + busy = FALSE; +} + +static void stop_scrn_saver(void (*saver)(int)) { - (*saver)(FALSE); + scrn_saver(saver, FALSE); run_scrn_saver = FALSE; /* the screen saver may have chosen not to stop after all... */ if (scrn_blanked > 0) @@ -2885,8 +2450,8 @@ wait_scrn_saver_stop(void) { int error = 0; - run_scrn_saver = FALSE; while (scrn_blanked > 0) { + run_scrn_saver = FALSE; error = tsleep((caddr_t)&scrn_blanked, PZERO | PCATCH, "scrsav", 0); run_scrn_saver = FALSE; if (error != ERESTART) @@ -2895,8 +2460,8 @@ wait_scrn_saver_stop(void) return error; } -static void -clear_screen(scr_stat *scp) +void +sc_clear_screen(scr_stat *scp) { move_crsr(scp, 0, 0); scp->cursor_oldpos = scp->cursor_pos; @@ -2928,8 +2493,7 @@ switch_scr(scr_stat *scp, u_int next_scr) switch_in_progress = FALSE; if (next_scr >= MAXCONS || switch_in_progress || - (cur_console->smode.mode == VT_AUTO - && cur_console->status & UNKNOWN_MODE)) { + (cur_console->smode.mode == VT_AUTO && ISGRAPHSC(cur_console))) { do_bell(scp, BELL_PITCH, BELL_DURATION); return EINVAL; } @@ -2982,30 +2546,30 @@ exchange_scr(void) move_crsr(old_scp, old_scp->xpos, old_scp->ypos); cur_console = new_scp; #ifdef PC98 - if (old_scp->mode != new_scp->mode || (old_scp->status & UNKNOWN_MODE) || (new_scp->status & UNKNOWN_MODE)){ + if (old_scp->mode != new_scp->mode || ISUNKNOWNSC(old_scp) || ISUNKNOWNSC(new_scp)) #else - if (old_scp->mode != new_scp->mode || (old_scp->status & UNKNOWN_MODE)){ - if (crtc_type == KD_VGA) + if (old_scp->mode != new_scp->mode || ISUNKNOWNSC(old_scp)) #endif - set_mode(new_scp); - } + set_mode(new_scp); move_crsr(new_scp, new_scp->xpos, new_scp->ypos); #ifndef PC98 - if (!(new_scp->status & UNKNOWN_MODE) && (flags & CHAR_CURSOR)) + if (ISTEXTSC(new_scp) && (sc_flags & CHAR_CURSOR)) set_destructive_cursor(new_scp); - if ((old_scp->status & UNKNOWN_MODE) && crtc_type == KD_VGA) - load_palette(palette); + if (ISGRAPHSC(old_scp)) + load_palette(new_scp, palette); #endif if (old_scp->status & KBD_RAW_MODE || new_scp->status & KBD_RAW_MODE || old_scp->status & KBD_CODE_MODE || new_scp->status & KBD_CODE_MODE) shfts = ctls = alts = agrs = metas = accents = 0; - set_border(new_scp->border); + set_border(new_scp, new_scp->border); update_leds(new_scp->status); delayed_next_scr = FALSE; mark_all(new_scp); +#ifdef PC98 if (new_scp->mode == 0x102) { bzero(Crtat, 800*600/8); } +#endif } static void @@ -3022,36 +2586,36 @@ scan_esc(scr_stat *scp, u_char c) if (scp->term.esc == 1) { /* seen ESC */ #ifdef KANJI switch (scp->kanji_type) { - case 0x80: + case KTYPE_KANIN: /* Kanji Invoke sequence */ switch (c) { case 'B': case '@': - scp->kanji_type = 0x20; + scp->kanji_type = KTYPE_7JIS; scp->term.esc = 0; scp->kanji_1st_char = 0; return; default: - scp->kanji_type = 0; + scp->kanji_type = KTYPE_ASCII; scp->term.esc = 0; break; } break; - case 0x40: + case KTYPE_ASCIN: /* Ascii Invoke sequence */ switch (c) { case 'J': case 'B': case 'H': - scp->kanji_type = 0; + scp->kanji_type = KTYPE_ASCII; scp->term.esc = 0; scp->kanji_1st_char = 0; return; case 'I': - scp->kanji_type = 0x10; + scp->kanji_type = KTYPE_JKANA; scp->term.esc = 0; scp->kanji_1st_char = 0; return; default: - scp->kanji_type = 0; + scp->kanji_type = KTYPE_ASCII; scp->term.esc = 0; break; } @@ -3081,8 +2645,8 @@ scan_esc(scr_stat *scp, u_char c) return; #ifdef KANJI - case '$': /* Kanji IN sequence */ - scp->kanji_type = 0x80; + case '$': /* Kanji Invoke sequence */ + scp->kanji_type = KTYPE_KANIN; return; #endif @@ -3114,12 +2678,12 @@ scan_esc(scr_stat *scp, u_char c) return; #endif case 'c': /* Clear screen & home */ - clear_screen(scp); + sc_clear_screen(scp); break; case '(': /* iso-2022: designate 94 character set to G0 */ #ifdef KANJI - scp->kanji_type = 0x40; + scp->kanji_type = KTYPE_ASCIN; #else scp->term.esc = 5; #endif @@ -3216,7 +2780,7 @@ scan_esc(scr_stat *scp, u_char c) #ifdef PC98 mark_for_update(scp, scp->cursor_atr - scp->atr_buf); #endif - mark_for_update(scp, scp->xsize * scp->ysize); + mark_for_update(scp, scp->xsize * scp->ysize - 1); remove_cutmarking(scp); break; case 1: /* clear from beginning of display to cursor */ @@ -3279,10 +2843,10 @@ scan_esc(scr_stat *scp, u_char c) mark_for_update(scp, scp->cursor_atr - scp->atr_buf); #endif mark_for_update(scp, scp->cursor_pos - scp->scr_buf + - scp->xsize - scp->xpos); + scp->xsize - 1 - scp->xpos); #ifdef PC98 mark_for_update(scp, scp->cursor_atr - scp->atr_buf + - scp->xsize - scp->xpos); + scp->xsize - 1 - scp->xpos); #endif break; case 1: /* clear from beginning of line to cursor */ @@ -3318,7 +2882,7 @@ scan_esc(scr_stat *scp, u_char c) scp->xsize); #endif mark_for_update(scp, scp->ypos * scp->xsize); - mark_for_update(scp, (scp->ypos + 1) * scp->xsize); + mark_for_update(scp, (scp->ypos + 1) * scp->xsize - 1); break; } break; @@ -3344,7 +2908,7 @@ scan_esc(scr_stat *scp, u_char c) n * scp->xsize); #endif mark_for_update(scp, scp->ypos * scp->xsize); - mark_for_update(scp, scp->xsize * scp->ysize); + mark_for_update(scp, scp->xsize * scp->ysize - 1); break; case 'M': /* Delete n lines */ @@ -3370,7 +2934,7 @@ scan_esc(scr_stat *scp, u_char c) n * scp->xsize); #endif mark_for_update(scp, scp->ypos * scp->xsize); - mark_for_update(scp, scp->xsize * scp->ysize); + mark_for_update(scp, scp->xsize * scp->ysize - 1); break; case 'P': /* Delete n chars */ @@ -3396,9 +2960,9 @@ scan_esc(scr_stat *scp, u_char c) #ifdef PC98 mark_for_update(scp, scp->cursor_atr - scp->atr_buf); #endif - mark_for_update(scp, scp->cursor_pos - scp->scr_buf + n + count); + mark_for_update(scp, scp->cursor_pos - scp->scr_buf + n + count - 1); #ifdef PC98 - mark_for_update(scp, scp->cursor_atr - scp->atr_buf + n + count); + mark_for_update(scp, scp->cursor_atr - scp->atr_buf + n + count - 1); #endif break; @@ -3423,9 +2987,9 @@ scan_esc(scr_stat *scp, u_char c) #ifdef PC98 mark_for_update(scp, scp->cursor_atr - scp->atr_buf); #endif - mark_for_update(scp, scp->cursor_pos - scp->scr_buf + n + count); + mark_for_update(scp, scp->cursor_pos - scp->scr_buf + n + count - 1); #ifdef PC98 - mark_for_update(scp, scp->cursor_atr - scp->atr_buf + n + count); + mark_for_update(scp, scp->cursor_atr - scp->atr_buf + n + count - 1); #endif break; @@ -3495,9 +3059,9 @@ scan_esc(scr_stat *scp, u_char c) #ifdef PC98 mark_for_update(scp, scp->cursor_atr - scp->atr_buf); #endif - mark_for_update(scp, scp->cursor_pos - scp->scr_buf + n); + mark_for_update(scp, scp->cursor_pos - scp->scr_buf + n - 1); #ifdef PC98 - mark_for_update(scp, scp->cursor_atr - scp->atr_buf + n); + mark_for_update(scp, scp->cursor_atr - scp->atr_buf + n - 1); #endif break; @@ -3569,7 +3133,7 @@ scan_esc(scr_stat *scp, u_char c) scp->term.cur_color = (scp->term.cur_color&0xF000) | (ansi_col[(n-30)&7]<<8); scp->term.cur_attr = mask2attr(&scp->term); - break; + break; case 40: case 41: /* set bg color */ case 42: case 43: case 44: case 45: case 46: case 47: @@ -3676,7 +3240,7 @@ scan_esc(scr_stat *scp, u_char c) if (scp->term.num_param == 1) { scp->border=scp->term.param[0] & 0xff; if (scp == cur_console) - set_border(scp->border); + set_border(cur_console, scp->border); } break; @@ -3690,14 +3254,21 @@ scan_esc(scr_stat *scp, u_char c) case 'C': /* set cursor type & shape */ if (scp->term.num_param == 1) { if (scp->term.param[0] & 0x01) - flags |= BLINK_CURSOR; + sc_flags |= BLINK_CURSOR; + else + sc_flags &= ~BLINK_CURSOR; +#ifdef PC98 + if (scp->term.param[0] & 0x02) + sc_flags |= CHAR_CURSOR; else - flags &= ~BLINK_CURSOR; - if ((scp->term.param[0] & 0x02) && - crtc_type == KD_VGA && !VESA_MODE(bios_video_mode)) - flags |= CHAR_CURSOR; + sc_flags &= ~CHAR_CURSOR; +#else /* PC98 */ + if ((scp->term.param[0] & 0x02) + && ISFONTAVAIL(get_adapter(scp)->va_flags)) + sc_flags |= CHAR_CURSOR; else - flags &= ~CHAR_CURSOR; + sc_flags &= ~CHAR_CURSOR; +#endif /* PC98 */ } else if (scp->term.num_param == 2) { scp->cursor_start = scp->term.param[0] & 0x1F; @@ -3707,9 +3278,9 @@ scan_esc(scr_stat *scp, u_char c) * The cursor shape is global property; all virtual consoles * are affected. Update the cursor in the current console... */ - if (!(cur_console->status & UNKNOWN_MODE)) { + if (!ISGRAPHSC(cur_console)) { remove_cursor_image(cur_console); - if (crtc_type == KD_VGA && (flags & CHAR_CURSOR)) + if (sc_flags & CHAR_CURSOR) set_destructive_cursor(cur_console); draw_cursor_image(cur_console); } @@ -3774,103 +3345,114 @@ scan_esc(scr_stat *scp, u_char c) #ifdef KANJI static u_char iskanji1(u_char mode, u_char c) { - if ((mode == 0x20) && (c >= 0x21) && (c <= 0x7e)) { + if ((mode == KTYPE_7JIS) && (c >= 0x21) && (c <= 0x7e)) { /* JIS */ - return 0x20; + default_kanji = UJIS; + return KTYPE_7JIS; } - if ((mode == 0x10) && (c >= 0x21) && (c <= 0x5f)) { + if ((mode == KTYPE_JKANA) && (c >= 0x21) && (c <= 0x5f)) { /* JIS HANKAKU */ - return 0x10; + default_kanji = UJIS; + return KTYPE_JKANA; + } + +#if 1 + if ((c >= 0xa1) && (c <= 0xdf) && (default_kanji == UJIS)) { + /* UJIS */ + return KTYPE_UJIS; } +#endif if ((c >= 0x81) && (c <= 0x9f) && (c != 0x8e)) { /* SJIS */ default_kanji = SJIS; - return 2; + return KTYPE_SJIS; } if ((c >= 0xa1) && (c <= 0xdf) && (default_kanji == SJIS)) { - /* Sjis HANKAKU */ - return 1; + /* SJIS HANKAKU */ + return KTYPE_KANA; } +#if 0 if ((c >= 0xa1) && (c <= 0xdf) && (default_kanji == UJIS)) { /* UJIS */ - return 4; + return KTYPE_UJIS; } +#endif if ((c >= 0xf0) && (c <= 0xfe)) { /* UJIS */ default_kanji = UJIS; - return 4; + return KTYPE_UJIS; } if ((c >= 0xe0) && (c <= 0xef)) { /* SJIS or UJIS */ - return 6; + return KTYPE_SUJIS; } if (c == 0x8e) { /* SJIS or UJIS HANKAKU */ - return 3; + return KTYPE_SUKANA; } - return 0; + return KTYPE_ASCII; } static u_char iskanji2(u_char mode, u_char c) { switch (mode) { - case 0x20: + case KTYPE_7JIS: if ((c >= 0x21) && (c <= 0x7e)) { /* JIS */ - return 0x20; + return KTYPE_7JIS; } break; - case 2: + case KTYPE_SJIS: if ((c >= 0x40) && (c <= 0xfc) && (c != 0x7f)) { /* SJIS */ - return 2; + return KTYPE_SJIS; } break; - case 4: + case KTYPE_UJIS: if ((c >= 0xa1) && (c <= 0xfe)) { /* UJIS */ - return 4; + return KTYPE_UJIS; } break; - case 3: + case KTYPE_SUKANA: if ((c >= 0xa1) && (c <= 0xdf) && (default_kanji == UJIS)) { /* UJIS HANKAKU */ - return 1; + return KTYPE_KANA; } if ((c >= 0x40) && (c <= 0xfc) && (c != 0x7f)) { /* SJIS */ default_kanji = SJIS; - return 2; + return KTYPE_SJIS; } break; - case 6: + case KTYPE_SUJIS: if ((c >= 0x40) && (c <= 0xa0) && (c != 0x7f)) { /* SJIS */ default_kanji = SJIS; - return 2; + return KTYPE_SJIS; } if ((c == 0xfd) || (c == 0xfe)) { /* UJIS */ default_kanji = UJIS; - return 4; + return KTYPE_UJIS; } if ((c >= 0xa1) && (c <= 0xfc)) { if (default_kanji == SJIS) - return 2; + return KTYPE_SJIS; if (default_kanji == UJIS) - return 4; + return KTYPE_UJIS; } break; } - return 0; + return KTYPE_ASCII; } /* @@ -3891,7 +3473,7 @@ static u_short kanji_convert(u_char mode, u_char h, u_char l) low = (u_short) l; switch (mode) { - case 2: /* SHIFT JIS */ + case KTYPE_SJIS: /* SHIFT JIS */ if (low >= 0xe0) { low -= 0x40; } @@ -3899,7 +3481,7 @@ static u_short kanji_convert(u_char mode, u_char h, u_char l) if (high > 0x7f) { high--; } - if (high >0x9d) { + if (high > 0x9d) { low++; high -= 0x9e - 0x21; } else { @@ -3909,8 +3491,8 @@ static u_short kanji_convert(u_char mode, u_char h, u_char l) low &= 0x7F; tmp = ((high << 8) | low) - 0x20; break; - case 0x20: /* JIS */ - case 4: /* HANKAKU? */ + case KTYPE_7JIS: /* JIS */ + case KTYPE_UJIS: /* UJIS */ high &= 0x7F; low &= 0x7F; tmp = ((high << 8) | low) - 0x20; @@ -3922,6 +3504,7 @@ static u_short kanji_convert(u_char mode, u_char h, u_char l) /* keisen */ c = ((tmp & 0xff) << 8) | (tmp >> 8); + /* 0x2821 .. 0x2840 */ if (0x0821 <= c && c <= 0x0840) tmp = keiConv[c - 0x0821]; @@ -3948,7 +3531,9 @@ outloop: len--; } else if (PRINTABLE(*ptr)) { /* Print only printables */ +#ifndef PC98 int cnt = len <= (scp->xsize-scp->xpos) ? len : (scp->xsize-scp->xpos); +#endif u_short cur_attr = scp->term.cur_attr; u_short *cursor_pos = scp->cursor_pos; #ifdef PC98 @@ -3957,7 +3542,7 @@ outloop: #ifdef KANJI if (scp->kanji_1st_char == 0) { scp->kanji_type = iskanji1(scp->kanji_type, c); - if (scp->kanji_type & 0xee) { + if (!IS_KTYPE_ASCII_or_HANKAKU(scp->kanji_type)) { /* not Ascii & not HANKAKU */ scp->kanji_1st_char = c; ptr++; len--; @@ -3970,7 +3555,8 @@ outloop: /* print kanji on TEXT VRAM */ kanji_code = kanji_convert(scp->kanji_type, c, scp->kanji_1st_char); for (i=0; i<2; i++){ - *cursor_pos = (kanji_code | (i*0x80)); + /* *cursor_pos = (kanji_code | (i*0x80)); */ + *cursor_pos = kanji_code | ((i==0) ? 0x00 : 0x80); *cursor_atr = (at2pc98(cur_attr)); cursor_pos++; cursor_atr++; @@ -3979,7 +3565,7 @@ outloop: scp->ypos++; } } - scp->kanji_type &= 0xF0; + KTYPE_MASK_CTRL(scp->kanji_type); scp->kanji_1st_char = 0; ptr++; len--; goto kanji_end; @@ -3987,8 +3573,9 @@ outloop: scp->kanji_1st_char = 0; } } - if ((scp->kanji_type & 0x11)) c |= 0x80; - scp->kanji_type &= 0xf0; + if (IS_KTYPE_KANA(scp->kanji_type)) + c |= 0x80; + KTYPE_MASK_CTRL(scp->kanji_type); #endif /* KANJI */ *cursor_pos++ = (scr_map[c]); *cursor_atr++ = at2pc98(cur_attr); @@ -4094,7 +3681,7 @@ kanji_end: break; case 0x0c: /* form feed, clears screen */ - clear_screen(scp); + sc_clear_screen(scp); break; case 0x0d: /* return, return to pos 0 */ @@ -4113,6 +3700,20 @@ kanji_end: scp->xpos = 0; break; +#ifdef PC98 + case 0x0e: /* ^N */ + scp->kanji_type = KTYPE_JKANA; + scp->term.esc = 0; + scp->kanji_1st_char = 0; + break; + + case 0x0f: /* ^O */ + scp->kanji_type = KTYPE_ASCII; + scp->term.esc = 0; + scp->kanji_1st_char = 0; + break; +#endif + case 0x1b: /* start escape sequence */ scp->term.esc = 1; scp->term.num_param = 0; @@ -4123,7 +3724,7 @@ kanji_end: /* do we have to scroll ?? */ if (scp->cursor_pos >= scp->scr_buf + scp->ysize * scp->xsize) { remove_cutmarking(scp); - if (scp->history) { + if (scp->history != NULL) { bcopy(scp->scr_buf, scp->history_head, scp->xsize * sizeof(u_short)); scp->history_head += scp->xsize; @@ -4139,7 +3740,8 @@ kanji_end: #endif scp->history_head = scp->history; #ifdef PC98 - scp->his_atr_head = scp->his_atr; } + scp->his_atr_head = scp->his_atr; + } #endif } bcopy(scp->scr_buf + scp->xsize, scp->scr_buf, @@ -4176,7 +3778,12 @@ kanji_end: static void scinit(void) { +#ifdef PC98 u_int hw_cursor; +#else + int col; + int row; +#endif u_int i; if (init_done != COLD) @@ -4206,35 +3813,9 @@ scinit(void) } crtc_vga = TRUE; #else /* IBM-PC */ - /* - * Ensure a zero start address. This is mainly to recover after - * switching from pcvt using userconfig(). The registers are w/o - * for old hardware so it's too hard to relocate the active screen - * memory. - */ - outb(crtc_addr, 12); - outb(crtc_addr + 1, 0); - outb(crtc_addr, 13); - outb(crtc_addr + 1, 0); - - /* extract cursor location */ - outb(crtc_addr, 14); - hw_cursor = inb(crtc_addr + 1) << 8; - outb(crtc_addr, 15); - hw_cursor |= inb(crtc_addr + 1); - - /* - * Validate cursor location. It may be off the screen. Then we must - * not use it for the initial buffer offset. - */ - if (hw_cursor >= ROW * COL) - hw_cursor = (ROW - 1) * COL; - - /* move hardware cursor out of the way */ - outb(crtc_addr, 14); - outb(crtc_addr + 1, 0xff); - outb(crtc_addr, 15); - outb(crtc_addr + 1, 0xff); + /* extract the hardware cursor location and move it out of the way */ + (*biosvidsw.read_hw_cursor)(V_ADP_PRIMARY, &col, &row); + (*biosvidsw.set_hw_cursor)(V_ADP_PRIMARY, -1, -1); #endif /* PC98 */ /* set up the first console */ @@ -4243,57 +3824,35 @@ scinit(void) init_scp(console[0]); cur_console = console[0]; -#ifndef PC98 - /* discard the video mode table if we are not familiar with it... */ - if (video_mode_ptr) { - bzero(mode_map, sizeof(mode_map)); - bcopy(video_mode_ptr + MODE_PARAM_SIZE*console[0]->mode, - vgaregs2, sizeof(vgaregs2)); - switch (comp_vgaregs(vgaregs, video_mode_ptr - + MODE_PARAM_SIZE*console[0]->mode)) { - case COMP_IDENTICAL: - map_mode_table(mode_map, video_mode_ptr, M_VGA_CG320 + 1); - /* - * This is a kludge for Toshiba DynaBook SS433 whose BIOS video - * mode table entry has the actual # of rows at the offset 1; - * BIOSes from other manufacturers store the # of rows - 1 there. - * XXX - */ - rows_offset = vgaregs[1] + 1 - - video_mode_ptr[MODE_PARAM_SIZE*console[0]->mode + 1]; - break; - case COMP_SIMILAR: - map_mode_table(mode_map, video_mode_ptr, M_VGA_CG320 + 1); - mode_map[console[0]->mode] = vgaregs; - rows_offset = vgaregs[1] + 1 - - video_mode_ptr[MODE_PARAM_SIZE*console[0]->mode + 1]; - vgaregs[1] -= rows_offset - 1; - break; - case COMP_DIFFERENT: - default: - video_mode_ptr = NULL; - mode_map[console[0]->mode] = vgaregs; - rows_offset = 1; - break; - } - } -#endif /* copy screen to temporary buffer */ - if (!VESA_MODE(console[0]->mode)) - generic_bcopy(Crtat, sc_buffer, - console[0]->xsize * console[0]->ysize * sizeof(u_short)); + if (ISTEXTSC(console[0])) +#ifdef PC98 + generic_bcopy(Crtat, sc_buffer, + console[0]->xsize * console[0]->ysize * sizeof(u_short)); +#else /* PC98 */ + generic_bcopy((ushort *)(get_adapter(console[0])->va_window), sc_buffer, + console[0]->xsize * console[0]->ysize * sizeof(u_short)); +#endif /* PC98 */ console[0]->scr_buf = console[0]->mouse_pos = console[0]->mouse_oldpos = sc_buffer; - console[0]->cursor_pos = console[0]->cursor_oldpos = sc_buffer + hw_cursor; #ifdef PC98 + console[0]->cursor_pos = console[0]->cursor_oldpos = sc_buffer + hw_cursor; console[0]->atr_buf = Atrat; console[0]->cursor_atr = Atrat + hw_cursor; + console[0]->xpos = hw_cursor % COL; + console[0]->ypos = hw_cursor / COL; #else + 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; #endif - console[0]->xpos = hw_cursor % COL; - console[0]->ypos = hw_cursor / COL; for (i=1; iva_flags)) { + if (fonts_loaded & FONT_16) { + copy_font(cur_console, LOAD, 16, font_16); + } else { + copy_font(cur_console, SAVE, 16, font_16); + fonts_loaded = FONT_16; + set_destructive_cursor(cur_console); } - save_palette(); + /* + * FONT KLUDGE + * Always use the font page #0. XXX + */ + (*biosvidsw.show_font)(cur_console->adp, 0); } + save_palette(cur_console, palette); #ifdef SC_SPLASH_SCREEN - /* - * If not booting verbosely, put up the splash. - * Note that the splash screen is not currently supported in - * the VESA mode. - */ - if (!(boothowto & RB_VERBOSE) && !VESA_MODE(bios_video_mode)) - scsplash_init(); + /* put up the splash. */ + scsplash_init(cur_console); #endif #endif } @@ -4349,52 +3906,102 @@ scshutdown(int howto, void *arg) shutdown_in_progress = TRUE; } -static void -map_mode_table(char *map[], char *table, int max) +int +sc_clean_up(scr_stat *scp) { - int i; + int error; - for(i = 0; i < max; ++i) - map[i] = table + i*MODE_PARAM_SIZE; - for(; i < MODE_MAP_SIZE; ++i) - map[i] = NULL; + if ((error = wait_scrn_saver_stop())) + return error; + scp->status &= ~MOUSE_VISIBLE; + remove_cutmarking(scp); + return 0; } -static int -map_mode_num(int mode) +void +sc_alloc_scr_buffer(scr_stat *scp, int wait, int clear) { - static struct { - int from; - int to; - } mode_map[] = { - { M_ENH_B80x43, M_ENH_B80x25 }, - { M_ENH_C80x43, M_ENH_C80x25 }, - { M_VGA_M80x30, M_VGA_M80x25 }, - { M_VGA_C80x30, M_VGA_C80x25 }, - { M_VGA_M80x50, M_VGA_M80x25 }, - { M_VGA_C80x50, M_VGA_C80x25 }, - { M_VGA_M80x60, M_VGA_M80x25 }, - { M_VGA_C80x60, M_VGA_C80x25 }, - { M_VGA_MODEX, M_VGA_CG320 }, - }; - int i; + if (scp->scr_buf) + free(scp->scr_buf, M_DEVBUF); + scp->scr_buf = (u_short *)malloc(scp->xsize*scp->ysize*sizeof(u_short), + M_DEVBUF, (wait) ? M_WAITOK : M_NOWAIT); +#ifdef PC98 + if (scp->atr_buf) + free(scp->atr_buf, M_DEVBUF); + scp->atr_buf = (u_short *)malloc(scp->xsize*scp->ysize*sizeof(u_short), + M_DEVBUF, (wait) ? M_WAITOK : M_NOWAIT); +#endif - for (i = 0; i < sizeof(mode_map)/sizeof(mode_map[0]); ++i) { - if (mode_map[i].from == mode) - return mode_map[i].to; + if (clear) { + /* clear the screen and move the text cursor to the top-left position */ + sc_clear_screen(scp); + } else { + /* retain the current cursor position, but adjust pointers */ + move_crsr(scp, scp->xpos, scp->ypos); + scp->cursor_oldpos = scp->cursor_pos; } - return mode; + + /* move the mouse cursor at the center of the screen */ + sc_move_mouse(scp, scp->xpixel / 2, scp->ypixel / 2); } -static char -*get_mode_param(scr_stat *scp, int mode) +void +sc_alloc_cut_buffer(scr_stat *scp, int wait) { - if (mode >= MODE_MAP_SIZE) - mode = map_mode_num(mode); - if (mode < MODE_MAP_SIZE) - return mode_map[mode]; - else - return NULL; + if ((cut_buffer == NULL) + || (cut_buffer_size < scp->xsize * scp->ysize + 1)) { + if (cut_buffer != NULL) + free(cut_buffer, M_DEVBUF); + cut_buffer_size = scp->xsize * scp->ysize + 1; + cut_buffer = (u_char *)malloc(cut_buffer_size, + M_DEVBUF, (wait) ? M_WAITOK : M_NOWAIT); + if (cut_buffer != NULL) + cut_buffer[0] = '\0'; + } +} + +void +sc_alloc_history_buffer(scr_stat *scp, int lines, int extra, int wait) +{ + u_short *usp; +#ifdef PC98 + u_short *atr_usp; +#endif + + 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; + } +#ifdef PC98 + atr_usp = scp->his_atr; + scp->his_atr = NULL; + if (atr_usp != NULL) + free(atr_usp, M_DEVBUF); +#endif + + 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; +#ifdef PC98 + atr_usp = (u_short *)malloc(scp->history_size * sizeof(u_short), + M_DEVBUF, (wait) ? M_WAITOK : M_NOWAIT); + if (atr_usp != NULL) + bzero(atr_usp, scp->history_size * sizeof(u_short)); + scp->his_atr_head = scp->his_atr_pos = atr_usp; + scp->his_atr = atr_usp; +#endif } static scr_stat @@ -4404,34 +4011,21 @@ static scr_stat scp = (scr_stat *)malloc(sizeof(scr_stat), M_DEVBUF, M_WAITOK); init_scp(scp); - scp->scr_buf = scp->cursor_pos = scp->cursor_oldpos = - (u_short *)malloc(scp->xsize*scp->ysize*sizeof(u_short), - M_DEVBUF, M_WAITOK); - scp->mouse_pos = scp->mouse_oldpos = - scp->scr_buf + ((scp->mouse_ypos/scp->font_size)*scp->xsize + - scp->mouse_xpos/8); - scp->history_head = scp->history_pos = - (u_short *)malloc(scp->history_size*sizeof(u_short), - M_DEVBUF, M_WAITOK); - bzero(scp->history_head, scp->history_size*sizeof(u_short)); - scp->history = scp->history_head; + sc_alloc_scr_buffer(scp, TRUE, TRUE); #ifdef PC98 - scp->atr_buf = scp->cursor_atr = scp->atr_buf = - (u_short *)malloc(scp->xsize*scp->ysize*sizeof(u_short), - M_DEVBUF, M_WAITOK); - scp->his_atr_head = scp->his_atr_pos = - (u_short *)malloc(scp->history_size*sizeof(u_short), - M_DEVBUF, M_WAITOK); - bzero(scp->his_atr_head, scp->history_size*sizeof(u_short)); - scp->his_atr = scp->his_atr_head; -#endif + sc_alloc_cut_buffer(scp, TRUE); +#else /* PC98 */ + if (ISMOUSEAVAIL(get_adapter(scp)->va_flags)) + sc_alloc_cut_buffer(scp, TRUE); +#endif /* PC98 */ + sc_alloc_history_buffer(scp, sc_history_size, 0, TRUE); /* SOS #ifndef PC98 - if (crtc_type == KD_VGA && video_mode_ptr) + if (get_adapter(scp)->va_flags & V_ADP_MODECHANGE) #endif set_mode(scp); */ - clear_screen(scp); + sc_clear_screen(scp); #ifndef PC98 scp->cursor_saveunder = *scp->cursor_pos; #endif @@ -4441,47 +4035,43 @@ static scr_stat static void init_scp(scr_stat *scp) { +#ifndef PC98 + video_info_t info; +#endif + #ifdef PC98 scp->mode = M_PC98_80x25; + scp->scr_buf = NULL; + scp->atr_buf = NULL; scp->font_size = 16; -#else - switch(crtc_type) { - case KD_VGA: - if (VESA_MODE(bios_video_mode)) - scp->mode = bios_video_mode; - else if (crtc_addr == MONO_BASE) - scp->mode = M_VGA_M80x25; - else - scp->mode = M_VGA_C80x25; - else - scp->font_size = 16; - break; - case KD_CGA: - if (crtc_addr == MONO_BASE) - scp->mode = M_B80x25; - else - scp->mode = M_C80x25; - scp->font_size = 8; - break; - case KD_EGA: - scp->mode = M_B80x25; - else - scp->mode = M_C80x25; - scp->font_size = 14; - break; - case KD_MONO: - case KD_HERCULES: - default: - scp->mode = M_EGAMONO80x25; - scp->font_size = 14; - break; - } - scp->initial_mode = scp->mode; -#endif + scp->xsize = COL; scp->ysize = ROW; scp->xpixel = scp->xsize * 8; scp->ypixel = scp->ysize * scp->font_size; +#else + scp->adp = V_ADP_PRIMARY; + (*biosvidsw.get_info)(scp->adp, initial_video_mode, &info); + + scp->status = 0; + scp->mode = scp->initial_mode = initial_video_mode; + scp->scr_buf = NULL; + if (info.vi_flags & V_INFO_GRAPHICS) { + scp->status |= GRAPHICS_MODE; + scp->xpixel = info.vi_width; + scp->ypixel = info.vi_height; + scp->xsize = info.vi_width/8; + scp->ysize = info.vi_height/info.vi_cheight; + scp->font_size = FONT_NONE; + } else { + scp->xsize = info.vi_width; + scp->ysize = info.vi_height; + scp->xpixel = scp->xsize*8; + scp->ypixel = scp->ysize*info.vi_cheight; + scp->font_size = info.vi_cheight; + } + scp->xoff = scp->yoff = 0; +#endif scp->xpos = scp->ypos = 0; scp->saved_xpos = scp->saved_ypos = -1; scp->start = scp->xsize * scp->ysize; @@ -4497,8 +4087,8 @@ init_scp(scr_stat *scp) scp->cursor_start = 0; scp->cursor_end = 0; #else - scp->cursor_start = *(char *)pa_to_va(0x461); - scp->cursor_end = *(char *)pa_to_va(0x460); + scp->cursor_start = *(u_int8_t *)pa_to_va(0x461); + scp->cursor_end = *(u_int8_t *)pa_to_va(0x460); #endif scp->mouse_xpos = scp->xsize*8/2; scp->mouse_ypos = scp->ysize*scp->font_size/2; @@ -4512,7 +4102,7 @@ init_scp(scr_stat *scp) scp->status = 0; scp->status |= CURSOR_ENABLED; #else - scp->status = (*(char *)pa_to_va(0x417) & 0x20) ? NLKED : 0; + scp->status |= (*(u_int8_t *)pa_to_va(0x417) & 0x20) ? NLKED : 0; scp->status |= CURSOR_ENABLED; #endif scp->pid = 0; @@ -4522,10 +4112,10 @@ init_scp(scr_stat *scp) #ifdef PC98 scp->his_atr_head = scp->his_atr_pos = scp->his_atr = NULL; #endif - scp->history_size = imax(SC_HISTORY_SIZE, scp->ysize) * scp->xsize; + scp->history_size = imax(sc_history_size, scp->ysize) * scp->xsize; #ifdef KANJI scp->kanji_1st_char = 0; - scp->kanji_type = 0; + scp->kanji_type = KTYPE_ASCII; #endif } @@ -5067,9 +4657,9 @@ next_code: scsplash_stick(FALSE); stop_scrn_saver(current_saver); } else { - if ((cur_console->status & UNKNOWN_MODE) == 0) { + if (!ISGRAPHSC(cur_console)) { scsplash_stick(TRUE); - (*current_saver)(TRUE); + scrn_saver(current_saver, TRUE); } } } @@ -5272,10 +4862,10 @@ mask2attr(struct term_stat *term) return attr; } +#ifndef PC98 static void set_keyboard(int command, int data) { -#ifndef PC98 int s; if (sc_kbdc == NULL) @@ -5323,14 +4913,13 @@ set_keyboard(int command, int data) splx(s); #endif kbdc_lock(sc_kbdc, FALSE); -#endif } +#endif static void update_leds(int which) { #ifndef PC98 - int s; static u_char xlate_leds[8] = { 0, 4, 2, 6, 1, 5, 3, 7 }; /* replace CAPS led with ALTGR led for ALTGR keyboards */ @@ -5345,31 +4934,66 @@ update_leds(int which) #endif } -void +int set_mode(scr_stat *scp) { - char special_modetable[MODE_PARAM_SIZE]; - char *mp; - int s; - int i; +#ifndef PC98 + video_info_t info; + video_adapter_t *adp; + + /* reject unsupported mode */ + if ((*biosvidsw.get_info)(scp->adp, scp->mode, &info)) + return 1; + /* if this vty is not currently showing, do nothing */ if (scp != cur_console) - return; + return 0; -#ifndef PC98 - /* - * even if mode switching is disabled, we can change back - * to the initial mode or the custom mode based on the initial - * mode if we have saved register values upon start-up. - */ - mp = get_mode_param(scp, scp->mode); - if (mp == NULL) - return; - bcopy(mp, &special_modetable, sizeof(special_modetable)); -#endif + /* setup video hardware for the given mode */ + adp = get_adapter(scp); + (*biosvidsw.set_mode)(scp->adp, scp->mode); + Crtat = (u_short *)adp->va_window; + + if (!(scp->status & GRAPHICS_MODE)) { + /* load appropriate font */ + if (!(scp->status & PIXEL_MODE) + && ISFONTAVAIL(get_adapter(scp)->va_flags)) { + if (scp->font_size < 14) { + if (fonts_loaded & FONT_8) + copy_font(scp, LOAD, 8, font_8); + } else if (scp->font_size >= 16) { + if (fonts_loaded & FONT_16) + copy_font(scp, LOAD, 16, font_16); + } else { + if (fonts_loaded & FONT_14) + copy_font(scp, LOAD, 14, font_14); + } + /* + * FONT KLUDGE: + * This is an interim kludge to display correct font. + * Always use the font page #0 on the video plane 2. + * Somehow we cannot show the font in other font pages on + * some video cards... XXX + */ + (*biosvidsw.show_font)(scp->adp, 0); + } + mark_all(scp); + } + + if (scp->status & PIXEL_MODE) + generic_bzero((u_char *)(adp->va_window), scp->xpixel*scp->ypixel/8); + set_border(scp, scp->border); + + /* move hardware cursor out of the way */ + (*biosvidsw.set_hw_cursor)(scp->adp, -1, -1); + + return 0; +#else /* PC98 */ + + if (scp != cur_console) + return 1; /* setup video hardware for the given mode */ -#ifdef PC98 #ifdef LINE30 switch (scp->mode) { case M_PC98_80x25: /* VGA TEXT MODES */ @@ -5388,439 +5012,86 @@ set_mode(scr_stat *scp) outb(0xA2, 0xd); /* graphics on */ } else { while (!(inb(0x60) & 0x20)) {} /* V-SYNC wait */ - outb(0x62, 0xd); /* text on */ - outb(0xA2, 0xc); /* graphics off */ - } -#else /* IBM-PC */ - switch (scp->mode) { - case M_VGA_C80x60: case M_VGA_M80x60: - special_modetable[2] = 0x08; - special_modetable[19] = 0x47; - goto special_480l; - - case M_VGA_C80x30: case M_VGA_M80x30: - special_modetable[19] = 0x4f; -special_480l: - special_modetable[9] |= 0xc0; - special_modetable[16] = 0x08; - special_modetable[17] = 0x3e; - special_modetable[26] = 0xea; - special_modetable[28] = 0xdf; - special_modetable[31] = 0xe7; - special_modetable[32] = 0x04; - goto setup_mode; - - case M_ENH_C80x43: case M_ENH_B80x43: - special_modetable[28] = 87; - goto special_80x50; - - case M_VGA_C80x50: case M_VGA_M80x50: -special_80x50: - special_modetable[2] = 8; - special_modetable[19] = 7; - goto setup_mode; - - case M_VGA_C40x25: case M_VGA_C80x25: - case M_VGA_M80x25: - case M_B40x25: case M_C40x25: - case M_B80x25: case M_C80x25: - case M_ENH_B40x25: case M_ENH_C40x25: - case M_ENH_B80x25: case M_ENH_C80x25: - case M_EGAMONO80x25: - -setup_mode: - set_vgaregs(special_modetable); - scp->font_size = special_modetable[2]; - - /* set font type (size) */ - if (scp->font_size < 14) { - if (fonts_loaded & FONT_8) - copy_font(LOAD, FONT_8, font_8); - i = 0x0a; /* font 2 */ - } else if (scp->font_size >= 16) { - if (fonts_loaded & FONT_16) - copy_font(LOAD, FONT_16, font_16); - i = 0x00; /* font 0 */ - } else { - if (fonts_loaded & FONT_14) - copy_font(LOAD, FONT_14, font_14); - i = 0x05; /* font 1 */ + outb(0x62, 0xd); /* text off */ + outb(0xA2, 0xc); /* graphics on */ } - /* - * FONT KLUDGE: - * This is an interim kludge to display correct font. - * Always use the font page #0 on the video plane 2. - * Somehow we cannot show the font in other font pages on - * some video cards... XXX - */ - i = 0x00; - s = splhigh(); - outb(TSIDX, 0x00); outb(TSREG, 0x01); - outb(TSIDX, 0x03); outb(TSREG, i); - outb(TSIDX, 0x00); outb(TSREG, 0x03); - splx(s); - if (flags & CHAR_CURSOR) - set_destructive_cursor(scp); - mark_all(scp); - break; - - case M_VGA_MODEX: - /* "unchain" the VGA mode */ - special_modetable[5-1+0x04] &= 0xf7; - special_modetable[5-1+0x04] |= 0x04; - /* turn off doubleword mode */ - special_modetable[10+0x14] &= 0xbf; - /* turn off word adressing */ - special_modetable[10+0x17] |= 0x40; - /* set logical screen width */ - special_modetable[10+0x13] = 80; - /* set 240 lines */ - special_modetable[10+0x11] = 0x2c; - special_modetable[10+0x06] = 0x0d; - special_modetable[10+0x07] = 0x3e; - special_modetable[10+0x10] = 0xea; - special_modetable[10+0x11] = 0xac; - special_modetable[10+0x12] = 0xdf; - special_modetable[10+0x15] = 0xe7; - special_modetable[10+0x16] = 0x06; - /* set vertical sync polarity to reflect aspect ratio */ - special_modetable[9] = 0xe3; - goto setup_grmode; - - case M_BG320: case M_CG320: case M_BG640: - case M_CG320_D: case M_CG640_E: - case M_CG640x350: case M_ENH_CG640: - case M_BG640x480: case M_CG640x480: case M_VGA_CG320: - -setup_grmode: - set_vgaregs(special_modetable); - scp->font_size = FONT_NONE; - break; - - default: - /* call user defined function XXX */ - break; - } -#endif /* PC98 */ /* set border color for this (virtual) console */ - set_border(scp->border); - return; + set_border(scp, scp->border); + return 0; +#endif /* PC98 */ } void -set_border(u_char color) +set_border(scr_stat *scp, int color) { +#ifndef PC98 + u_char *p; + int xoff; + int yoff; + int xlen; + int ylen; + int i; + + (*biosvidsw.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 = (u_char *)(get_adapter(scp)->va_window); + xoff = scp->xoff; + yoff = scp->yoff*scp->font_size; + xlen = scp->xpixel/8; + ylen = scp->ysize*scp->font_size; + if (yoff > 0) { + generic_bzero(p, xlen*yoff); + generic_bzero(p + xlen*(yoff + ylen), + xlen*scp->ypixel - xlen*(yoff + ylen)); + } + if (xoff > 0) { + for (i = 0; i < ylen; ++i) { + generic_bzero(p + xlen*(yoff + i), xoff); + generic_bzero(p + xlen*(yoff + i) + xoff + scp->xsize, + xlen - xoff - scp->xsize); + } + } + outw(GDCIDX, 0x0000); /* set/reset */ + outw(GDCIDX, 0x0001); /* set/reset enable */ + } +#else /* PC98 */ switch (crtc_type) { -#ifdef PC98 case KD_PC98: outb(0x6c, color << 4); break; -#else - case KD_EGA: - case KD_VGA: - inb(crtc_addr + 6); /* reset flip-flop */ - outb(ATC, 0x31); outb(ATC, color); - break; - case KD_CGA: - outb(crtc_addr + 5, color & 0x0f); /* color select register */ - break; - case KD_MONO: - case KD_HERCULES: -#endif default: break; } +#endif /* PC98 */ } -#ifndef PC98 -static void -set_vgaregs(char *modetable) -{ - int i, s = splhigh(); - - outb(TSIDX, 0x00); outb(TSREG, 0x01); /* stop sequencer */ - for (i=0; i<4; i++) { /* program sequencer */ - outb(TSIDX, i+1); - outb(TSREG, modetable[i+5]); - } - outb(MISC, modetable[9]); /* set dot-clock */ - outb(TSIDX, 0x00); outb(TSREG, 0x03); /* start sequencer */ - outb(crtc_addr, 0x11); - outb(crtc_addr+1, inb(crtc_addr+1) & 0x7F); - for (i=0; i<25; i++) { /* program crtc */ - outb(crtc_addr, i); - if (i == 14 || i == 15) /* no hardware cursor */ - outb(crtc_addr+1, 0xff); - else - outb(crtc_addr+1, modetable[i+10]); - } - inb(crtc_addr+6); /* reset flip-flop */ - for (i=0; i<20; i++) { /* program attribute ctrl */ - outb(ATC, i); - outb(ATC, modetable[i+35]); - } - for (i=0; i<9; i++) { /* program graph data ctrl */ - outb(GDCIDX, i); - outb(GDCREG, modetable[i+55]); - } - inb(crtc_addr+6); /* reset flip-flop */ - outb(ATC, 0x20); /* enable palette */ - splx(s); -} - -static void -read_vgaregs(char *buf) -{ - int i, j; - int s; - - bzero(buf, MODE_PARAM_SIZE); - - s = splhigh(); - - outb(TSIDX, 0x00); outb(TSREG, 0x01); /* stop sequencer */ - for (i=0, j=5; i<4; i++) { - outb(TSIDX, i+1); - buf[j++] = inb(TSREG); - } - buf[9] = inb(MISC + 10); /* dot-clock */ - outb(TSIDX, 0x00); outb(TSREG, 0x03); /* start sequencer */ - - for (i=0, j=10; i<25; i++) { /* crtc */ - outb(crtc_addr, i); - buf[j++] = inb(crtc_addr+1); - } - for (i=0, j=35; i<20; i++) { /* attribute ctrl */ - inb(crtc_addr+6); /* reset flip-flop */ - outb(ATC, i); - buf[j++] = inb(ATC + 1); - } - for (i=0, j=55; i<9; i++) { /* graph data ctrl */ - outb(GDCIDX, i); - buf[j++] = inb(GDCREG); - } - inb(crtc_addr+6); /* reset flip-flop */ - outb(ATC, 0x20); /* enable palette */ - - buf[0] = *(char *)pa_to_va(0x44a); /* COLS */ - buf[1] = *(char *)pa_to_va(0x484); /* ROWS */ - buf[2] = *(char *)pa_to_va(0x485); /* POINTS */ - buf[3] = *(char *)pa_to_va(0x44c); - buf[4] = *(char *)pa_to_va(0x44d); - - splx(s); -} - -static int -comp_vgaregs(u_char *buf1, u_char *buf2) -{ - static struct { - u_char mask; - } params[MODE_PARAM_SIZE] = { - 0xff, 0x00, 0xff, /* COLS, ROWS, POINTS */ - 0xff, 0xff, /* page length */ - 0xfe, 0xff, 0xff, 0xff, /* sequencer registers */ - 0xf3, /* misc register */ - 0xff, 0xff, 0xff, 0x7f, 0xff, /* CRTC */ - 0xff, 0xff, 0xff, 0x7f, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xff, 0x7f, 0xff, 0xff, - 0x7f, 0xff, 0xff, 0xef, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, /* attribute controller registers */ - 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xf0, - 0xff, 0xff, 0xff, 0xff, 0xff, /* GDC register */ - 0xff, 0xff, 0xff, 0xff, - }; - int identical = TRUE; - int i; - - for (i = 0; i < sizeof(params)/sizeof(params[0]); ++i) { - if (params[i].mask == 0) /* don't care */ - continue; - if ((buf1[i] & params[i].mask) != (buf2[i] & params[i].mask)) - return COMP_DIFFERENT; - if (buf1[i] != buf2[i]) - identical = FALSE; - } - return (identical) ? COMP_IDENTICAL : COMP_SIMILAR; - -#if 0 - for(i = 0; i < 20; ++i) { - if (*buf1++ != *buf2++) - return COMP_DIFFERENT; - } - buf1 += 2; /* skip the cursor shape */ - buf2 += 2; - for(i = 22; i < 24; ++i) { - if (*buf1++ != *buf2++) - return COMP_DIFFERENT; - } - buf1 += 2; /* skip the cursor position */ - buf2 += 2; - for(i = 26; i < MODE_PARAM_SIZE; ++i) { - if (*buf1++ != *buf2++) - return COMP_DIFFERENT; - } - return COMP_IDENTICAL; -#endif -} - -static void -dump_vgaregs(u_char *buf) -{ - int i; - - for(i = 0; i < MODE_PARAM_SIZE;) { - printf("%02x ", buf[i]); - if ((++i % 16) == 0) - printf("\n"); - } -} - -static void -set_font_mode(u_char *buf) -{ - int s = splhigh(); - - font_loading_in_progress = TRUE; - - /* save register values */ - outb(TSIDX, 0x02); buf[0] = inb(TSREG); - outb(TSIDX, 0x04); buf[1] = inb(TSREG); - outb(GDCIDX, 0x04); buf[2] = inb(GDCREG); - outb(GDCIDX, 0x05); buf[3] = inb(GDCREG); - outb(GDCIDX, 0x06); buf[4] = inb(GDCREG); - inb(crtc_addr + 6); - outb(ATC, 0x10); buf[5] = inb(ATC + 1); - - /* setup vga for loading fonts */ - inb(crtc_addr+6); /* reset flip-flop */ - outb(ATC, 0x10); outb(ATC, buf[5] & ~0x01); - inb(crtc_addr+6); /* reset flip-flop */ - outb(ATC, 0x20); /* enable palette */ - -#if SLOW_VGA -#ifndef SC_BAD_FLICKER - outb(TSIDX, 0x00); outb(TSREG, 0x01); -#endif - outb(TSIDX, 0x02); outb(TSREG, 0x04); - outb(TSIDX, 0x04); outb(TSREG, 0x07); -#ifndef SC_BAD_FLICKER - outb(TSIDX, 0x00); outb(TSREG, 0x03); -#endif - outb(GDCIDX, 0x04); outb(GDCREG, 0x02); - outb(GDCIDX, 0x05); outb(GDCREG, 0x00); - outb(GDCIDX, 0x06); outb(GDCREG, 0x04); -#else -#ifndef SC_BAD_FLICKER - outw(TSIDX, 0x0100); -#endif - outw(TSIDX, 0x0402); - outw(TSIDX, 0x0704); -#ifndef SC_BAD_FLICKER - outw(TSIDX, 0x0300); -#endif - outw(GDCIDX, 0x0204); - outw(GDCIDX, 0x0005); - outw(GDCIDX, 0x0406); /* addr = a0000, 64kb */ -#endif - splx(s); -} - -static void -set_normal_mode(u_char *buf) -{ - char *modetable; - int s = splhigh(); - - /* setup vga for normal operation mode again */ - inb(crtc_addr+6); /* reset flip-flop */ - outb(ATC, 0x10); outb(ATC, buf[5]); - inb(crtc_addr+6); /* reset flip-flop */ - outb(ATC, 0x20); /* enable palette */ - -#if SLOW_VGA -#ifndef SC_BAD_FLICKER - outb(TSIDX, 0x00); outb(TSREG, 0x01); -#endif - outb(TSIDX, 0x02); outb(TSREG, buf[0]); - outb(TSIDX, 0x04); outb(TSREG, buf[1]); -#ifndef SC_BAD_FLICKER - outb(TSIDX, 0x00); outb(TSREG, 0x03); -#endif - outb(GDCIDX, 0x04); outb(GDCREG, buf[2]); - outb(GDCIDX, 0x05); outb(GDCREG, buf[3]); - if (crtc_addr == MONO_BASE) { - outb(GDCIDX, 0x06); outb(GDCREG,(buf[4] & 0x03) | 0x08); - } else { - outb(GDCIDX, 0x06); outb(GDCREG,(buf[4] & 0x03) | 0x0c); - } -#else -#ifndef SC_BAD_FLICKER - outw(TSIDX, 0x0100); -#endif - outw(TSIDX, 0x0002 | (buf[0] << 8)); - outw(TSIDX, 0x0004 | (buf[1] << 8)); -#ifndef SC_BAD_FLICKER - outw(TSIDX, 0x0300); -#endif - outw(GDCIDX, 0x0004 | (buf[2] << 8)); - outw(GDCIDX, 0x0005 | (buf[3] << 8)); - if (crtc_addr == MONO_BASE) - outw(GDCIDX, 0x0006 | (((buf[4] & 0x03) | 0x08)<<8)); - else - outw(GDCIDX, 0x0006 | (((buf[4] & 0x03) | 0x0c)<<8)); -#endif - - font_loading_in_progress = FALSE; - splx(s); -} -#endif - void -copy_font(int operation, int font_type, char* font_image) +copy_font(scr_stat *scp, int operation, int font_size, u_char *buf) { #ifndef PC98 - int ch, line, segment, fontsize; - u_char buf[PARAM_BUFSIZE]; - u_char val; - - switch (font_type) { - default: - case FONT_8: - segment = 0x8000; - fontsize = 8; - break; - case FONT_14: - segment = 0x4000; - fontsize = 14; - break; - case FONT_16: - segment = 0x0000; - fontsize = 16; - break; - } /* - * FONT KLUDGE - * Always use the font page #0. XXX - */ - segment = 0x0000; - outb(TSIDX, 0x01); val = inb(TSREG); /* disable screen */ - outb(TSIDX, 0x01); outb(TSREG, val | 0x20); - set_font_mode(buf); - for (ch=0; ch < 256; ch++) - for (line=0; line < fontsize; line++) - if (operation) - *(char *)pa_to_va(VIDEOMEM+(segment)+(ch*32)+line) = - font_image[(ch*fontsize)+line]; - else - font_image[(ch*fontsize)+line] = - *(char *)pa_to_va(VIDEOMEM+(segment)+(ch*32)+line); - set_normal_mode(buf); - outb(TSIDX, 0x01); outb(TSREG, val & 0xDF); /* enable screen */ + * FONT KLUDGE: + * This is an interim kludge to display correct font. + * Always use the font page #0 on the video plane 2. + * Somehow we cannot show the font in other font pages on + * some video cards... XXX + */ + font_loading_in_progress = TRUE; + if (operation == LOAD) { + (*biosvidsw.load_font)(scp->adp, 0, font_size, buf, 0, 256); + if (sc_flags & CHAR_CURSOR) + set_destructive_cursor(scp); + } else if (operation == SAVE) { + (*biosvidsw.save_font)(scp->adp, 0, font_size, buf, 0, 256); + } + font_loading_in_progress = FALSE; #endif } @@ -5828,29 +5099,25 @@ static void set_destructive_cursor(scr_stat *scp) { #ifndef PC98 - u_char buf[PARAM_BUFSIZE]; u_char cursor[32]; - caddr_t address; + u_char *font_buffer; + int font_size; int i; - char *font_buffer; + + if (!ISFONTAVAIL(get_adapter(scp)->va_flags) + || (scp->status & (GRAPHICS_MODE | PIXEL_MODE))) + return; if (scp->font_size < 14) { font_buffer = font_8; - address = (caddr_t)VIDEOMEM + 0x8000; - } - else if (scp->font_size >= 16) { + font_size = 8; + } else if (scp->font_size >= 16) { font_buffer = font_16; - address = (caddr_t)VIDEOMEM; - } - else { + font_size = 16; + } else { font_buffer = font_14; - address = (caddr_t)VIDEOMEM + 0x4000; + font_size = 14; } - /* - * FONT KLUDGE - * Always use the font page #0. XXX - */ - address = (caddr_t)VIDEOMEM; if (scp->status & MOUSE_VISIBLE) { if ((scp->cursor_saveunder & 0xff) == SC_MOUSE_CHAR) @@ -5875,12 +5142,21 @@ set_destructive_cursor(scr_stat *scp) #if 1 while (!(inb(crtc_addr+6) & 0x08)) /* wait for vertical retrace */ ; #endif - set_font_mode(buf); - generic_bcopy(cursor, (char *)pa_to_va(address) + DEAD_CHAR * 32, 32); - set_normal_mode(buf); + font_loading_in_progress = TRUE; + (*biosvidsw.load_font)(scp->adp, 0, font_size, cursor, DEAD_CHAR, 1); + font_loading_in_progress = FALSE; #endif } +void +sc_move_mouse(scr_stat *scp, int x, int y) +{ + scp->mouse_xpos = x; + scp->mouse_ypos = y; + scp->mouse_pos = scp->mouse_oldpos = + scp->scr_buf + (y / scp->font_size) * scp->xsize + x / 8; +} + static void set_mouse_pos(scr_stat *scp) { @@ -5890,7 +5166,7 @@ set_mouse_pos(scr_stat *scp) scp->mouse_xpos = 0; if (scp->mouse_ypos < 0) scp->mouse_ypos = 0; - if (scp->status & UNKNOWN_MODE) { + if (!ISTEXTSC(scp)) { if (scp->mouse_xpos > scp->xpixel-1) scp->mouse_xpos = scp->xpixel-1; if (scp->mouse_ypos > scp->ypixel-1) @@ -6123,35 +5399,27 @@ draw_mouse_image(scr_stat *scp) #ifdef PC98 *(Atrat + (scp->mouse_pos - scp->scr_buf)) ^= 0x4; /* reverse bit */ #else - caddr_t address; - int i; - char *font_buffer; - u_char buf[PARAM_BUFSIZE]; u_short buffer[32]; u_short xoffset, yoffset; - u_short *crt_pos = Crtat + (scp->mouse_pos - scp->scr_buf); - int font_size = scp->font_size; + u_short *crt_pos = (u_short *)(get_adapter(scp)->va_window) + + (scp->mouse_pos - scp->scr_buf); + u_char *font_buffer; + int font_size; + int i; - if (font_size < 14) { + if (scp->font_size < 14) { font_buffer = font_8; - address = (caddr_t)VIDEOMEM + 0x8000; - } - else if (font_size >= 16) { + font_size = 8; + } else if (scp->font_size >= 16) { font_buffer = font_16; - address = (caddr_t)VIDEOMEM; - } - else { + font_size = 16; + } else { font_buffer = font_14; - address = (caddr_t)VIDEOMEM + 0x4000; + font_size = 14; } - /* - * FONT KLUDGE - * Always use the font page #0. XXX - */ - address = (caddr_t)VIDEOMEM; xoffset = scp->mouse_xpos % 8; - yoffset = scp->mouse_ypos % font_size; + yoffset = scp->mouse_ypos % scp->font_size; /* prepare mousepointer char's bitmaps */ bcopy(font_buffer + ((*(scp->mouse_pos) & 0xff) * font_size), @@ -6180,15 +5448,18 @@ draw_mouse_image(scr_stat *scp) scp->mouse_cursor[i+96] = buffer[i+font_size] & 0xff; } #endif + scp->mouse_oldpos = scp->mouse_pos; #ifndef PC98 #if 1 /* wait for vertical retrace to avoid jitter on some videocards */ while (!(inb(crtc_addr+6) & 0x08)) /* idle */ ; #endif - set_font_mode(buf); - generic_bcopy(scp->mouse_cursor, (char *)pa_to_va(address) + SC_MOUSE_CHAR * 32, 128); - set_normal_mode(buf); + font_loading_in_progress = TRUE; + (*biosvidsw.load_font)(scp->adp, 0, 32, scp->mouse_cursor, + SC_MOUSE_CHAR, 4); + font_loading_in_progress = FALSE; + *(crt_pos) = (*(scp->mouse_pos) & 0xff00) | SC_MOUSE_CHAR; *(crt_pos+scp->xsize) = (*(scp->mouse_pos + scp->xsize) & 0xff00) | (SC_MOUSE_CHAR + 2); @@ -6207,10 +5478,16 @@ draw_mouse_image(scr_stat *scp) static void remove_mouse_image(scr_stat *scp) { + u_short *crt_pos; + + if (!ISTEXTSC(scp)) + return; + #ifdef PC98 - u_short *crt_pos = Atrat + (scp->mouse_oldpos - scp->scr_buf); + crt_pos = Atrat + (scp->mouse_oldpos - scp->scr_buf); #else - u_short *crt_pos = Crtat + (scp->mouse_oldpos - scp->scr_buf); + crt_pos = (u_short *)(get_adapter(scp)->va_window) + + (scp->mouse_oldpos - scp->scr_buf); #endif #ifdef PC98 @@ -6230,15 +5507,17 @@ remove_mouse_image(scr_stat *scp) static void draw_cutmarking(scr_stat *scp) { + u_short *crt_pos; u_short *ptr; u_short och, nch; - for (ptr=scp->scr_buf; ptr<=(scp->scr_buf+(scp->xsize*scp->ysize)); ptr++) { #ifdef PC98 - nch = och = *(Atrat + (ptr - scp->scr_buf)); + crt_pos = Atrat; #else - nch = och = *(Crtat + (ptr - scp->scr_buf)); + crt_pos = (u_short *)(get_adapter(scp)->va_window); #endif + for (ptr=scp->scr_buf; ptr<=(scp->scr_buf+(scp->xsize*scp->ysize)); ptr++) { + nch = och = *(crt_pos + (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) || @@ -6263,20 +5542,16 @@ draw_cutmarking(scr_stat *scp) if (ptr != scp->cursor_pos) nch = (och & 0x88ff) | (*ptr & 0x7000)>>4 | (*ptr & 0x0700)<<4; else { - if (flags & CHAR_CURSOR) + if (sc_flags & CHAR_CURSOR) nch = (och & 0x88ff)|(*ptr & 0x7000)>>4|(*ptr & 0x0700)<<4; else - if (!(flags & BLINK_CURSOR)) + if (!(sc_flags & BLINK_CURSOR)) nch = (och & 0xff) | (*ptr & 0xff00); } #endif } if (nch != och) -#ifdef PC98 - *(Atrat + (ptr - scp->scr_buf)) = nch; -#else - *(Crtat + (ptr - scp->scr_buf)) = nch; -#endif + *(crt_pos + (ptr - scp->scr_buf)) = nch; } } @@ -6289,43 +5564,15 @@ remove_cutmarking(scr_stat *scp) } static void -save_palette(void) -{ -#ifndef PC98 - int i; - - outb(PALRADR, 0x00); - for (i=0x00; i<0x300; i++) - palette[i] = inb(PALDATA); - inb(crtc_addr+6); /* reset flip/flop */ -#endif -} - -void -load_palette(char *palette) -{ -#ifndef PC98 - int i; - - outb(PIXMASK, 0xFF); /* no pixelmask */ - outb(PALWADR, 0x00); - for (i=0x00; i<0x300; i++) - outb(PALDATA, palette[i]); - inb(crtc_addr+6); /* reset flip/flop */ - outb(ATC, 0x20); /* enable palette */ -#endif -} - -static void do_bell(scr_stat *scp, int pitch, int duration) { if (cold || shutdown_in_progress) return; - if (scp != cur_console && (flags & QUIET_BELL)) + if (scp != cur_console && (sc_flags & QUIET_BELL)) return; - if (flags & VISUAL_BELL) { + if (sc_flags & VISUAL_BELL) { if (blink_in_progress) return; blink_in_progress = 4; @@ -6344,7 +5591,7 @@ blink_screen(void *arg) { scr_stat *scp = arg; - if ((scp->status & UNKNOWN_MODE) || (blink_in_progress <= 1)) { + if (!ISTEXTSC(scp) || (blink_in_progress <= 1)) { blink_in_progress = FALSE; mark_all(scp); if (delayed_next_scr) @@ -6366,10 +5613,12 @@ blink_screen(void *arg) #else if (blink_in_progress & 1) fillw(kernel_default.std_color | scr_map[0x20], - Crtat, scp->xsize * scp->ysize); + (u_short *)(get_adapter(scp)->va_window), + scp->xsize * scp->ysize); else fillw(kernel_default.rev_color | scr_map[0x20], - Crtat, scp->xsize * scp->ysize); + (u_short *)(get_adapter(scp)->va_window), + scp->xsize * scp->ysize); #endif blink_in_progress--; timeout(blink_screen, scp, hz / 10); @@ -6379,8 +5628,10 @@ blink_screen(void *arg) void sc_bcopy(scr_stat *scp, u_short *p, int from, int to, int mark) { - if (!VESA_MODE(scp->mode)) { - generic_bcopy(p+from, Crtat+from, (to-from+1)*sizeof (u_short)); +#ifdef PC98 + if (ISTEXTSC(scp)) { + generic_bcopy(p + from, Crtat + from, + (to - from + 1)*sizeof(u_short)); } else if (scp->mode == 0x102) { u_char *d, *e; int i,j; @@ -6400,41 +5651,137 @@ sc_bcopy(scr_stat *scp, u_short *p, int from, int to, int mark) d += 20 + 15*100; } } +#else /* PC98 */ + u_char *font; + u_char volatile *d; + u_char *e; + u_char *f; + int font_size; + int line_length; + int xsize; + u_short bg; + int i, j; + u_char c; + + if (ISTEXTSC(scp)) { + generic_bcopy(p + from, (u_short *)(get_adapter(scp)->va_window) + 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 = (u_char *)(get_adapter(scp)->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 */ + *d = 0; + c = *d; /* set the background color in the latch */ + } + /* 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++) { + outw(GDCIDX, ((*f^mark) << 8) | 0x08); /* bit mask */ + *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 /* PC98 */ } #ifdef SC_SPLASH_SCREEN static void -scsplash_init(void) +scsplash_init(scr_stat *scp) { -#ifndef PC98 - /* - * We currently assume the splash screen always use - * VGA_CG320 mode and abort installation if this mode is not - * supported with this video card. XXX - */ - if (crtc_type != KD_VGA || get_mode_param(cur_console, M_VGA_CG320) == NULL) - return; -#endif + video_info_t info; - if (splash_load() == 0 && add_scrn_saver(scsplash) == 0) { - default_saver = scsplash; + if (scsplash_load(scp) == 0 && add_scrn_saver(scsplash_saver) == 0) { + default_saver = scsplash_saver; scrn_blank_time = DEFAULT_BLANKTIME; run_scrn_saver = TRUE; - if (!(boothowto & RB_CONFIG)) { + if (!(boothowto & (RB_VERBOSE | RB_CONFIG))) { scsplash_stick(TRUE); - scsplash(TRUE); + scsplash_saver(TRUE); } } } static void -scsplash(int show) +scsplash_term(scr_stat *scp) +{ + default_saver = none_saver; + scsplash_stick(FALSE); + remove_scrn_saver(scsplash_saver); + scsplash_unload(scp); +} + +static void +scsplash_saver(int show) { if (show) - splash(TRUE); + scsplash(TRUE); else if (!sticky_splash) - splash(FALSE); + scsplash(FALSE); } #endif /* SC_SPLASH_SCREEN */ diff --git a/sys/pc98/pc98/syscons.h b/sys/pc98/pc98/syscons.h index 3d4b8d3..49471a9 100644 --- a/sys/pc98/pc98/syscons.h +++ b/sys/pc98/pc98/syscons.h @@ -1,18 +1,18 @@ /*- - * Copyright (c) 1995 Sen Schmidt + * Copyright (c) 1992-1998 Sen Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. + * notice, this list of conditions and the following disclaimer, + * without modification, immediately at the beginning of the file. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission + * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: syscons.h,v 1.24 1998/08/03 10:50:57 kato Exp $ + * $Id: syscons.h,v 1.25 1998/08/07 11:51:06 kato Exp $ */ #ifndef _PC98_PC98_SYSCONS_H_ @@ -38,8 +38,13 @@ #define pa_to_va(pa) (KERNBASE + (pa)) /* works if ISMAPPED(pa...) */ /* printable chars */ +#ifdef PC98 +#define PRINTABLE(ch) ((ch) > 0x1b || ((ch) > 0x0f && (ch) < 0x1b) \ + || (ch) < 0x07) +#else #define PRINTABLE(ch) ((ch) > 0x1b || ((ch) > 0x0d && (ch) < 0x1b) \ || (ch) < 0x07) +#endif /* macros for "intelligent" screen update */ #define mark_for_update(scp, x) {\ @@ -65,6 +70,9 @@ #define MOUSE_MOVED 0x01000 #define MOUSE_CUTTING 0x02000 #define MOUSE_VISIBLE 0x04000 +#define GRAPHICS_MODE 0x08000 +#define PIXEL_MODE 0x10000 +#define SAVER_RUNNING 0x20000 /* configuration flags */ #define VISUAL_BELL 0x00001 @@ -74,6 +82,7 @@ #define XT_KEYBD 0x00010 #define KBD_NORESET 0x00020 #define QUIET_BELL 0x00040 +#define VESA800X600 0x00080 /* attribute flags */ #define NORMAL_ATTR 0x00 @@ -84,9 +93,6 @@ #define FOREGROUND_CHANGED 0x10 #define BACKGROUND_CHANGED 0x20 -/* video hardware memory addresses */ -#define VIDEOMEM 0x000A0000 - /* misc defines */ #define FALSE 0 #define TRUE 1 @@ -111,24 +117,11 @@ static unsigned int BELL_PITCH = 1678; #define FONT_14 4 #define FONT_16 8 -/* defines related to hardware addresses */ #ifdef PC98 +/* defines related to hardware addresses */ #define TEXT_GDC IO_GDC1 /* 0x60 */ #define TEXT_VRAM (KERNBASE+0xA0000) #define ATTR_OFFSET 0x1000 -#else /* IBM */ -#define MONO_BASE 0x3B4 /* crt controller base mono */ -#define COLOR_BASE 0x3D4 /* crt controller base color */ -#define MISC 0x3C2 /* misc output register */ -#define ATC IO_VGA+0x00 /* attribute controller */ -#define TSIDX IO_VGA+0x04 /* timing sequencer idx */ -#define TSREG IO_VGA+0x05 /* timing sequencer data */ -#define PIXMASK IO_VGA+0x06 /* pixel write mask */ -#define PALRADR IO_VGA+0x07 /* palette read address */ -#define PALWADR IO_VGA+0x08 /* palette write address */ -#define PALDATA IO_VGA+0x09 /* palette data register */ -#define GDCIDX IO_VGA+0x0E /* graph data controller idx */ -#define GDCREG IO_VGA+0x0F /* graph data controller data */ #endif /* special characters */ @@ -154,6 +147,7 @@ typedef struct term_stat { } term_stat; typedef struct scr_stat { + int adp; /* video adapter index */ u_short *scr_buf; /* buffer when off screen */ #ifdef PC98 u_short *atr_buf; /* buffer when off screen */ @@ -167,6 +161,8 @@ typedef struct scr_stat { int ysize; /* Y text size */ int xpixel; /* X graphics size */ int ypixel; /* Y graphics size */ + int xoff; /* X offset in pixel mode */ + int yoff; /* Y offset in pixel mode */ int font_size; /* fontsize in Y direction */ int start; /* modified area start */ int end; /* modified area end */ @@ -213,13 +209,31 @@ typedef struct scr_stat { int history_size; /* size of history buffer */ struct apmhook r_hook; /* reconfiguration support */ #ifdef SC_SPLASH_SCREEN - u_char splash_save_mode; /* saved mode for splash screen */ + int splash_save_mode; /* saved mode for splash screen */ + int splash_save_status; /* saved status for splash screen */ #endif #ifdef KANJI u_char kanji_1st_char; - u_char kanji_type; /* 0: ASCII CODE 1: HANKAKU ? */ - /* 2: SHIFT JIS 4: EUC */ +#define KTYPE_ASCII 0 +#define KTYPE_KANA 1 +#define KTYPE_JKANA 0x10 +#define KTYPE_7JIS 0x20 +#define KTYPE_SJIS 2 +#define KTYPE_UJIS 4 +#define KTYPE_SUKANA 3 +#define KTYPE_SUJIS 6 +#define KTYPE_KANIN 0x80 +#define KTYPE_ASCIN 0x40 + u_char kanji_type; /* 0: Ascii code 1: HANKAKU */ + /* 2: Shift JIS 4: UJIS */ + /* 3: Shift JIS or UJIS HANKAKU */ + /* 6: Shift JIS or UJIS */ /* 0x10: JIS HANKAKU 0x20: JIS */ + /* 0x80: Kanji Invoke sequence */ + /* 0x40: Ascii Invoke sequence */ +#define IS_KTYPE_ASCII_or_HANKAKU(A) (!((A) & 0xee)) +#define IS_KTYPE_KANA(A) ((A) & 0x11) +#define KTYPE_MASK_CTRL(A) ((A) &= 0xF0) #endif } scr_stat; @@ -228,22 +242,64 @@ typedef struct default_attr { int rev_color; /* reverse hardware color */ } default_attr; + +#define ISTEXTSC(scp) (!((scp)->status \ + & (UNKNOWN_MODE | GRAPHICS_MODE | PIXEL_MODE))) +#define ISGRAPHSC(scp) (((scp)->status \ + & (UNKNOWN_MODE | GRAPHICS_MODE))) +#define ISPIXELSC(scp) (((scp)->status \ + & (UNKNOWN_MODE | GRAPHICS_MODE | PIXEL_MODE))\ + == PIXEL_MODE) +#define ISUNKNOWNSC(scp) ((scp)->status & UNKNOWN_MODE) + +#define ISFONTAVAIL(af) ((af) & V_ADP_FONT) +#define ISMOUSEAVAIL(af) ((af) & V_ADP_FONT) +#define ISPALAVAIL(af) ((af) & V_ADP_PALETTE) + /* misc prototypes used by different syscons related LKM's */ -void set_border(u_char color); -void set_mode(scr_stat *scp); -void copy_font(int operation, int font_type, char* font_image); -void load_palette(char *palette); + +/* syscons.c */ +extern int (*sc_user_ioctl)(dev_t dev, 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); + +void copy_font(scr_stat *scp, int operation, int font_size, u_char *font_image); +void set_border(scr_stat *scp, int color); +#define save_palette(scp, pal) (*biosvidsw.save_palette)((scp)->adp, pal) +#define load_palette(scp, pal) (*biosvidsw.load_palette)((scp)->adp, pal) +#define get_adapter(scp) (*biosvidsw.adapter)((scp)->adp) + int add_scrn_saver(void (*this)(int)); int remove_scrn_saver(void (*this)(int)); +void sc_clear_screen(scr_stat *scp); +void sc_move_mouse(scr_stat *scp, int x, int y); +int sc_clean_up(scr_stat *scp); +void sc_alloc_scr_buffer(scr_stat *scp, int wait, int clear); +void sc_alloc_cut_buffer(scr_stat *scp, int wait); +void sc_alloc_history_buffer(scr_stat *scp, int lines, int extra, int wait); +struct tty *scdevtotty(dev_t dev); + +/* scvidctl.c */ +int sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, + int xsize, int ysize, int fontsize); +int sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode); +int sc_set_pixel_mode(scr_stat *scp, struct tty *tp, + int xsize, int ysize, int fontsize); +int sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, + struct proc *p); + #ifdef SC_SPLASH_SCREEN -void splash(int); -int splash_load(void); -int splash_unload(void); +/* splash.c */ +void scsplash(int); +int scsplash_load(scr_stat *scp); +int scsplash_unload(scr_stat *scp); #endif #ifdef PC98 unsigned int at2pc98(unsigned int attr); #endif -#endif /* !_I386_ISA_SYSCONS_H_ */ +#endif /* !_PC98_PC98_SYSCONS_H_ */ -- cgit v1.1