diff --git a/lkm/syscons/blank/blank_saver.c b/lkm/syscons/blank/blank_saver.c index 451dc9a4b241..d5f4cf0bf560 100644 --- a/lkm/syscons/blank/blank_saver.c +++ b/lkm/syscons/blank/blank_saver.c @@ -1,18 +1,18 @@ /*- - * Copyright (c) 1995 Søren Schmidt + * Copyright (c) 1995-1998 Søren Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. + * notice, this list of conditions and the following disclaimer, + * without modification, immediately at the beginning of the file. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products - * derived from this software 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,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: blank_saver.c,v 1.10 1997/07/15 14:49:09 yokota Exp $ + * $Id$ */ #include diff --git a/lkm/syscons/daemon/daemon_saver.c b/lkm/syscons/daemon/daemon_saver.c index f3cf3dce7736..688df41f274a 100644 --- a/lkm/syscons/daemon/daemon_saver.c +++ b/lkm/syscons/daemon/daemon_saver.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: daemon_saver.c,v 1.8 1998/01/16 17:58:43 bde Exp $ + * $Id: daemon_saver.c,v 1.9 1998/08/06 09:14:20 yokota Exp $ */ #include @@ -205,7 +205,7 @@ daemon_saver(int blank) /* clear the screen and set the border color */ fillw(((FG_LIGHTGREY|BG_BLACK) << 8) | scr_map[0x20], Crtat, scp->xsize * scp->ysize); - set_border(0); + set_border(scp, 0); xlen = ylen = tlen = 0; } if (scrn_blanked++ < 2) @@ -322,7 +322,7 @@ daemon_saver(int blank) draw_string(txpos, typos, toff, (char *)message, tlen); } else { if (scrn_blanked > 0) { - set_border(scp->border); + set_border(scp, scp->border); scrn_blanked = 0; } } diff --git a/lkm/syscons/fade/fade_saver.c b/lkm/syscons/fade/fade_saver.c index 341f7e8d240c..41176e76e092 100644 --- a/lkm/syscons/fade/fade_saver.c +++ b/lkm/syscons/fade/fade_saver.c @@ -1,18 +1,18 @@ /*- - * Copyright (c) 1995-1997 Søren Schmidt + * Copyright (c) 1995-1998 Søren Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. + * notice, this list of conditions and the following disclaimer, + * without modification, immediately at the beginning of the file. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products - * derived from this software 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,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: fade_saver.c,v 1.11 1997/07/15 14:49:25 yokota Exp $ + * $Id$ */ #include @@ -84,7 +84,7 @@ fade_saver(int blank) else { switch (crtc_type) { case KD_VGA: - load_palette(palette); + load_palette(cur_console, palette); count = 0; break; case KD_EGA: diff --git a/lkm/syscons/green/green_saver.c b/lkm/syscons/green/green_saver.c index b8c82958ac34..667866284681 100644 --- a/lkm/syscons/green/green_saver.c +++ b/lkm/syscons/green/green_saver.c @@ -1,18 +1,18 @@ /*- - * Copyright (c) 1995 Søren Schmidt + * Copyright (c) 1995-1998 Søren Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. + * notice, this list of conditions and the following disclaimer, + * without modification, immediately at the beginning of the file. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products - * derived from this software 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,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: green_saver.c,v 1.10 1997/07/15 14:49:29 yokota Exp $ + * $Id$ */ #include diff --git a/lkm/syscons/saver.h b/lkm/syscons/saver.h index 7118e4588e22..96cc010e9b81 100644 --- a/lkm/syscons/saver.h +++ b/lkm/syscons/saver.h @@ -1,18 +1,18 @@ /*- - * Copyright (c) 1995-1997 Søren Schmidt + * Copyright (c) 1995-1998 Søren Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. + * notice, this list of conditions and the following disclaimer, + * without modification, immediately at the beginning of the file. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products - * derived from this software 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,12 +25,12 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: saver.h,v 1.9 1997/07/15 14:48:11 yokota Exp $ + * $Id$ */ - #include #include +#include #include extern scr_stat *cur_console; diff --git a/lkm/syscons/snake/snake_saver.c b/lkm/syscons/snake/snake_saver.c index c3fa1fe7ce38..c5011d04bac2 100644 --- a/lkm/syscons/snake/snake_saver.c +++ b/lkm/syscons/snake/snake_saver.c @@ -1,18 +1,18 @@ /*- - * Copyright (c) 1995 Søren Schmidt + * Copyright (c) 1995-1998 Søren Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. + * notice, this list of conditions and the following disclaimer, + * without modification, immediately at the beginning of the file. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products - * derived from this software 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,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: snake_saver.c,v 1.16 1998/01/16 17:58:50 bde Exp $ + * $Id$ */ #include @@ -63,7 +63,7 @@ snake_saver(int blank) if (scrn_blanked <= 0) { fillw((FG_LIGHTGREY|BG_BLACK)<<8 | scr_map[0x20], Crtat, scp->xsize * scp->ysize); - set_border(0); + set_border(scp, 0); dirx = (scp->xpos ? 1 : -1); diry = (scp->ypos ? scp->xsize : -scp->xsize); @@ -99,7 +99,7 @@ snake_saver(int blank) } else { if (scrn_blanked > 0) { - set_border(scp->border); + set_border(scp, scp->border); scrn_blanked = 0; } } diff --git a/lkm/syscons/star/star_saver.c b/lkm/syscons/star/star_saver.c index 517a5579968f..8ac65bdba71c 100644 --- a/lkm/syscons/star/star_saver.c +++ b/lkm/syscons/star/star_saver.c @@ -1,18 +1,18 @@ /*- - * Copyright (c) 1995 Søren Schmidt + * Copyright (c) 1995-1998 Søren Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. + * notice, this list of conditions and the following disclaimer, + * without modification, immediately at the beginning of the file. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products - * derived from this software 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,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: star_saver.c,v 1.13 1998/01/16 17:58:55 bde Exp $ + * $Id$ */ #include @@ -62,7 +62,7 @@ star_saver(int blank) scrn_blanked = 1; fillw((FG_LIGHTGREY|BG_BLACK)<<8|scr_map[0x20], Crtat, scp->xsize * scp->ysize); - set_border(0); + set_border(scp, 0); for(i=0; ixsize*scp->ysize); @@ -80,7 +80,7 @@ star_saver(int blank) } else { if (scrn_blanked > 0) { - set_border(scp->border); + set_border(scp, scp->border); scrn_blanked = 0; } } diff --git a/sys/conf/NOTES b/sys/conf/NOTES index 2d8c4a883224..8b20f861bacc 100644 --- a/sys/conf/NOTES +++ b/sys/conf/NOTES @@ -2,7 +2,7 @@ # LINT -- config file for checking all the sources, tries to pull in # as much of the source tree as it can. # -# $Id: LINT,v 1.464 1998/09/15 10:01:13 gibbs Exp $ +# $Id: LINT,v 1.465 1998/09/15 11:44:43 phk Exp $ # # NB: You probably don't want to try running a kernel built from this # file. Instead, you should start from GENERIC, and add options from @@ -803,6 +803,9 @@ options SC_HISTORY_SIZE=200 # number of history buffer lines options SC_DISABLE_REBOOT # disable reboot key sequence # If the screen flickers badly when the mouse pointer is moved, try this. options SC_BAD_FLICKER +# To include support for VESA video modes +# Dont use together with SMP!! +options VESA # needs VM86 defined too!! # # `flags' for sc0: diff --git a/sys/conf/files.i386 b/sys/conf/files.i386 index 5302df40d509..6a0847003632 100644 --- a/sys/conf/files.i386 +++ b/sys/conf/files.i386 @@ -1,7 +1,7 @@ # This file tells config what files go into building a kernel, # files marked standard are always included. # -# $Id: files.i386,v 1.202 1998/09/08 20:57:46 sos Exp $ +# $Id: files.i386,v 1.203 1998/09/15 10:01:13 gibbs Exp $ # # The long compile-with and dependency lines are required because of # limitations in config: backslash-newline doesn't work in strings, and @@ -240,6 +240,10 @@ i386/isa/spigot.c optional spigot device-driver i386/isa/spkr.c optional speaker device-driver i386/isa/stallion.c optional stl device-driver i386/isa/syscons.c optional sc device-driver +i386/isa/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 i386/isa/tw.c optional tw device-driver #i386/isa/ultra14f.c optional uha device-driver i386/isa/wd.c optional wdc device-driver diff --git a/sys/conf/options.i386 b/sys/conf/options.i386 index c07d086cbdf4..21c45983b680 100644 --- a/sys/conf/options.i386 +++ b/sys/conf/options.i386 @@ -1,4 +1,4 @@ -# $Id: options.i386,v 1.85 1998/09/08 18:09:50 brian Exp $ +# $Id: options.i386,v 1.86 1998/09/15 10:01:14 gibbs Exp $ BOUNCEPAGES opt_bounce.h DISABLE_PSE @@ -77,6 +77,8 @@ SC_DISABLE_REBOOT opt_syscons.h SC_MOUSE_CHAR opt_syscons.h SC_BAD_FLICKER opt_syscons.h +VESA opt_vesa.h + PSM_HOOKAPM opt_psm.h PSM_RESETAFTERSUSPEND opt_psm.h PSM_DEBUG opt_psm.h diff --git a/sys/dev/kbd/kbdtables.h b/sys/dev/kbd/kbdtables.h index d36b39a33e7a..61376f48b919 100644 --- a/sys/dev/kbd/kbdtables.h +++ b/sys/dev/kbd/kbdtables.h @@ -1,18 +1,18 @@ /*- - * Copyright (c) 1992-1995 Søren Schmidt + * Copyright (c) 1992-1998 Søren Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. + * notice, this list of conditions and the following disclaimer, + * without modification, immediately at the beginning of the file. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products - * derived from this software withough specific prior written permission + * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES @@ -25,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: kbdtables.h,v 1.39 1998/01/28 08:45:18 yokota Exp $ + * $Id$ */ #define SET8 0x80 /* set eight bit on */ diff --git a/sys/dev/syscons/blank/blank_saver.c b/sys/dev/syscons/blank/blank_saver.c index 451dc9a4b241..d5f4cf0bf560 100644 --- a/sys/dev/syscons/blank/blank_saver.c +++ b/sys/dev/syscons/blank/blank_saver.c @@ -1,18 +1,18 @@ /*- - * Copyright (c) 1995 Søren Schmidt + * Copyright (c) 1995-1998 Søren Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. + * notice, this list of conditions and the following disclaimer, + * without modification, immediately at the beginning of the file. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products - * derived from this software 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,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: blank_saver.c,v 1.10 1997/07/15 14:49:09 yokota Exp $ + * $Id$ */ #include diff --git a/sys/dev/syscons/daemon/daemon_saver.c b/sys/dev/syscons/daemon/daemon_saver.c index f3cf3dce7736..688df41f274a 100644 --- a/sys/dev/syscons/daemon/daemon_saver.c +++ b/sys/dev/syscons/daemon/daemon_saver.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: daemon_saver.c,v 1.8 1998/01/16 17:58:43 bde Exp $ + * $Id: daemon_saver.c,v 1.9 1998/08/06 09:14:20 yokota Exp $ */ #include @@ -205,7 +205,7 @@ daemon_saver(int blank) /* clear the screen and set the border color */ fillw(((FG_LIGHTGREY|BG_BLACK) << 8) | scr_map[0x20], Crtat, scp->xsize * scp->ysize); - set_border(0); + set_border(scp, 0); xlen = ylen = tlen = 0; } if (scrn_blanked++ < 2) @@ -322,7 +322,7 @@ daemon_saver(int blank) draw_string(txpos, typos, toff, (char *)message, tlen); } else { if (scrn_blanked > 0) { - set_border(scp->border); + set_border(scp, scp->border); scrn_blanked = 0; } } diff --git a/sys/dev/syscons/fade/fade_saver.c b/sys/dev/syscons/fade/fade_saver.c index 341f7e8d240c..41176e76e092 100644 --- a/sys/dev/syscons/fade/fade_saver.c +++ b/sys/dev/syscons/fade/fade_saver.c @@ -1,18 +1,18 @@ /*- - * Copyright (c) 1995-1997 Søren Schmidt + * Copyright (c) 1995-1998 Søren Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. + * notice, this list of conditions and the following disclaimer, + * without modification, immediately at the beginning of the file. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products - * derived from this software 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,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: fade_saver.c,v 1.11 1997/07/15 14:49:25 yokota Exp $ + * $Id$ */ #include @@ -84,7 +84,7 @@ fade_saver(int blank) else { switch (crtc_type) { case KD_VGA: - load_palette(palette); + load_palette(cur_console, palette); count = 0; break; case KD_EGA: diff --git a/sys/dev/syscons/green/green_saver.c b/sys/dev/syscons/green/green_saver.c index b8c82958ac34..667866284681 100644 --- a/sys/dev/syscons/green/green_saver.c +++ b/sys/dev/syscons/green/green_saver.c @@ -1,18 +1,18 @@ /*- - * Copyright (c) 1995 Søren Schmidt + * Copyright (c) 1995-1998 Søren Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. + * notice, this list of conditions and the following disclaimer, + * without modification, immediately at the beginning of the file. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products - * derived from this software 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,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: green_saver.c,v 1.10 1997/07/15 14:49:29 yokota Exp $ + * $Id$ */ #include diff --git a/sys/dev/syscons/scvesactl.c b/sys/dev/syscons/scvesactl.c new file mode 100644 index 000000000000..9678177d4011 --- /dev/null +++ b/sys/dev/syscons/scvesactl.c @@ -0,0 +1,150 @@ +/*- + * Copyright (c) 1998 Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#include "sc.h" +#include "opt_vesa.h" +#include "opt_vm86.h" + +#if (NSC > 0 && defined(VESA) && defined(VM86)) || defined(VESA_MODULE) + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +static int (*prev_user_ioctl)(dev_t dev, int cmd, caddr_t data, int flag, + struct proc *p); + +extern struct tty *scdevtotty(dev_t dev); + +int +vesa_ioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) +{ + scr_stat *scp; + struct tty *tp; + video_info_t info; + video_adapter_t *adp; + int mode; + int error; + int s; + + tp = scdevtotty(dev); + if (!tp) + return ENXIO; + scp = sc_get_scr_stat(tp->t_dev); + + switch (cmd) { + case SW_VESA_USER: + + mode = (int)data; + if ((*biosvidsw.get_info)(scp->adp, mode, &info)) + return ENODEV; + if (info.vi_flags & V_INFO_GRAPHICS) + goto vesa_graphics; + else + goto vesa_text; + + /* text modes */ + case SW_VESA_C80x60: + case SW_VESA_C132x25: + case SW_VESA_C132x43: + case SW_VESA_C132x50: + case SW_VESA_C132x60: + adp = get_adapter(scp); + if (!(adp->va_flags & V_ADP_MODECHANGE)) + return ENODEV; + mode = (cmd & 0xff) + M_VESA_BASE; +vesa_text: + return sc_set_text_mode(scp, tp, mode, 0, 0, 0); + + /* graphics modes */ + case SW_VESA_32K_320: case SW_VESA_64K_320: + case SW_VESA_FULL_320: + + case SW_VESA_CG640x400: + + case SW_VESA_CG640x480: + case SW_VESA_32K_640: case SW_VESA_64K_640: + case SW_VESA_FULL_640: + + case SW_VESA_800x600: case SW_VESA_CG800x600: + case SW_VESA_32K_800: case SW_VESA_64K_800: + case SW_VESA_FULL_800: + + case SW_VESA_1024x768: case SW_VESA_CG1024x768: + case SW_VESA_32K_1024: case SW_VESA_64K_1024: + case SW_VESA_FULL_1024: + + case SW_VESA_1280x1024: case SW_VESA_CG1280x1024: + case SW_VESA_32K_1280: case SW_VESA_64K_1280: + case SW_VESA_FULL_1280: + adp = get_adapter(scp); + if (!(adp->va_flags & V_ADP_MODECHANGE)) + return ENODEV; + mode = (cmd & 0xff) + M_VESA_BASE; +vesa_graphics: + return sc_set_graphics_mode(scp, tp, mode); + } + + if (prev_user_ioctl) + return (*prev_user_ioctl)(dev, cmd, data, flag, p); + else + return ENOIOCTL; +} + +int +vesa_load_ioctl(void) +{ + if (prev_user_ioctl) + return EBUSY; + prev_user_ioctl = sc_user_ioctl; + sc_user_ioctl = vesa_ioctl; + return 0; +} + +int +vesa_unload_ioctl(void) +{ + if (sc_user_ioctl != vesa_ioctl) + return EBUSY; + sc_user_ioctl = prev_user_ioctl; + prev_user_ioctl = NULL; + return 0; +} + +#endif /* (NSC > 0 && VESA && VM86) || VESA_MODULE */ diff --git a/sys/dev/syscons/scvidctl.c b/sys/dev/syscons/scvidctl.c new file mode 100644 index 000000000000..464933edb112 --- /dev/null +++ b/sys/dev/syscons/scvidctl.c @@ -0,0 +1,486 @@ +/*- + * Copyright (c) 1998 Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#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 u_short *Crtat; +extern int fonts_loaded; +extern int sc_history_size; +extern u_char palette[]; + +int +sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, int xsize, int ysize, + int fontsize) +{ + video_adapter_t *adp; + video_info_t info; + int error; + int s; + int i; + + if ((*biosvidsw.get_info)(scp->adp, mode, &info)) + return ENODEV; + adp = get_adapter(scp); + + /* adjust argument values */ + if (fontsize <= 0) + fontsize = info.vi_cheight; + if (fontsize < 14) { + fontsize = 8; + if (!(fonts_loaded & FONT_8)) + return EINVAL; + } else if (fontsize >= 16) { + fontsize = 16; + if (!(fonts_loaded & FONT_16)) + return EINVAL; + } else { + fontsize = 14; + if (!(fonts_loaded & FONT_14)) + return EINVAL; + } + if ((xsize <= 0) || (xsize > info.vi_width)) + xsize = info.vi_width; + if ((ysize <= 0) || (ysize > info.vi_height)) + ysize = info.vi_height; + + /* stop screen saver, etc */ + s = spltty(); + if ((error = sc_clean_up(scp))) { + splx(s); + return error; + } + + /* set up scp */ + if (scp->history != NULL) + i = imax(scp->history_size / scp->xsize + - imax(sc_history_size, scp->ysize), 0); + else + i = 0; + /* + * This is a kludge to fend off scrn_update() while we + * muck around with scp. XXX + */ + scp->status |= UNKNOWN_MODE; + scp->status &= ~(GRAPHICS_MODE | PIXEL_MODE); + scp->mode = mode; + scp->font_size = fontsize; + scp->xsize = xsize; + scp->ysize = ysize; + scp->xpixel = scp->xsize*8; + scp->ypixel = scp->ysize*fontsize; + + /* allocate buffers */ + sc_alloc_scr_buffer(scp, TRUE, TRUE); + if (ISMOUSEAVAIL(adp->va_flags)) + sc_alloc_cut_buffer(scp, FALSE); + sc_alloc_history_buffer(scp, sc_history_size, i, FALSE); + splx(s); + + if (scp == cur_console) + set_mode(scp); + scp->status &= ~UNKNOWN_MODE; + + if (tp == NULL) + return 0; + if (tp->t_winsize.ws_col != scp->xsize + || tp->t_winsize.ws_row != scp->ysize) { + tp->t_winsize.ws_col = scp->xsize; + tp->t_winsize.ws_row = scp->ysize; + pgsignal(tp->t_pgrp, SIGWINCH, 1); + } + + return 0; +} + +int +sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode) +{ + video_adapter_t *adp; + video_info_t info; + int error; + int s; + + if ((*biosvidsw.get_info)(scp->adp, mode, &info)) + return ENODEV; + adp = get_adapter(scp); + + /* stop screen saver, etc */ + s = spltty(); + if ((error = sc_clean_up(scp))) { + splx(s); + return error; + } + + /* set up scp */ + scp->status |= (UNKNOWN_MODE | GRAPHICS_MODE); + scp->status &= ~PIXEL_MODE; + scp->mode = mode; + scp->xpixel = info.vi_width; + scp->ypixel = info.vi_height; + scp->xsize = info.vi_width/8; + scp->ysize = info.vi_height/info.vi_cheight; + scp->font_size = FONT_NONE; + /* move the mouse cursor at the center of the screen */ + sc_move_mouse(scp, scp->xpixel / 2, scp->ypixel / 2); + splx(s); + + if (scp == cur_console) + set_mode(scp); + /* clear_graphics();*/ + scp->status &= ~UNKNOWN_MODE; + + if (tp == NULL) + return 0; + if (tp->t_winsize.ws_xpixel != scp->xpixel + || tp->t_winsize.ws_ypixel != scp->ypixel) { + tp->t_winsize.ws_xpixel = scp->xpixel; + tp->t_winsize.ws_ypixel = scp->ypixel; + pgsignal(tp->t_pgrp, SIGWINCH, 1); + } + + return 0; +} + +int +sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize, + int fontsize) +{ + video_adapter_t *adp; + video_info_t info; + int error; + int s; + int i; + + if ((*biosvidsw.get_info)(scp->adp, scp->mode, &info)) + return ENODEV; /* this shouldn't happen */ + adp = get_adapter(scp); + +#ifdef SC_VIDEO_DEBUG + if (scp->scr_buf != NULL) { + printf("set_pixel_mode(): mode:%x, col:%d, row:%d, font:%d\n", + scp->mode, xsize, ysize, fontsize); + } +#endif + + /* adjust argument values */ + if ((fontsize <= 0) || (fontsize == FONT_NONE)) + fontsize = info.vi_cheight; + if (fontsize < 14) { + fontsize = 8; + if (!(fonts_loaded & FONT_8)) + return EINVAL; + } else if (fontsize >= 16) { + fontsize = 16; + if (!(fonts_loaded & FONT_16)) + return EINVAL; + } else { + fontsize = 14; + if (!(fonts_loaded & FONT_14)) + return EINVAL; + } + if (xsize <= 0) + xsize = info.vi_width/8; + if (ysize <= 0) + ysize = info.vi_height/fontsize; + +#ifdef SC_VIDEO_DEBUG + if (scp->scr_buf != NULL) { + printf("set_pixel_mode(): mode:%x, col:%d, row:%d, font:%d\n", + scp->mode, xsize, ysize, fontsize); + printf("set_pixel_mode(): Crtat:%x, %dx%d, xoff:%d, yoff:%d\n", + Crtat, info.vi_width, info.vi_height, + (info.vi_width/8 - xsize)/2, + (info.vi_height/fontsize - ysize)/2); + } +#endif + + /* stop screen saver, etc */ + s = spltty(); + if ((error = sc_clean_up(scp))) { + splx(s); + return error; + } + + /* set up scp */ + if (scp->history != NULL) + i = imax(scp->history_size / scp->xsize + - imax(sc_history_size, scp->ysize), 0); + else + i = 0; + scp->status |= (UNKNOWN_MODE | PIXEL_MODE); + scp->status &= ~(GRAPHICS_MODE | MOUSE_ENABLED); + scp->xsize = xsize; + scp->ysize = ysize; + scp->font_size = fontsize; + scp->xoff = (scp->xpixel/8 - xsize)/2; + scp->yoff = (scp->ypixel/fontsize - ysize)/2; + + /* allocate buffers */ + sc_alloc_scr_buffer(scp, TRUE, TRUE); + if (ISMOUSEAVAIL(adp->va_flags)) + sc_alloc_cut_buffer(scp, FALSE); + sc_alloc_history_buffer(scp, sc_history_size, i, FALSE); + splx(s); + + /* FIXME */ + if (scp == cur_console) + bzero(Crtat, scp->xpixel*scp->ypixel/8); + + scp->status &= ~UNKNOWN_MODE; + +#ifdef SC_VIDEO_DEBUG + printf("set_pixel_mode(): status:%x\n", scp->status); +#endif + + if (tp == NULL) + return 0; + if (tp->t_winsize.ws_col != scp->xsize + || tp->t_winsize.ws_row != scp->ysize) { + tp->t_winsize.ws_col = scp->xsize; + tp->t_winsize.ws_row = scp->ysize; + pgsignal(tp->t_pgrp, SIGWINCH, 1); + } + + return 0; +} + +int +sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p) +{ + scr_stat *scp; + video_adapter_t *adp; + int error; + int s; + + scp = sc_get_scr_stat(tp->t_dev); + + switch (cmd) { + + case CONS_CURRENT: /* get current adapter type */ + adp = get_adapter(scp); + *(int *)data = adp->va_type; + return 0; + + case CONS_CURRENTADP: /* get current adapter index */ + *(int *)data = scp->adp; + return 0; + + case CONS_ADPINFO: /* adapter information */ + adp = (*biosvidsw.adapter)(((video_adapter_t *)data)->va_index); + if (adp == NULL) + return ENODEV; + bcopy(adp, data, sizeof(*adp)); + return 0; + + case CONS_GET: /* get current video mode */ + *(int *)data = scp->mode; + return 0; + + case CONS_MODEINFO: /* get mode information */ + return ((*biosvidsw.get_info)(scp->adp, + ((video_info_t *)data)->vi_mode, (video_info_t *)data) + ? ENODEV : 0); + + case CONS_FINDMODE: /* find a matching video mode */ + return ((*biosvidsw.query_mode)(scp->adp, (video_info_t *)data) + ? ENODEV : 0); + + case CONS_SETWINORG: + return ((*biosvidsw.set_win_org)(scp->adp, *(u_int *)data) + ? ENODEV : 0); + + /* VGA TEXT MODES */ + case SW_VGA_C40x25: + case SW_VGA_C80x25: case SW_VGA_M80x25: + case SW_VGA_C80x30: case SW_VGA_M80x30: + case SW_VGA_C80x50: case SW_VGA_M80x50: + case SW_VGA_C80x60: case SW_VGA_M80x60: + case SW_B40x25: case SW_C40x25: + case SW_B80x25: case SW_C80x25: + case SW_ENH_B40x25: case SW_ENH_C40x25: + case SW_ENH_B80x25: case SW_ENH_C80x25: + case SW_ENH_B80x43: case SW_ENH_C80x43: + case SW_EGAMONO80x25: + adp = get_adapter(scp); + if (!(adp->va_flags & V_ADP_MODECHANGE)) + return ENODEV; + return sc_set_text_mode(scp, tp, cmd & 0xff, 0, 0, 0); + + /* GRAPHICS MODES */ + case SW_BG320: case SW_BG640: + case SW_CG320: case SW_CG320_D: case SW_CG640_E: + case SW_CG640x350: case SW_ENH_CG640: + case SW_BG640x480: case SW_CG640x480: case SW_VGA_CG320: + case SW_VGA_MODEX: + adp = get_adapter(scp); + if (!(adp->va_flags & V_ADP_MODECHANGE)) + return ENODEV; + return sc_set_graphics_mode(scp, tp, cmd & 0xff); + + case KDSETMODE: /* set current mode of this (virtual) console */ + switch (*data) { + case KD_TEXT: /* switch to TEXT (known) mode */ + /* + * If scp->mode is of graphics modes, we don't know which + * text mode to switch back to... + */ + if (scp->status & GRAPHICS_MODE) + return EINVAL; + /* restore fonts & palette ! */ +#if 0 + adp = get_adapter(scp); + if (ISFONTAVAIL(adp->va_flags) + && !(scp->status & (GRAPHICS_MODE | PIXEL_MODE))) + /* + * FONT KLUDGE + * Don't load fonts for now... XXX + */ + if (fonts_loaded & FONT_8) + copy_font(scp, LOAD, 8, font_8); + if (fonts_loaded & FONT_14) + copy_font(scp, LOAD, 14, font_14); + if (fonts_loaded & FONT_16) + copy_font(scp, LOAD, 16, font_16); + } +#endif + load_palette(scp, palette); + + /* move hardware cursor out of the way */ + (*biosvidsw.set_hw_cursor)(scp->adp, -1, -1); + + /* FALL THROUGH */ + + case KD_TEXT1: /* switch to TEXT (known) mode */ + /* + * If scp->mode is of graphics modes, we don't know which + * text/pixel mode to switch back to... + */ + if (scp->status & GRAPHICS_MODE) + return EINVAL; + s = spltty(); + if ((error = sc_clean_up(scp))) { + splx(s); + return error; + } + scp->status |= UNKNOWN_MODE; + splx(s); + /* no restore fonts & palette */ + if (scp == cur_console) { + set_mode(scp); + /* FIXME */ + if (scp->status & PIXEL_MODE) + bzero(Crtat, scp->xpixel*scp->ypixel/8); + } + sc_clear_screen(scp); + scp->status &= ~UNKNOWN_MODE; + return 0; + + case KD_PIXEL: /* pixel (raster) display */ + if (!(scp->status & (GRAPHICS_MODE | PIXEL_MODE))) + return EINVAL; + if (!(scp->status & PIXEL_MODE)) + return sc_set_pixel_mode(scp, tp, scp->xsize, scp->ysize, + scp->font_size); + s = spltty(); + if ((error = sc_clean_up(scp))) { + splx(s); + return error; + } + scp->status |= (UNKNOWN_MODE | PIXEL_MODE); + splx(s); + if (scp == cur_console) { + set_mode(scp); + load_palette(scp, palette); + /* FIXME */ + bzero(Crtat, scp->xpixel*scp->ypixel/8); + } + sc_clear_screen(scp); + scp->status &= ~UNKNOWN_MODE; + return 0; + + case KD_GRAPHICS: /* switch to GRAPHICS (unknown) mode */ + s = spltty(); + if ((error = sc_clean_up(scp))) { + splx(s); + return error; + } + scp->status |= UNKNOWN_MODE; + splx(s); + return 0; + + default: + return EINVAL; + } + /* NOT REACHED */ + + case KDRASTER: /* set pixel (raster) display mode */ + if (ISUNKNOWNSC(scp) || ISTEXTSC(scp)) + return ENODEV; + return sc_set_pixel_mode(scp, tp, ((int *)data)[0], ((int *)data)[1], + ((int *)data)[2]); + + case KDGETMODE: /* get current mode of this (virtual) console */ + /* + * From the user program's point of view, KD_PIXEL is the same + * as KD_TEXT... + */ + *data = ISGRAPHSC(scp) ? KD_GRAPHICS : KD_TEXT; + return 0; + + case KDSBORDER: /* set border color of this (virtual) console */ + scp->border = *data; + if (scp == cur_console) + set_border(cur_console, scp->border); + return 0; + } + + return ENOIOCTL; +} + +#endif /* NSC > 0 */ diff --git a/sys/dev/syscons/snake/snake_saver.c b/sys/dev/syscons/snake/snake_saver.c index c3fa1fe7ce38..c5011d04bac2 100644 --- a/sys/dev/syscons/snake/snake_saver.c +++ b/sys/dev/syscons/snake/snake_saver.c @@ -1,18 +1,18 @@ /*- - * Copyright (c) 1995 Søren Schmidt + * Copyright (c) 1995-1998 Søren Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. + * notice, this list of conditions and the following disclaimer, + * without modification, immediately at the beginning of the file. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products - * derived from this software 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,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: snake_saver.c,v 1.16 1998/01/16 17:58:50 bde Exp $ + * $Id$ */ #include @@ -63,7 +63,7 @@ snake_saver(int blank) if (scrn_blanked <= 0) { fillw((FG_LIGHTGREY|BG_BLACK)<<8 | scr_map[0x20], Crtat, scp->xsize * scp->ysize); - set_border(0); + set_border(scp, 0); dirx = (scp->xpos ? 1 : -1); diry = (scp->ypos ? scp->xsize : -scp->xsize); @@ -99,7 +99,7 @@ snake_saver(int blank) } else { if (scrn_blanked > 0) { - set_border(scp->border); + set_border(scp, scp->border); scrn_blanked = 0; } } diff --git a/sys/dev/syscons/star/star_saver.c b/sys/dev/syscons/star/star_saver.c index 517a5579968f..8ac65bdba71c 100644 --- a/sys/dev/syscons/star/star_saver.c +++ b/sys/dev/syscons/star/star_saver.c @@ -1,18 +1,18 @@ /*- - * Copyright (c) 1995 Søren Schmidt + * Copyright (c) 1995-1998 Søren Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. + * notice, this list of conditions and the following disclaimer, + * without modification, immediately at the beginning of the file. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products - * derived from this software 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,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: star_saver.c,v 1.13 1998/01/16 17:58:55 bde Exp $ + * $Id$ */ #include @@ -62,7 +62,7 @@ star_saver(int blank) scrn_blanked = 1; fillw((FG_LIGHTGREY|BG_BLACK)<<8|scr_map[0x20], Crtat, scp->xsize * scp->ysize); - set_border(0); + set_border(scp, 0); for(i=0; ixsize*scp->ysize); @@ -80,7 +80,7 @@ star_saver(int blank) } else { if (scrn_blanked > 0) { - set_border(scp->border); + set_border(scp, scp->border); scrn_blanked = 0; } } diff --git a/sys/dev/syscons/syscons.c b/sys/dev/syscons/syscons.c index ebc243f52ba7..50e0f199c0fb 100644 --- a/sys/dev/syscons/syscons.c +++ b/sys/dev/syscons/syscons.c @@ -1,18 +1,18 @@ /*- - * Copyright (c) 1992-1997 Søren Schmidt + * Copyright (c) 1992-1998 Søren Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. + * notice, this list of conditions and the following disclaimer, + * without modification, immediately at the beginning of the file. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products - * derived from this software withough specific prior written permission + * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES @@ -25,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.276 1998/08/23 08:26:41 bde Exp $ + * $Id$ */ #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 @@ -70,6 +72,7 @@ #include #include #include +#include #include #if !defined(MAXCONS) @@ -96,11 +99,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!? */ @@ -159,6 +157,7 @@ static int blinkrate = 0; u_int crtc_addr = MONO_BASE; char crtc_type = KD_MONO; char crtc_vga = FALSE; +static int adp_flags = 0; static u_char shfts = 0, ctls = 0, alts = 0, agrs = 0, metas = 0; static u_char accents = 0; static u_char nlkcnt = 0, clkcnt = 0, slkcnt = 0, alkcnt = 0; @@ -172,7 +171,7 @@ static int run_scrn_saver = FALSE; /* should run the saver? */ static int scrn_idle = FALSE; /* about to run the saver */ u_char scr_map[256]; u_char scr_rmap[256]; - char *video_mode_ptr = NULL; +static int initial_video_mode; /* initial video mode # */ static int bios_video_mode; /* video mode # set by BIOS */ int fonts_loaded = 0 #ifdef STD8X16FONT @@ -180,19 +179,15 @@ static int bios_video_mode; /* video mode # set by BIOS */ #endif ; - char font_8[256*8]; - char font_14[256*14]; + u_char font_8[256*8]; + u_char font_14[256*14]; #ifdef STD8X16FONT extern #endif - unsigned char font_16[256*16]; - char palette[256*3]; -static char *mode_map[MODE_MAP_SIZE]; -static char vgaregs[MODE_PARAM_SIZE]; -static char vgaregs2[MODE_PARAM_SIZE]; -static int rows_offset = 1; -static char *cut_buffer; -static int cut_buffer_size; + u_char font_16[256*16]; + u_char palette[256*3]; +static u_char *cut_buffer = NULL; +static int cut_buffer_size = 0; static int mouse_level = 0; /* sysmouse protocol level */ static mousestatus_t mouse_status = { 0, 0, 0, 0, 0, 0 }; static u_short mouse_and_mask[16] = { @@ -208,13 +203,14 @@ static u_short mouse_or_mask[16] = { 0x0000, 0x0000, 0x0000, 0x0000 }; -static int extra_history_size = + int sc_history_size = SC_HISTORY_SIZE; +static int extra_history_size = SC_MAX_HISTORY_SIZE - SC_HISTORY_SIZE * MAXCONS; static void none_saver(int blank) { } static void (*current_saver)(int blank) = none_saver; static void (*default_saver)(int blank) = none_saver; -int (*sc_user_ioctl)(dev_t dev, int cmd, caddr_t data, + int (*sc_user_ioctl)(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) = NULL; static int sticky_splash = FALSE; @@ -233,8 +229,6 @@ static struct tty sccons[MAXCONS+2]; #endif #define SC_MOUSE 128 #define SC_CONSOLE 255 -#define MONO_BUF pa_to_va(0xB0000) -#define CGA_BUF pa_to_va(0xB8000) u_short *Crtat; static const int nsccons = MAXCONS+2; @@ -243,9 +237,6 @@ static const int nsccons = MAXCONS+2; + (offset)) % (scp->history_size))) #define ISSIGVALID(sig) ((sig) > 0 && (sig) < NSIG) -/* this should really be in `rtc.h' */ -#define RTC_EQUIPMENT 0x14 - /* prototypes */ static int scattach(struct isa_device *dev); static int scparam(struct tty *tp, struct termios *t); @@ -256,30 +247,26 @@ static void scstart(struct tty *tp); static void scmousestart(struct tty *tp); static void scinit(void); static void scshutdown(int howto, void *arg); -static void map_mode_table(char *map[], char *table, int max); -static int map_mode_num(int mode); -static char *get_mode_param(scr_stat *scp, int mode); static u_int scgetc(u_int flags); #define SCGETC_CN 1 #define SCGETC_NONBLOCK 2 static void sccnupdate(scr_stat *scp); -static scr_stat *get_scr_stat(dev_t dev); static scr_stat *alloc_scp(void); static void init_scp(scr_stat *scp); static void sc_bcopy(scr_stat *scp, u_short *p, int from, int to, int mark); static int get_scr_num(void); static timeout_t scrn_timer; static void scrn_update(scr_stat *scp, int show_cursor); +static void scrn_saver(void (*saver)(int), int blank); static void stop_scrn_saver(void (*saver)(int)); static int wait_scrn_saver_stop(void); -static void clear_screen(scr_stat *scp); static int switch_scr(scr_stat *scp, u_int next_scr); static void exchange_scr(void); -static void move_crsr(scr_stat *scp, int x, int y); static void scan_esc(scr_stat *scp, u_char c); +static void ansi_put(scr_stat *scp, u_char *buf, int len); static void draw_cursor_image(scr_stat *scp); static void remove_cursor_image(scr_stat *scp); -static void ansi_put(scr_stat *scp, u_char *buf, int len); +static void move_crsr(scr_stat *scp, int x, int y); static u_char *get_fstr(u_int c, u_int *len); static void history_to_screen(scr_stat *scp); static int history_up_line(scr_stat *scp); @@ -287,16 +274,6 @@ static int history_down_line(scr_stat *scp); static int mask2attr(struct term_stat *term); static void set_keyboard(int command, int data); static void update_leds(int which); -static void set_vgaregs(char *modetable); -static void read_vgaregs(char *buf); -#define COMP_IDENTICAL 0 -#define COMP_SIMILAR 1 -#define COMP_DIFFERENT 2 -static int comp_vgaregs(u_char *buf1, u_char *buf2); -static void dump_vgaregs(u_char *buf); -#define PARAM_BUFSIZE 6 -static void set_font_mode(u_char *buf); -static void set_normal_mode(u_char *buf); static void set_destructive_cursor(scr_stat *scp); static void set_mouse_pos(scr_stat *scp); static int skip_spc_right(scr_stat *scp, u_short *p); @@ -312,12 +289,11 @@ static void draw_mouse_image(scr_stat *scp); static void remove_mouse_image(scr_stat *scp); static void draw_cutmarking(scr_stat *scp); static void remove_cutmarking(scr_stat *scp); -static void save_palette(void); static void do_bell(scr_stat *scp, int pitch, int duration); static timeout_t blink_screen; #ifdef SC_SPLASH_SCREEN -static void scsplash_init(void); -static void scsplash(int show); +static void scsplash_init(scr_stat *scp); +static void scsplash_saver(int show); #define scsplash_stick(stick) (sticky_splash = (stick)) #else #define scsplash_stick(stick) @@ -332,7 +308,7 @@ static d_close_t scclose; static d_read_t scread; static d_write_t scwrite; static d_ioctl_t scioctl; -static d_devtotty_t scdevtotty; + d_devtotty_t scdevtotty; static d_mmap_t scmmap; #define CDEV_MAJOR 12 @@ -353,7 +329,7 @@ draw_cursor_image(scr_stat *scp) u_short cursor_image, *ptr = Crtat + (scp->cursor_pos - scp->scr_buf); u_short prev_image; - if (VESA_MODE(scp->mode)) { + if (ISPIXELSC(scp)) { sc_bcopy(scp, scp->scr_buf, scp->cursor_pos - scp->scr_buf, scp->cursor_pos - scp->scr_buf, 1); return; @@ -405,7 +381,7 @@ draw_cursor_image(scr_stat *scp) static void remove_cursor_image(scr_stat *scp) { - if (VESA_MODE(scp->mode)) + if (ISPIXELSC(scp)) sc_bcopy(scp, scp->scr_buf, scp->cursor_oldpos - scp->scr_buf, scp->cursor_oldpos - scp->scr_buf, 0); else @@ -436,6 +412,12 @@ scprobe(struct isa_device *dev) printf("sc%d: no video adapter is found.\n", dev->id_unit); return (0); } + (*biosvidsw.diag)(bootverbose); +#if defined(VESA) && defined(VM86) + if (vesa_load()) + return FALSE; + (*biosvidsw.diag)(bootverbose); +#endif sc_port = dev->id_iobase; if (sckbdprobe(dev->id_unit, dev->id_flags)) @@ -448,99 +430,24 @@ 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; + video_adapter_t *adp; /* 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. - */ - 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 ((*biosvidsw.init)() <= 0) + return FALSE; + if ((adp = (*biosvidsw.adapter)(V_ADP_PRIMARY)) == NULL) + return FALSE; - 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; - } - - /* 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); - } - } - } + 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; return TRUE; } @@ -728,48 +635,42 @@ static int scattach(struct isa_device *dev) { scr_stat *scp; + video_info_t info; dev_t cdev = makedev(CDEV_MAJOR, 0); - char *p; #ifdef DEVFS int vc; #endif scinit(); flags = dev->id_flags; - if (crtc_type != KD_VGA || VESA_MODE(bios_video_mode)) + if (!ISFONTAVAIL(adp_flags)) flags &= ~CHAR_CURSOR; scp = console[0]; - if (crtc_type == KD_VGA) { - cut_buffer_size = scp->xsize * scp->ysize + 1; - cut_buffer = (char *)malloc(cut_buffer_size, M_DEVBUF, M_NOWAIT); - if (cut_buffer != NULL) - cut_buffer[0] = '\0'; - } - - scp->scr_buf = (u_short *)malloc(scp->xsize*scp->ysize*sizeof(u_short), - M_DEVBUF, M_NOWAIT); - /* copy temporary buffer to final buffer */ - bcopy(sc_buffer, scp->scr_buf, scp->xsize * scp->ysize * sizeof(u_short)); + scp->scr_buf = NULL; + sc_alloc_scr_buffer(scp, FALSE, FALSE); + bcopy(sc_buffer, scp->scr_buf, scp->xsize*scp->ysize*sizeof(u_short)); - scp->cursor_pos = scp->cursor_oldpos = - scp->scr_buf + scp->xpos + scp->ypos * scp->xsize; - scp->mouse_pos = scp->mouse_oldpos = - scp->scr_buf + ((scp->mouse_ypos/scp->font_size)*scp->xsize + - scp->mouse_xpos/8); + /* cut buffer is available only when the mouse pointer is used */ + if (ISMOUSEAVAIL(adp_flags)) + sc_alloc_cut_buffer(scp, FALSE); /* initialize history buffer & pointers */ - scp->history_head = scp->history_pos = - (u_short *)malloc(scp->history_size*sizeof(u_short), - M_DEVBUF, M_NOWAIT); - if (scp->history_head != NULL) - bzero(scp->history_head, scp->history_size*sizeof(u_short)); - scp->history = scp->history_head; + sc_alloc_history_buffer(scp, sc_history_size, 0, FALSE); + +#if defined(VESA) && defined(VM86) + if ((flags & VESA800X600) + && ((*biosvidsw.get_info)(scp->adp, M_VESA_800x600, &info) == 0)) { + sc_set_graphics_mode(scp, NULL, M_VESA_800x600); + sc_set_pixel_mode(scp, NULL, COL, ROW, 16); + initial_video_mode = M_VESA_800x600; + } +#endif /* VESA && VM86 */ /* initialize cursor stuff */ - if (!(scp->status & UNKNOWN_MODE)) + if (!ISGRAPHSC(scp)) draw_cursor_image(scp); /* get screen update going */ @@ -777,42 +678,13 @@ scattach(struct isa_device *dev) update_leds(scp->status); - 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); - printf("sc%d: ", dev->id_unit); switch(crtc_type) { case KD_VGA: - if (VESA_MODE(bios_video_mode)) - printf("Graphics display (VESA mode = 0x%x)", bios_video_mode); - else if (crtc_addr == MONO_BASE) - printf("VGA mono"); - else - printf("VGA color"); + printf("VGA %s", (adp_flags & V_ADP_COLOR) ? "color" : "mono"); break; case KD_EGA: - if (crtc_addr == MONO_BASE) - printf("EGA mono"); - else - printf("EGA color"); + printf("EGA %s", (adp_flags & V_ADP_COLOR) ? "color" : "mono"); break; case KD_CGA: printf("CGA"); @@ -820,7 +692,7 @@ scattach(struct isa_device *dev) case KD_MONO: case KD_HERCULES: default: - printf("MDA/hercules"); + printf("MDA/Hercules"); break; } printf(" <%d virtual consoles, flags=0x%x>\n", MAXCONS, flags); @@ -896,6 +768,8 @@ scopen(dev_t dev, int flag, int mode, struct proc *p) return(EBUSY); if (minor(dev) < MAXCONS && !console[minor(dev)]) { console[minor(dev)] = alloc_scp(); + if (ISGRAPHSC(console[minor(dev)])) + sc_set_pixel_mode(console[minor(dev)], NULL, COL, ROW, 16); } if (minor(dev)t_winsize.ws_col && !tp->t_winsize.ws_row) { tp->t_winsize.ws_col = console[minor(dev)]->xsize; @@ -913,7 +787,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 @@ -927,9 +801,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; @@ -1008,10 +882,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 @@ -1030,21 +911,25 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) u_int i; struct tty *tp; scr_stat *scp; - u_short *usp; - char *mp; + video_adapter_t *adp; int s; tp = scdevtotty(dev); if (!tp) return ENXIO; - scp = get_scr_stat(tp->t_dev); + scp = sc_get_scr_stat(tp->t_dev); /* If there is a user_ioctl function call that first */ if (sc_user_ioctl) { - if (error = (*sc_user_ioctl)(dev, cmd, data, flag, p)) + error = (*sc_user_ioctl)(dev, cmd, data, flag, p); + if (error != ENOIOCTL) return error; } + error = sc_vid_ioctl(tp, cmd, data, flag, p); + if (error != ENOIOCTL) + return error; + switch (cmd) { /* process console hardware related ioctl's */ case GIO_ATTR: /* get current attributes */ @@ -1052,18 +937,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) return 0; case GIO_COLOR: /* is this a color console ? */ - if (crtc_addr == COLOR_BASE) - *(int*)data = 1; - else - *(int*)data = 0; - return 0; - - case CONS_CURRENT: /* get current adapter type */ - *(int *)data = crtc_type; - return 0; - - case CONS_GET: /* get current video mode */ - *(int*)data = scp->mode; + *(int *)data = (adp_flags & V_ADP_COLOR) ? 1 : 0; return 0; case CONS_BLANKTIME: /* set screen saver timeout (0 = no saver) */ @@ -1081,7 +955,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) else flags &= ~BLINK_CURSOR; if ((*(int*)data) & 0x02) { - if (crtc_type != KD_VGA || VESA_MODE(bios_video_mode)) + if (!ISFONTAVAIL(get_adapter(scp)->va_flags)) return ENXIO; flags |= CHAR_CURSOR; } else @@ -1090,7 +964,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) * The cursor shape is global property; all virtual consoles * are affected. Update the cursor in the current console... */ - if (!(cur_console->status & UNKNOWN_MODE)) { + if (!ISGRAPHSC(cur_console)) { remove_cursor_image(cur_console); if (flags & CHAR_CURSOR) set_destructive_cursor(cur_console); @@ -1117,37 +991,22 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) lines = imax(*(int *)data, scp->ysize); lines0 = (scp->history != NULL) ? scp->history_size / scp->xsize : scp->ysize; + if (lines0 > imax(sc_history_size, scp->ysize)) + i = lines0 - imax(sc_history_size, scp->ysize); + else + i = 0; /* * syscons unconditionally allocates buffers upto SC_HISTORY_SIZE * lines or scp->ysize lines, whichever is larger. A value * greater than that is allowed, subject to extra_history_size. */ - if (lines > imax(lines0, SC_HISTORY_SIZE) + extra_history_size) - return EINVAL; + if (lines > imax(sc_history_size, scp->ysize)) + if (lines - imax(sc_history_size, scp->ysize) > + extra_history_size + i) + return EINVAL; if (cur_console->status & BUFFER_SAVED) return EBUSY; - usp = scp->history; - scp->history = NULL; - if (usp != NULL) - free(usp, M_DEVBUF); - scp->history_size = lines * scp->xsize; - /* - * extra_history_size += - * (lines0 > imax(SC_HISTORY_SIZE, scp->ysize)) ? - * lines0 - imax(SC_HISTORY_SIZE, scp->ysize)) : 0; - * extra_history_size -= - * (lines > imax(SC_HISTORY_SIZE, scp->ysize)) ? - * lines - imax(SC_HISTORY_SIZE, scp->ysize)) : 0; - * lines0 >= ysize && lines >= ysize... Hey, the above can be - * reduced to the following... - */ - extra_history_size += - imax(lines0, SC_HISTORY_SIZE) - imax(lines, SC_HISTORY_SIZE); - usp = (u_short *)malloc(scp->history_size * sizeof(u_short), - M_DEVBUF, M_WAITOK); - bzero(usp, scp->history_size * sizeof(u_short)); - scp->history_head = scp->history_pos = usp; - scp->history = usp; + sc_alloc_history_buffer(scp, lines, i, TRUE); return 0; } else @@ -1171,7 +1030,8 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) mouse_info_t *mouse = (mouse_info_t*)data; mouse_info_t buf; - if (crtc_type != KD_VGA || VESA_MODE(bios_video_mode)) + /* FIXME: */ + if (!ISMOUSEAVAIL(get_adapter(scp)->va_flags)) return ENODEV; if (cmd == OLD_CONS_MOUSECTL) { @@ -1220,7 +1080,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); @@ -1231,7 +1091,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; @@ -1276,7 +1136,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) { @@ -1321,7 +1181,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); @@ -1358,7 +1218,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) { @@ -1387,7 +1247,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) { @@ -1567,18 +1427,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; @@ -1597,226 +1480,6 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) splx(s); return 0; - /* VGA TEXT MODES */ - case SW_VGA_C40x25: - case SW_VGA_C80x25: case SW_VGA_M80x25: - case SW_VGA_C80x30: case SW_VGA_M80x30: - case SW_VGA_C80x50: case SW_VGA_M80x50: - case SW_VGA_C80x60: case SW_VGA_M80x60: - case SW_B40x25: case SW_C40x25: - case SW_B80x25: case SW_C80x25: - case SW_ENH_B40x25: case SW_ENH_C40x25: - case SW_ENH_B80x25: case SW_ENH_C80x25: - case SW_ENH_B80x43: case SW_ENH_C80x43: - case SW_EGAMONO80x25: - - if (crtc_type != KD_VGA) - return ENODEV; - mp = get_mode_param(scp, cmd & 0xff); - if (mp == NULL) - return ENODEV; - - s = spltty(); - if ((error = wait_scrn_saver_stop())) { - splx(s); - return error; - } - - scp->status &= ~MOUSE_VISIBLE; - remove_cutmarking(scp); - if (scp->history != NULL) - i = imax(scp->history_size / scp->xsize - - imax(SC_HISTORY_SIZE, scp->ysize), 0); - else - i = 0; - switch (cmd & 0xff) { - case M_VGA_C80x60: case M_VGA_M80x60: - if (!(fonts_loaded & FONT_8)) { - splx(s); - return EINVAL; - } - /* - * This is a kludge to fend off scrn_update() while we - * muck around with scp. XXX - */ - scp->status |= UNKNOWN_MODE; - scp->xsize = 80; - scp->ysize = 60; - scp->font_size = 8; - break; - case M_VGA_C80x50: case M_VGA_M80x50: - if (!(fonts_loaded & FONT_8)) { - splx(s); - return EINVAL; - } - scp->status |= UNKNOWN_MODE; - scp->xsize = 80; - scp->ysize = 50; - scp->font_size = 8; - break; - case M_ENH_B80x43: case M_ENH_C80x43: - if (!(fonts_loaded & FONT_8)) { - splx(s); - return EINVAL; - } - scp->status |= UNKNOWN_MODE; - scp->xsize = 80; - scp->ysize = 43; - scp->font_size = 8; - break; - case M_VGA_C80x30: case M_VGA_M80x30: - scp->status |= UNKNOWN_MODE; - scp->xsize = 80; - scp->ysize = 30; - scp->font_size = mp[2]; - break; - case M_ENH_C40x25: case M_ENH_B40x25: - case M_ENH_C80x25: case M_ENH_B80x25: - case M_EGAMONO80x25: - if (!(fonts_loaded & FONT_14)) { - splx(s); - return EINVAL; - } - /* FALL THROUGH */ - default: - if ((cmd & 0xff) > M_VGA_CG320) { - splx(s); - return EINVAL; - } - scp->status |= UNKNOWN_MODE; - scp->xsize = mp[0]; - scp->ysize = mp[1] + rows_offset; - scp->font_size = mp[2]; - break; - } - - scp->mode = cmd & 0xff; - scp->xpixel = scp->xsize * 8; - scp->ypixel = scp->ysize * scp->font_size; - free(scp->scr_buf, M_DEVBUF); - scp->scr_buf = (u_short *) - malloc(scp->xsize*scp->ysize*sizeof(u_short), M_DEVBUF, M_WAITOK); - /* move the text cursor to the home position */ - move_crsr(scp, 0, 0); - /* move the mouse cursor at the center of the screen */ - scp->mouse_xpos = scp->xpixel / 2; - scp->mouse_ypos = scp->ypixel / 2; - scp->mouse_pos = scp->mouse_oldpos = - scp->scr_buf + (scp->mouse_ypos / scp->font_size) * scp->xsize - + scp->mouse_xpos / 8; - /* allocate a larger cut buffer if necessary */ - if ((cut_buffer == NULL) - || (cut_buffer_size < scp->xsize * scp->ysize + 1)) { - if (cut_buffer != NULL) - free(cut_buffer, M_DEVBUF); - cut_buffer_size = scp->xsize * scp->ysize + 1; - cut_buffer = (char *)malloc(cut_buffer_size, M_DEVBUF, M_NOWAIT); - if (cut_buffer != NULL) - cut_buffer[0] = '\0'; - } - splx(s); - - usp = scp->history; - scp->history = NULL; - if (usp != NULL) { - free(usp, M_DEVBUF); - extra_history_size += i; - } - scp->history_size = imax(SC_HISTORY_SIZE, scp->ysize) * scp->xsize; - usp = (u_short *)malloc(scp->history_size * sizeof(u_short), - M_DEVBUF, M_NOWAIT); - if (usp != NULL) - bzero(usp, scp->history_size * sizeof(u_short)); - scp->history_head = scp->history_pos = usp; - scp->history = usp; - if (scp == cur_console) - set_mode(scp); - clear_screen(scp); - scp->status &= ~UNKNOWN_MODE; - - if (tp->t_winsize.ws_col != scp->xsize - || tp->t_winsize.ws_row != scp->ysize) { - tp->t_winsize.ws_col = scp->xsize; - tp->t_winsize.ws_row = scp->ysize; - pgsignal(tp->t_pgrp, SIGWINCH, 1); - } - return 0; - - /* GRAPHICS MODES */ - case SW_BG320: case SW_BG640: - case SW_CG320: case SW_CG320_D: case SW_CG640_E: - case SW_CG640x350: case SW_ENH_CG640: - case SW_BG640x480: case SW_CG640x480: case SW_VGA_CG320: - - if (crtc_type != KD_VGA) - return ENODEV; - mp = get_mode_param(scp, cmd & 0xff); - if (mp == NULL) - return ENODEV; - - s = spltty(); - if ((error = wait_scrn_saver_stop())) { - splx(s); - return error; - } - - scp->status &= ~MOUSE_VISIBLE; - remove_cutmarking(scp); - scp->status |= UNKNOWN_MODE; /* graphics mode */ - scp->mode = cmd & 0xFF; - scp->xpixel = mp[0] * 8; - scp->ypixel = (mp[1] + rows_offset) * mp[2]; - scp->font_size = FONT_NONE; - /* move the mouse cursor at the center of the screen */ - scp->mouse_xpos = scp->xpixel / 2; - scp->mouse_ypos = scp->ypixel / 2; - splx(s); - - if (scp == cur_console) - set_mode(scp); - /* clear_graphics();*/ - - if (tp->t_winsize.ws_xpixel != scp->xpixel - || tp->t_winsize.ws_ypixel != scp->ypixel) { - tp->t_winsize.ws_xpixel = scp->xpixel; - tp->t_winsize.ws_ypixel = scp->ypixel; - pgsignal(tp->t_pgrp, SIGWINCH, 1); - } - return 0; - - case SW_VGA_MODEX: - if (crtc_type != KD_VGA) - return ENODEV; - mp = get_mode_param(scp, cmd & 0xff); - if (mp == NULL) - return ENODEV; - - s = spltty(); - if ((error = wait_scrn_saver_stop())) { - splx(s); - return error; - } - - scp->status &= ~MOUSE_VISIBLE; - remove_cutmarking(scp); - scp->status |= UNKNOWN_MODE; /* graphics mode */ - scp->mode = cmd & 0xFF; - scp->xpixel = 320; - scp->ypixel = 240; - scp->font_size = FONT_NONE; - splx(s); - - if (scp == cur_console) - set_mode(scp); - /* clear_graphics();*/ - if (tp->t_winsize.ws_xpixel != scp->xpixel - || tp->t_winsize.ws_ypixel != scp->ypixel) { - tp->t_winsize.ws_xpixel = scp->xpixel; - tp->t_winsize.ws_ypixel = scp->ypixel; - pgsignal(tp->t_pgrp, SIGWINCH, 1); - } - return 0; - case VT_SETMODE: /* set screen switcher mode */ { struct vt_mode *mode; @@ -1839,7 +1502,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; @@ -1879,32 +1542,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 */ @@ -1920,102 +1583,28 @@ 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 */ - /* restore fonts & palette ! */ - if (crtc_type == KD_VGA) { - if (!VESA_MODE(scp->mode)) { -#if 0 - /* - * FONT KLUDGE - * Don't load fonts for now... XXX - */ - if (fonts_loaded & FONT_8) - copy_font(LOAD, FONT_8, font_8); - if (fonts_loaded & FONT_14) - copy_font(LOAD, FONT_14, font_14); - if (fonts_loaded & FONT_16) - copy_font(LOAD, FONT_16, font_16); -#endif - } - load_palette(palette); - } - - /* move hardware cursor out of the way */ - outb(crtc_addr, 14); - outb(crtc_addr + 1, 0xff); - outb(crtc_addr, 15); - outb(crtc_addr + 1, 0xff); - - /* FALL THROUGH */ - - case KD_TEXT1: /* switch to TEXT (known) mode */ - s = spltty(); - if ((error = wait_scrn_saver_stop())) { - splx(s); - return error; - } - scp->status &= ~MOUSE_VISIBLE; - remove_cutmarking(scp); - scp->status |= UNKNOWN_MODE; - splx(s); - /* no restore fonts & palette */ - if (crtc_type == KD_VGA) - set_mode(scp); - scp->status &= ~UNKNOWN_MODE; - clear_screen(scp); - return 0; - - case KD_GRAPHICS: /* switch to GRAPHICS (unknown) mode */ - s = spltty(); - if ((error = wait_scrn_saver_stop())) { - splx(s); - return error; - } - scp->status &= ~MOUSE_VISIBLE; - remove_cutmarking(scp); - scp->status |= UNKNOWN_MODE; - splx(s); - return 0; - default: - 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; + 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) */ - *data = scp->status & LOCK_KEY_MASK; + *(int *)data = scp->status & LOCK_KEY_MASK; return 0; case KDSETRAD: /* set keyboard repeat & delay rates */ - if (*data & 0x80) + if (*(int *)data & ~0x7f) return EINVAL; if (sc_kbdc != NULL) - set_keyboard(KBDC_SET_TYPEMATIC, *data); + set_keyboard(KBDC_SET_TYPEMATIC, *(int *)data); return 0; case KDSKBMODE: /* set keyboard mode */ - switch (*data) { + switch (*(int *)data) { case K_RAW: /* switch to RAW scancode mode */ scp->status &= ~KBD_CODE_MODE; scp->status |= KBD_RAW_MODE; @@ -2037,7 +1626,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; @@ -2074,21 +1663,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 */ @@ -2143,7 +1731,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) return 0; case PIO_FONT8x8: /* set 8x8 dot font */ - if (crtc_type != KD_VGA) + if (!ISFONTAVAIL(get_adapter(scp)->va_flags)) return ENXIO; bcopy(data, font_8, 8*256); fonts_loaded |= FONT_8; @@ -2152,17 +1740,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); @@ -2172,7 +1755,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; @@ -2181,17 +1764,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); @@ -2201,7 +1780,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; @@ -2210,17 +1789,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); @@ -2247,7 +1821,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? */ @@ -2329,7 +1903,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); @@ -2384,25 +1958,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); @@ -2461,6 +2038,8 @@ scrn_timer(void *arg) scintr(0); } + scp = cur_console; + /* should we stop the screen saver? */ getmicrouptime(&tv); if (panicstr || shutdown_in_progress) { @@ -2476,7 +2055,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 ? */ @@ -2488,14 +2067,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); @@ -2583,9 +2161,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; } @@ -2612,10 +2190,22 @@ remove_scrn_saver(void (*this_saver)(int)) return 0; } +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) @@ -2632,8 +2222,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) @@ -2642,8 +2232,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; @@ -2668,8 +2258,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; } @@ -2721,25 +2310,26 @@ exchange_scr(void) { move_crsr(old_scp, old_scp->xpos, old_scp->ypos); cur_console = new_scp; - if (old_scp->mode != new_scp->mode || (old_scp->status & UNKNOWN_MODE)){ - if (crtc_type == KD_VGA) + if (old_scp->mode != new_scp->mode || ISUNKNOWNSC(old_scp)) { + if (adp_flags & V_ADP_MODECHANGE) set_mode(new_scp); } move_crsr(new_scp, new_scp->xpos, new_scp->ypos); - if (!(new_scp->status & UNKNOWN_MODE) && (flags & CHAR_CURSOR)) + if (ISTEXTSC(new_scp) && (flags & CHAR_CURSOR)) set_destructive_cursor(new_scp); - if ((old_scp->status & UNKNOWN_MODE) && crtc_type == KD_VGA) - load_palette(palette); + if (ISGRAPHSC(old_scp)) + load_palette(new_scp, palette); if (old_scp->status & KBD_RAW_MODE || new_scp->status & KBD_RAW_MODE || old_scp->status & KBD_CODE_MODE || new_scp->status & KBD_CODE_MODE) shfts = ctls = alts = agrs = metas = accents = 0; - set_border(new_scp->border); + set_border(new_scp, new_scp->border); update_leds(new_scp->status); delayed_next_scr = FALSE; mark_all(new_scp); - if (new_scp->mode == 0x102) { - bzero(Crtat, 800*600/8); - } + + /* FIXME: the screen size may be larger than a 64K segment. */ + if (ISPIXELSC(new_scp)) + bzero(Crtat, new_scp->xpixel*new_scp->ypixel/8); } static void @@ -2788,7 +2378,7 @@ scan_esc(scr_stat *scp, u_char c) return; #endif case 'c': /* Clear screen & home */ - clear_screen(scp); + sc_clear_screen(scp); break; case '(': /* iso-2022: designate 94 character set to G0 */ @@ -2874,7 +2464,7 @@ scan_esc(scr_stat *scp, u_char c) scp->cursor_pos, scp->scr_buf + scp->xsize * scp->ysize - scp->cursor_pos); mark_for_update(scp, scp->cursor_pos - scp->scr_buf); - mark_for_update(scp, scp->xsize * scp->ysize); + mark_for_update(scp, scp->xsize * scp->ysize - 1); remove_cutmarking(scp); break; case 1: /* clear from beginning of display to cursor */ @@ -2936,7 +2526,7 @@ scan_esc(scr_stat *scp, u_char c) fillw(scp->term.cur_color | scr_map[0x20], src, n * scp->xsize); mark_for_update(scp, scp->ypos * scp->xsize); - mark_for_update(scp, scp->xsize * scp->ysize); + mark_for_update(scp, scp->xsize * scp->ysize - 1); break; case 'M': /* Delete n lines */ @@ -2951,7 +2541,7 @@ scan_esc(scr_stat *scp, u_char c) fillw(scp->term.cur_color | scr_map[0x20], src, n * scp->xsize); mark_for_update(scp, scp->ypos * scp->xsize); - mark_for_update(scp, scp->xsize * scp->ysize); + mark_for_update(scp, scp->xsize * scp->ysize - 1); break; case 'P': /* Delete n chars */ @@ -3192,7 +2782,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; @@ -3209,8 +2799,8 @@ scan_esc(scr_stat *scp, u_char c) flags |= BLINK_CURSOR; else flags &= ~BLINK_CURSOR; - if ((scp->term.param[0] & 0x02) && - crtc_type == KD_VGA && !VESA_MODE(bios_video_mode)) + if ((scp->term.param[0] & 0x02) + && ISFONTAVAIL(get_adapter(scp)->va_flags)) flags |= CHAR_CURSOR; else flags &= ~CHAR_CURSOR; @@ -3223,9 +2813,9 @@ scan_esc(scr_stat *scp, u_char c) * The cursor shape is global property; all virtual consoles * are affected. Update the cursor in the current console... */ - if (!(cur_console->status & UNKNOWN_MODE)) { + if (!ISGRAPHSC(cur_console)) { remove_cursor_image(cur_console); - if (crtc_type == KD_VGA && (flags & CHAR_CURSOR)) + if (flags & CHAR_CURSOR) set_destructive_cursor(cur_console); draw_cursor_image(cur_console); } @@ -3366,7 +2956,7 @@ ansi_put(scr_stat *scp, u_char *buf, int len) break; case 0x0c: /* form feed, clears screen */ - clear_screen(scp); + sc_clear_screen(scp); break; case 0x0d: /* return, return to pos 0 */ @@ -3413,42 +3003,17 @@ ansi_put(scr_stat *scp, u_char *buf, int len) static void scinit(void) { - u_int hw_cursor; + int col; + int row; u_int i; if (init_done != COLD) return; init_done = WARM; - /* - * Ensure a zero start address. This is mainly to recover after - * switching from pcvt using userconfig(). The registers are w/o - * for old hardware so it's too hard to relocate the active screen - * memory. - */ - outb(crtc_addr, 12); - outb(crtc_addr + 1, 0); - outb(crtc_addr, 13); - outb(crtc_addr + 1, 0); - - /* extract cursor location */ - outb(crtc_addr, 14); - hw_cursor = inb(crtc_addr + 1) << 8; - outb(crtc_addr, 15); - hw_cursor |= inb(crtc_addr + 1); - - /* - * Validate cursor location. It may be off the screen. Then we must - * not use it for the initial buffer offset. - */ - if (hw_cursor >= ROW * COL) - hw_cursor = (ROW - 1) * COL; - - /* move hardware cursor out of the way */ - outb(crtc_addr, 14); - outb(crtc_addr + 1, 0xff); - outb(crtc_addr, 15); - outb(crtc_addr + 1, 0xff); + /* extract the hardware cursor location and move it out of the way */ + (*biosvidsw.read_hw_cursor)(V_ADP_PRIMARY, &col, &row); + (*biosvidsw.set_hw_cursor)(V_ADP_PRIMARY, -1, -1); /* set up the first console */ current_default = &user_default; @@ -3456,51 +3021,22 @@ scinit(void) init_scp(console[0]); cur_console = console[0]; - /* discard the video mode table if we are not familiar with it... */ - if (video_mode_ptr) { - bzero(mode_map, sizeof(mode_map)); - bcopy(video_mode_ptr + MODE_PARAM_SIZE*console[0]->mode, - vgaregs2, sizeof(vgaregs2)); - switch (comp_vgaregs(vgaregs, video_mode_ptr - + MODE_PARAM_SIZE*console[0]->mode)) { - case COMP_IDENTICAL: - map_mode_table(mode_map, video_mode_ptr, M_VGA_CG320 + 1); - /* - * This is a kludge for Toshiba DynaBook SS433 whose BIOS video - * mode table entry has the actual # of rows at the offset 1; - * BIOSes from other manufacturers store the # of rows - 1 there. - * XXX - */ - rows_offset = vgaregs[1] + 1 - - video_mode_ptr[MODE_PARAM_SIZE*console[0]->mode + 1]; - break; - case COMP_SIMILAR: - map_mode_table(mode_map, video_mode_ptr, M_VGA_CG320 + 1); - mode_map[console[0]->mode] = vgaregs; - rows_offset = vgaregs[1] + 1 - - video_mode_ptr[MODE_PARAM_SIZE*console[0]->mode + 1]; - vgaregs[1] -= rows_offset - 1; - break; - case COMP_DIFFERENT: - default: - video_mode_ptr = NULL; - mode_map[console[0]->mode] = vgaregs; - rows_offset = 1; - break; - } - } - /* copy screen to temporary buffer */ - if (!VESA_MODE(console[0]->mode)) + if (ISTEXTSC(console[0])) generic_bcopy(Crtat, sc_buffer, console[0]->xsize * console[0]->ysize * sizeof(u_short)); console[0]->scr_buf = console[0]->mouse_pos = console[0]->mouse_oldpos = sc_buffer; - console[0]->cursor_pos = console[0]->cursor_oldpos = sc_buffer + hw_cursor; + if (col >= console[0]->xsize) + col = 0; + if (row >= console[0]->ysize) + row = console[0]->ysize - 1; + console[0]->xpos = col; + console[0]->ypos = row; + console[0]->cursor_pos = console[0]->cursor_oldpos = + sc_buffer + row*console[0]->xsize + col; console[0]->cursor_saveunder = *console[0]->cursor_pos; - console[0]->xpos = hw_cursor % COL; - console[0]->ypos = hw_cursor / COL; for (i=1; 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 } @@ -3551,52 +3085,79 @@ scshutdown(int howto, void *arg) shutdown_in_progress = TRUE; } -static void -map_mode_table(char *map[], char *table, int max) +int +sc_clean_up(scr_stat *scp) { - int i; + int error; - for(i = 0; i < max; ++i) - map[i] = table + i*MODE_PARAM_SIZE; - for(; i < MODE_MAP_SIZE; ++i) - map[i] = NULL; + if ((error = wait_scrn_saver_stop())) + return error; + scp->status &= ~MOUSE_VISIBLE; + remove_cutmarking(scp); + return 0; } -static int -map_mode_num(int mode) +void +sc_alloc_scr_buffer(scr_stat *scp, int wait, int clear) { - static struct { - int from; - int to; - } mode_map[] = { - { M_ENH_B80x43, M_ENH_B80x25 }, - { M_ENH_C80x43, M_ENH_C80x25 }, - { M_VGA_M80x30, M_VGA_M80x25 }, - { M_VGA_C80x30, M_VGA_C80x25 }, - { M_VGA_M80x50, M_VGA_M80x25 }, - { M_VGA_C80x50, M_VGA_C80x25 }, - { M_VGA_M80x60, M_VGA_M80x25 }, - { M_VGA_C80x60, M_VGA_C80x25 }, - { M_VGA_MODEX, M_VGA_CG320 }, - }; - int i; + if (scp->scr_buf) + free(scp->scr_buf, M_DEVBUF); + scp->scr_buf = (u_short *)malloc(scp->xsize*scp->ysize*sizeof(u_short), + M_DEVBUF, (wait) ? M_WAITOK : M_NOWAIT); - for (i = 0; i < sizeof(mode_map)/sizeof(mode_map[0]); ++i) { - if (mode_map[i].from == mode) - return mode_map[i].to; + if (clear) { + /* clear the screen and move the text cursor to the top-left position */ + sc_clear_screen(scp); + } else { + /* retain the current cursor position, but adjust pointers */ + move_crsr(scp, scp->xpos, scp->ypos); + scp->cursor_oldpos = scp->cursor_pos; } - return mode; + + /* move the mouse cursor at the center of the screen */ + sc_move_mouse(scp, scp->xpixel / 2, scp->ypixel / 2); } -static char -*get_mode_param(scr_stat *scp, int mode) +void +sc_alloc_cut_buffer(scr_stat *scp, int wait) { - if (mode >= MODE_MAP_SIZE) - mode = map_mode_num(mode); - if (mode < MODE_MAP_SIZE) - return mode_map[mode]; - else - return NULL; + if ((cut_buffer == NULL) + || (cut_buffer_size < scp->xsize * scp->ysize + 1)) { + if (cut_buffer != NULL) + free(cut_buffer, M_DEVBUF); + cut_buffer_size = scp->xsize * scp->ysize + 1; + cut_buffer = (u_char *)malloc(cut_buffer_size, + M_DEVBUF, (wait) ? M_WAITOK : M_NOWAIT); + if (cut_buffer != NULL) + cut_buffer[0] = '\0'; + } +} + +void +sc_alloc_history_buffer(scr_stat *scp, int lines, int extra, int wait) +{ + u_short *usp; + + if (lines < scp->ysize) + lines = scp->ysize; + + usp = scp->history; + scp->history = NULL; + if (usp != NULL) { + free(usp, M_DEVBUF); + if (extra > 0) + extra_history_size += extra; + } + + scp->history_size = lines * scp->xsize; + if (lines > imax(sc_history_size, scp->ysize)) + extra_history_size -= lines - imax(sc_history_size, scp->ysize); + usp = (u_short *)malloc(scp->history_size * sizeof(u_short), + M_DEVBUF, (wait) ? M_WAITOK : M_NOWAIT); + if (usp != NULL) + bzero(usp, scp->history_size * sizeof(u_short)); + scp->history_head = scp->history_pos = usp; + scp->history = usp; } static scr_stat @@ -3606,22 +3167,15 @@ static scr_stat scp = (scr_stat *)malloc(sizeof(scr_stat), M_DEVBUF, M_WAITOK); init_scp(scp); - scp->scr_buf = scp->cursor_pos = scp->cursor_oldpos = - (u_short *)malloc(scp->xsize*scp->ysize*sizeof(u_short), - M_DEVBUF, M_WAITOK); - scp->mouse_pos = scp->mouse_oldpos = - scp->scr_buf + ((scp->mouse_ypos/scp->font_size)*scp->xsize + - scp->mouse_xpos/8); - scp->history_head = scp->history_pos = - (u_short *)malloc(scp->history_size*sizeof(u_short), - M_DEVBUF, M_WAITOK); - bzero(scp->history_head, scp->history_size*sizeof(u_short)); - scp->history = scp->history_head; + sc_alloc_scr_buffer(scp, TRUE, TRUE); + if (ISMOUSEAVAIL(get_adapter(scp)->va_flags)) + sc_alloc_cut_buffer(scp, TRUE); + sc_alloc_history_buffer(scp, sc_history_size, 0, TRUE); /* SOS - if (crtc_type == KD_VGA && video_mode_ptr) + if (get_adapter(scp)->va_flags & V_ADP_MODECHANGE) set_mode(scp); */ - clear_screen(scp); + sc_clear_screen(scp); scp->cursor_saveunder = *scp->cursor_pos; return scp; } @@ -3629,43 +3183,29 @@ static scr_stat static void init_scp(scr_stat *scp) { - switch(crtc_type) { - case KD_VGA: - if (VESA_MODE(bios_video_mode)) - scp->mode = bios_video_mode; - else if (crtc_addr == MONO_BASE) - scp->mode = M_VGA_M80x25; - else - scp->mode = M_VGA_C80x25; - scp->font_size = 16; - break; - case KD_CGA: - if (crtc_addr == MONO_BASE) - scp->mode = M_B80x25; - else - scp->mode = M_C80x25; - scp->font_size = 8; - break; - case KD_EGA: - if (crtc_addr == MONO_BASE) - scp->mode = M_B80x25; - else - scp->mode = M_C80x25; - scp->font_size = 14; - break; - case KD_MONO: - case KD_HERCULES: - default: - scp->mode = M_EGAMONO80x25; - scp->font_size = 14; - break; - } - scp->initial_mode = scp->mode; + video_info_t info; - scp->xsize = COL; - scp->ysize = ROW; - scp->xpixel = scp->xsize * 8; - scp->ypixel = scp->ysize * scp->font_size; + 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; scp->xpos = scp->ypos = 0; scp->saved_xpos = scp->saved_ypos = -1; scp->start = scp->xsize * scp->ysize; @@ -3677,8 +3217,8 @@ init_scp(scr_stat *scp) current_default->std_color; scp->term.rev_color = current_default->rev_color; scp->border = BG_BLACK; - 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); scp->mouse_xpos = scp->xsize*8/2; scp->mouse_ypos = scp->ysize*scp->font_size/2; scp->mouse_cut_start = scp->mouse_cut_end = NULL; @@ -3687,13 +3227,13 @@ init_scp(scr_stat *scp) scp->mouse_proc = NULL; scp->bell_pitch = BELL_PITCH; scp->bell_duration = BELL_DURATION; - 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; scp->pid = 0; scp->proc = NULL; scp->smode.mode = VT_AUTO; scp->history_head = scp->history_pos = scp->history = NULL; - scp->history_size = imax(SC_HISTORY_SIZE, scp->ysize) * scp->xsize; + scp->history_size = imax(sc_history_size, scp->ysize) * scp->xsize; } static u_char @@ -4140,9 +3680,9 @@ scgetc(u_int flags) 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); } } } @@ -4409,475 +3949,100 @@ update_leds(int which) set_keyboard(KBDC_SET_LEDS, xlate_leds[which & LED_MASK]); } -void +int set_mode(scr_stat *scp) { - char special_modetable[MODE_PARAM_SIZE]; - char *mp; - int s; - int i; + video_info_t info; + video_adapter_t *adp; + /* 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; - - /* - * 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)); + return 0; /* setup video hardware for the given mode */ - switch (scp->mode) { - case M_VGA_C80x60: case M_VGA_M80x60: - special_modetable[2] = 0x08; - special_modetable[19] = 0x47; - goto special_480l; + adp = get_adapter(scp); + (*biosvidsw.set_mode)(scp->adp, scp->mode); + Crtat = (u_short *)adp->va_window; - 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 */ + if (!(scp->status & GRAPHICS_MODE)) { + /* load appropriate font */ + if (!(scp->status & PIXEL_MODE) + && ISFONTAVAIL(get_adapter(scp)->va_flags)) { + if (scp->font_size < 14) { + if (fonts_loaded & FONT_8) + copy_font(scp, LOAD, 8, font_8); + } else if (scp->font_size >= 16) { + if (fonts_loaded & FONT_16) + copy_font(scp, LOAD, 16, font_16); + } else { + if (fonts_loaded & FONT_14) + copy_font(scp, LOAD, 14, font_14); + } + /* + * FONT KLUDGE: + * This is an interim kludge to display correct font. + * Always use the font page #0 on the video plane 2. + * Somehow we cannot show the font in other font pages on + * some video cards... XXX + */ + (*biosvidsw.show_font)(scp->adp, 0); } - /* - * FONT KLUDGE: - * This is an interim kludge to display correct font. - * Always use the font page #0 on the video plane 2. - * Somehow we cannot show the font in other font pages on - * some video cards... XXX - */ - i = 0x00; - s = splhigh(); - outb(TSIDX, 0x00); outb(TSREG, 0x01); - outb(TSIDX, 0x03); outb(TSREG, i); - outb(TSIDX, 0x00); outb(TSREG, 0x03); - splx(s); + mark_all(scp); + } + set_border(scp, scp->border); + + /* move hardware cursor out of the way */ + (*biosvidsw.set_hw_cursor)(scp->adp, -1, -1); + + return 0; +} + +void +copy_font(scr_stat *scp, int operation, int font_size, u_char *buf) +{ + /* + * 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 (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; + } else if (operation == SAVE) { + (*biosvidsw.save_font)(scp->adp, 0, font_size, buf, 0, 256); } - - /* set border color for this (virtual) console */ - set_border(scp->border); - return; -} - -void -set_border(u_char color) -{ - switch (crtc_type) { - case KD_EGA: - case KD_VGA: - inb(crtc_addr + 6); /* reset flip-flop */ - outb(ATC, 0x31); outb(ATC, color); - break; - case KD_CGA: - outb(crtc_addr + 5, color & 0x0f); /* color select register */ - break; - case KD_MONO: - case KD_HERCULES: - default: - break; - } -} - -static void -set_vgaregs(char *modetable) -{ - int i, s = splhigh(); - - outb(TSIDX, 0x00); outb(TSREG, 0x01); /* stop sequencer */ - for (i=0; i<4; i++) { /* program sequencer */ - outb(TSIDX, i+1); - outb(TSREG, modetable[i+5]); - } - outb(MISC, modetable[9]); /* set dot-clock */ - outb(TSIDX, 0x00); outb(TSREG, 0x03); /* start sequencer */ - outb(crtc_addr, 0x11); - outb(crtc_addr+1, inb(crtc_addr+1) & 0x7F); - for (i=0; i<25; i++) { /* program crtc */ - outb(crtc_addr, i); - if (i == 14 || i == 15) /* no hardware cursor */ - outb(crtc_addr+1, 0xff); - else - outb(crtc_addr+1, modetable[i+10]); - } - inb(crtc_addr+6); /* reset flip-flop */ - for (i=0; i<20; i++) { /* program attribute ctrl */ - outb(ATC, i); - outb(ATC, modetable[i+35]); - } - for (i=0; i<9; i++) { /* program graph data ctrl */ - outb(GDCIDX, i); - outb(GDCREG, modetable[i+55]); - } - inb(crtc_addr+6); /* reset flip-flop */ - outb(ATC, 0x20); /* enable palette */ - splx(s); -} - -static void -read_vgaregs(char *buf) -{ - int i, j; - int s; - - bzero(buf, MODE_PARAM_SIZE); - - s = splhigh(); - - outb(TSIDX, 0x00); outb(TSREG, 0x01); /* stop sequencer */ - for (i=0, j=5; i<4; i++) { - outb(TSIDX, i+1); - buf[j++] = inb(TSREG); - } - buf[9] = inb(MISC + 10); /* dot-clock */ - outb(TSIDX, 0x00); outb(TSREG, 0x03); /* start sequencer */ - - for (i=0, j=10; i<25; i++) { /* crtc */ - outb(crtc_addr, i); - buf[j++] = inb(crtc_addr+1); - } - for (i=0, j=35; i<20; i++) { /* attribute ctrl */ - inb(crtc_addr+6); /* reset flip-flop */ - outb(ATC, i); - buf[j++] = inb(ATC + 1); - } - for (i=0, j=55; i<9; i++) { /* graph data ctrl */ - outb(GDCIDX, i); - buf[j++] = inb(GDCREG); - } - inb(crtc_addr+6); /* reset flip-flop */ - outb(ATC, 0x20); /* enable palette */ - - buf[0] = *(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); -} - -void -copy_font(int operation, int font_type, char* font_image) -{ - int ch, line, segment, fontsize; - u_char buf[PARAM_BUFSIZE]; - u_char val; - - switch (font_type) { - default: - case FONT_8: - segment = 0x8000; - fontsize = 8; - break; - case FONT_14: - segment = 0x4000; - fontsize = 14; - break; - case FONT_16: - segment = 0x0000; - fontsize = 16; - break; - } - /* - * FONT KLUDGE - * Always use the font page #0. XXX - */ - segment = 0x0000; - outb(TSIDX, 0x01); val = inb(TSREG); /* disable screen */ - outb(TSIDX, 0x01); outb(TSREG, val | 0x20); - set_font_mode(buf); - for (ch=0; ch < 256; ch++) - for (line=0; line < fontsize; line++) - if (operation) - *(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 */ } static void set_destructive_cursor(scr_stat *scp) { - 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) || !ISTEXTSC(scp)) + 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) @@ -4902,9 +4067,18 @@ 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; +} + +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 @@ -4916,7 +4090,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) @@ -5146,35 +4320,26 @@ mouse_paste(scr_stat *scp) static void draw_mouse_image(scr_stat *scp) { - 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_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), @@ -5209,9 +4374,11 @@ draw_mouse_image(scr_stat *scp) /* wait for vertical retrace to avoid jitter on some videocards */ while (!(inb(crtc_addr+6) & 0x08)) /* idle */ ; #endif - set_font_mode(buf); - 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); @@ -5229,6 +4396,8 @@ remove_mouse_image(scr_stat *scp) { u_short *crt_pos = Crtat + (scp->mouse_oldpos - scp->scr_buf); + if (!ISTEXTSC(scp)) + return; *(crt_pos) = *(scp->mouse_oldpos); *(crt_pos+1) = *(scp->mouse_oldpos+1); *(crt_pos+scp->xsize) = *(scp->mouse_oldpos+scp->xsize); @@ -5278,30 +4447,6 @@ remove_cutmarking(scr_stat *scp) mark_all(scp); } -static void -save_palette(void) -{ - int i; - - outb(PALRADR, 0x00); - for (i=0x00; i<0x300; i++) - palette[i] = inb(PALDATA); - inb(crtc_addr+6); /* reset flip/flop */ -} - -void -load_palette(char *palette) -{ - int i; - - outb(PIXMASK, 0xFF); /* no pixelmask */ - outb(PALWADR, 0x00); - for (i=0x00; i<0x300; i++) - outb(PALDATA, palette[i]); - inb(crtc_addr+6); /* reset flip/flop */ - outb(ATC, 0x20); /* enable palette */ -} - static void do_bell(scr_stat *scp, int pitch, int duration) { @@ -5330,7 +4475,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) @@ -5351,25 +4496,41 @@ blink_screen(void *arg) void sc_bcopy(scr_stat *scp, u_short *p, int from, int to, int mark) { - if (!VESA_MODE(scp->mode)) { - generic_bcopy(p+from, Crtat+from, (to-from+1)*sizeof (u_short)); - } else if (scp->mode == 0x102) { - u_char *d, *e; - int i,j; + u_char *font; + u_char *d, *e; + u_char *f; + int font_size; + int line_length; + int xsize; + int i, j; + if (ISTEXTSC(scp)) { + generic_bcopy(p+from, Crtat+from, (to-from+1)*sizeof (u_short)); + } else /* if ISPIXELSC(scp) */ { if (mark) - mark = 255; - d = (u_char *)Crtat; - d += 10 + 6*16*100 + (from%80) + 16*100*(from/80); + mark = 255; + font_size = scp->font_size; + if (font_size < 14) + font = font_8; + else if (font_size >= 16) + font = font_16; + else + font = font_14; + line_length = scp->xpixel/8; + xsize = scp->xsize; + d = (u_char *)Crtat + + scp->xoff + scp->yoff*font_size*line_length + + (from%xsize) + font_size*line_length*(from/xsize); for (i = from ; i <= to ; i++) { e = d; - for (j = 0 ; j < 16; j++) { - *e = mark^font_16[(p[i]&0xff)*16+j]; - e+=100; + f = &font[(p[i] & 0x00ff)*font_size]; + for (j = 0 ; j < font_size; j++, f++) { + *e = mark^*f; + e += line_length; } d++; - if ((i % 80) == 79) - d += 20 + 15*100; + if ((i % xsize) == xsize - 1) + d += scp->xoff*2 + (font_size - 1)*line_length; } } } @@ -5377,34 +4538,36 @@ sc_bcopy(scr_stat *scp, u_short *p, int from, int to, int mark) #ifdef SC_SPLASH_SCREEN static void -scsplash_init(void) +scsplash_init(scr_stat *scp) { + video_info_t info; + /* * We currently assume the splash screen always use * VGA_CG320 mode and abort installation if this mode is not * supported with this video card. XXX */ - if (crtc_type != KD_VGA || get_mode_param(cur_console, M_VGA_CG320) == NULL) + if ((*biosvidsw.get_info)(scp->adp, M_VGA_CG320, &info)) return; - if (splash_load() == 0 && add_scrn_saver(scsplash) == 0) { - default_saver = scsplash; + if (scsplash_load(scp) == 0 && add_scrn_saver(scsplash_saver) == 0) { + default_saver = scsplash_saver; scrn_blank_time = DEFAULT_BLANKTIME; run_scrn_saver = TRUE; - if (!(boothowto & RB_CONFIG)) { + if (!(boothowto & (RB_VERBOSE | RB_CONFIG))) { scsplash_stick(TRUE); - scsplash(TRUE); + scsplash_saver(TRUE); } } } static void -scsplash(int show) +scsplash_saver(int show) { if (show) - splash(TRUE); + scsplash(TRUE); else if (!sticky_splash) - splash(FALSE); + scsplash(FALSE); } #endif /* SC_SPLASH_SCREEN */ diff --git a/sys/dev/syscons/syscons.h b/sys/dev/syscons/syscons.h index b23a2ae7c5da..315946b57305 100644 --- a/sys/dev/syscons/syscons.h +++ b/sys/dev/syscons/syscons.h @@ -1,18 +1,18 @@ /*- - * Copyright (c) 1995-1997 Søren Schmidt + * Copyright (c) 1995-1998 Søren Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. + * notice, this list of conditions and the following disclaimer, + * without modification, immediately at the beginning of the file. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission + * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES @@ -25,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.38 1998/08/03 09:09:35 yokota Exp $ + * $Id$ */ #ifndef _I386_ISA_SYSCONS_H_ @@ -65,6 +65,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 +77,7 @@ #define XT_KEYBD 0x00010 #define KBD_NORESET 0x00020 #define QUIET_BELL 0x00040 +#define VESA800X600 0x00080 /* attribute flags */ #define NORMAL_ATTR 0x00 @@ -84,9 +88,6 @@ #define FOREGROUND_CHANGED 0x10 #define BACKGROUND_CHANGED 0x20 -/* video hardware memory addresses */ -#define VIDEOMEM 0x000A0000 - /* misc defines */ #define FALSE 0 #define TRUE 1 @@ -104,20 +105,6 @@ #define FONT_14 4 #define FONT_16 8 -/* defines related to hardware addresses */ -#define MONO_BASE 0x3B4 /* crt controller base mono */ -#define COLOR_BASE 0x3D4 /* crt controller base color */ -#define MISC 0x3C2 /* misc output register */ -#define ATC IO_VGA+0x00 /* attribute controller */ -#define TSIDX IO_VGA+0x04 /* timing sequencer idx */ -#define TSREG IO_VGA+0x05 /* timing sequencer data */ -#define PIXMASK IO_VGA+0x06 /* pixel write mask */ -#define PALRADR IO_VGA+0x07 /* palette read address */ -#define PALWADR IO_VGA+0x08 /* palette write address */ -#define PALDATA IO_VGA+0x09 /* palette data register */ -#define GDCIDX IO_VGA+0x0E /* graph data controller idx */ -#define GDCREG IO_VGA+0x0F /* graph data controller data */ - /* special characters */ #define cntlc 0x03 #define cntld 0x04 @@ -141,6 +128,7 @@ typedef struct term_stat { } term_stat; typedef struct scr_stat { + int adp; /* video adapter index */ u_short *scr_buf; /* buffer when off screen */ int xpos; /* current X position */ int ypos; /* current Y position */ @@ -150,6 +138,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 */ @@ -186,7 +176,8 @@ 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 } scr_stat; @@ -195,18 +186,59 @@ typedef struct default_attr { int rev_color; /* reverse hardware color */ } default_attr; + +#define ISTEXTSC(scp) (!((scp)->status \ + & (UNKNOWN_MODE | GRAPHICS_MODE | PIXEL_MODE))) +#define ISGRAPHSC(scp) (((scp)->status \ + & (UNKNOWN_MODE | GRAPHICS_MODE))) +#define ISPIXELSC(scp) (((scp)->status \ + & (UNKNOWN_MODE | GRAPHICS_MODE | PIXEL_MODE))\ + == PIXEL_MODE) +#define ISUNKNOWNSC(scp) ((scp)->status & UNKNOWN_MODE) + +#define ISFONTAVAIL(af) ((af) & V_ADP_FONT) +#define ISMOUSEAVAIL(af) ((af) & V_ADP_FONT) +#define ISPALAVAIL(af) ((af) & V_ADP_PALETTE) + /* misc prototypes used by different syscons related LKM's */ -void set_border(u_char color); -void set_mode(scr_stat *scp); -void copy_font(int operation, int font_type, char* font_image); -void load_palette(char *palette); + +/* syscons.c */ +extern int (*sc_user_ioctl)(dev_t dev, int cmd, caddr_t data, int flag, + struct proc *p); + +int set_mode(scr_stat *scp); +scr_stat *sc_get_scr_stat(dev_t dev); + +void copy_font(scr_stat *scp, int operation, int font_size, u_char *font_image); +#define save_palette(scp, pal) (*biosvidsw.save_palette)((scp)->adp, pal) +#define load_palette(scp, pal) (*biosvidsw.load_palette)((scp)->adp, pal) +#define set_border(scp, col) (*biosvidsw.set_border)((scp)->adp, col) +#define get_adapter(scp) (*biosvidsw.adapter)((scp)->adp) + int add_scrn_saver(void (*this)(int)); int remove_scrn_saver(void (*this)(int)); +void sc_clear_screen(scr_stat *scp); +void sc_move_mouse(scr_stat *scp, int x, int y); +int sc_clean_up(scr_stat *scp); +void sc_alloc_scr_buffer(scr_stat *scp, int wait, int clear); +void sc_alloc_cut_buffer(scr_stat *scp, int wait); +void sc_alloc_history_buffer(scr_stat *scp, int lines, int extra, int wait); + +/* scvidctl.c */ +int sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, + int xsize, int ysize, int fontsize); +int sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode); +int sc_set_pixel_mode(scr_stat *scp, struct tty *tp, + int xsize, int ysize, int fontsize); +int sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, + struct proc *p); + #ifdef SC_SPLASH_SCREEN -void splash(int); -int splash_load(void); -int splash_unload(void); +/* splash.c */ +void scsplash(int); +int scsplash_load(scr_stat *scp); +int scsplash_unload(scr_stat *scp); #endif #endif /* !_I386_ISA_SYSCONS_H_ */ diff --git a/sys/i386/conf/LINT b/sys/i386/conf/LINT index 2d8c4a883224..8b20f861bacc 100644 --- a/sys/i386/conf/LINT +++ b/sys/i386/conf/LINT @@ -2,7 +2,7 @@ # LINT -- config file for checking all the sources, tries to pull in # as much of the source tree as it can. # -# $Id: LINT,v 1.464 1998/09/15 10:01:13 gibbs Exp $ +# $Id: LINT,v 1.465 1998/09/15 11:44:43 phk Exp $ # # NB: You probably don't want to try running a kernel built from this # file. Instead, you should start from GENERIC, and add options from @@ -803,6 +803,9 @@ options SC_HISTORY_SIZE=200 # number of history buffer lines options SC_DISABLE_REBOOT # disable reboot key sequence # If the screen flickers badly when the mouse pointer is moved, try this. options SC_BAD_FLICKER +# To include support for VESA video modes +# Dont use together with SMP!! +options VESA # needs VM86 defined too!! # # `flags' for sc0: diff --git a/sys/i386/conf/NOTES b/sys/i386/conf/NOTES index 2d8c4a883224..8b20f861bacc 100644 --- a/sys/i386/conf/NOTES +++ b/sys/i386/conf/NOTES @@ -2,7 +2,7 @@ # LINT -- config file for checking all the sources, tries to pull in # as much of the source tree as it can. # -# $Id: LINT,v 1.464 1998/09/15 10:01:13 gibbs Exp $ +# $Id: LINT,v 1.465 1998/09/15 11:44:43 phk Exp $ # # NB: You probably don't want to try running a kernel built from this # file. Instead, you should start from GENERIC, and add options from @@ -803,6 +803,9 @@ options SC_HISTORY_SIZE=200 # number of history buffer lines options SC_DISABLE_REBOOT # disable reboot key sequence # If the screen flickers badly when the mouse pointer is moved, try this. options SC_BAD_FLICKER +# To include support for VESA video modes +# Dont use together with SMP!! +options VESA # needs VM86 defined too!! # # `flags' for sc0: diff --git a/sys/i386/conf/files.i386 b/sys/i386/conf/files.i386 index 5302df40d509..6a0847003632 100644 --- a/sys/i386/conf/files.i386 +++ b/sys/i386/conf/files.i386 @@ -1,7 +1,7 @@ # This file tells config what files go into building a kernel, # files marked standard are always included. # -# $Id: files.i386,v 1.202 1998/09/08 20:57:46 sos Exp $ +# $Id: files.i386,v 1.203 1998/09/15 10:01:13 gibbs Exp $ # # The long compile-with and dependency lines are required because of # limitations in config: backslash-newline doesn't work in strings, and @@ -240,6 +240,10 @@ i386/isa/spigot.c optional spigot device-driver i386/isa/spkr.c optional speaker device-driver i386/isa/stallion.c optional stl device-driver i386/isa/syscons.c optional sc device-driver +i386/isa/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 i386/isa/tw.c optional tw device-driver #i386/isa/ultra14f.c optional uha device-driver i386/isa/wd.c optional wdc device-driver diff --git a/sys/i386/conf/options.i386 b/sys/i386/conf/options.i386 index c07d086cbdf4..21c45983b680 100644 --- a/sys/i386/conf/options.i386 +++ b/sys/i386/conf/options.i386 @@ -1,4 +1,4 @@ -# $Id: options.i386,v 1.85 1998/09/08 18:09:50 brian Exp $ +# $Id: options.i386,v 1.86 1998/09/15 10:01:14 gibbs Exp $ BOUNCEPAGES opt_bounce.h DISABLE_PSE @@ -77,6 +77,8 @@ SC_DISABLE_REBOOT opt_syscons.h SC_MOUSE_CHAR opt_syscons.h SC_BAD_FLICKER opt_syscons.h +VESA opt_vesa.h + PSM_HOOKAPM opt_psm.h PSM_RESETAFTERSUSPEND opt_psm.h PSM_DEBUG opt_psm.h diff --git a/sys/i386/include/console.h b/sys/i386/include/console.h index 7503746c8420..3373e608eabf 100644 --- a/sys/i386/include/console.h +++ b/sys/i386/include/console.h @@ -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: console.h,v 1.37 1998/07/06 06:29:06 imp Exp $ + * $Id: console.h,v 1.38 1998/08/03 11:30:28 yokota Exp $ */ #ifndef _MACHINE_CONSOLE_H_ @@ -51,6 +51,7 @@ #define KDGETLED _IOR('K', 65, int) #define KDSETLED _IO('K', 66 /*, int */) #define KDSETRAD _IO('K', 67 /*, int */) +#define KDRASTER _IOW('K', 100, scr_size_t) #define GETFKEY _IOWR('k', 0, fkeyarg_t) #define SETFKEY _IOWR('k', 1, fkeyarg_t) @@ -84,6 +85,11 @@ #define GIO_FONT8x16 _IOR('c', 69, fnt16_t) #define CONS_GETINFO _IOWR('c', 73, vid_info_t) #define CONS_GETVERS _IOR('c', 74, int) +#define CONS_CURRENTADP _IOR('c', 100, int) +#define CONS_ADPINFO _IOWR('c', 101, video_adapter_t) +#define CONS_MODEINFO _IOWR('c', 102, video_info_t) +#define CONS_FINDMODE _IOWR('c', 103, video_info_t) +#define CONS_SETWINORG _IO('c', 104 /* u_int */) /* CONS_SAVERMODE */ #define CONS_LKM_SAVER 0 @@ -169,6 +175,7 @@ struct mouse_info { #define KD_TEXT0 0 /* ditto */ #define KD_TEXT1 2 /* set text mode !restore fonts */ #define KD_GRAPHICS 1 /* set graphics mode */ +#define KD_PIXEL 3 /* set pixel mode */ #define K_RAW 0 /* keyboard returns scancodes */ #define K_XLATE 1 /* keyboard returns ascii */ @@ -263,6 +270,55 @@ struct ssaver { long time; }; +/* adapter infromation block */ +struct video_adapter { + int va_index; + int va_type; + int va_flags; +#define V_ADP_COLOR (1<<0) +#define V_ADP_MODECHANGE (1<<1) +#define V_ADP_STATESAVE (1<<2) +#define V_ADP_STATELOAD (1<<3) +#define V_ADP_FONT (1<<4) +#define V_ADP_PALETTE (1<<5) +#define V_ADP_BORDER (1<<6) +#define V_ADP_VESA (1<<7) + int va_crtc_addr; + u_int va_window; /* virtual address */ + size_t va_window_size; + size_t va_window_gran; + u_int va_buffer; /* virtual address */ + size_t va_buffer_size; + int va_initial_mode; + int va_initial_bios_mode; + int va_mode; +}; + +#define V_ADP_PRIMARY 0 +#define V_ADP_SECONDARY 1 + +/* video mode information block */ +struct video_info { + int vi_mode; + int vi_flags; +#define V_INFO_COLOR (1<<0) +#define V_INFO_GRAPHICS (1<<1) +#define V_INFO_LENEAR (1<<2) +#define V_INFO_VESA (1<<3) + int vi_width; + int vi_height; + int vi_cwidth; + int vi_cheight; + int vi_depth; + int vi_planes; + u_int vi_window; /* physical address */ + size_t vi_window_size; + size_t vi_window_gran; + u_int vi_buffer; /* physical address */ + size_t vi_buffer_size; + /* XXX pixel format, memory model,... */ +}; + typedef struct accentmap accentmap_t; typedef struct fkeytab fkeytab_t; typedef struct fkeyarg fkeyarg_t; @@ -273,6 +329,9 @@ typedef struct {char fnt8x8[8*256];} fnt8_t; typedef struct {char fnt8x14[14*256];} fnt14_t; typedef struct {char fnt8x16[16*256];} fnt16_t; typedef struct ssaver ssaver_t; +typedef struct video_adapter video_adapter_t; +typedef struct video_info video_info_t; +typedef struct {int scr_size[3];} scr_size_t; /* defines for "special" keys (spcl bit set in keymap) */ #define NOP 0x00 /* nothing (dead key) */ @@ -378,8 +437,6 @@ typedef struct ssaver ssaver_t; #define M_HGC_P1 0xe1 /* hercules graphics - page 1 @ B8000 */ #define M_MCA_MODE 0xff /* monochrome adapter mode */ -#define M_VESA_BASE 0x100 /* VESA mode number base */ - #define SW_PC98_80x25 _IO('S', M_PC98_80x25) #define SW_PC98_80x30 _IO('S', M_PC98_80x30) #define SW_B40x25 _IO('S', M_B40x25) @@ -421,4 +478,68 @@ typedef struct ssaver ssaver_t; #define SW_VGA_CG640 _IO('S', M_VGA_CG640) #define SW_VGA_MODEX _IO('S', M_VGA_MODEX) +#define M_VESA_BASE 0x100 /* VESA mode number base */ + +#define M_VESA_CG640x400 0x100 /* 640x400, 256 color */ +#define M_VESA_CG640x480 0x101 /* 640x480, 256 color */ +#define M_VESA_800x600 0x102 /* 800x600, 16 color */ +#define M_VESA_CG800x600 0x103 /* 800x600, 256 color */ +#define M_VESA_1024x768 0x104 /* 1024x768, 16 color */ +#define M_VESA_CG1024x768 0x105 /* 1024x768, 256 color */ +#define M_VESA_1280x1024 0x106 /* 1280x1024, 16 color */ +#define M_VESA_CG1280x1024 0x107 /* 1280x1024, 256 color */ +#define M_VESA_C80x60 0x108 /* 8x8 font */ +#define M_VESA_C132x25 0x109 /* 8x16 font */ +#define M_VESA_C132x43 0x10a /* 8x14 font */ +#define M_VESA_C132x50 0x10b /* 8x8 font */ +#define M_VESA_C132x60 0x10c /* 8x8 font */ +#define M_VESA_32K_320 0x10d /* 320x200, 5:5:5 */ +#define M_VESA_64K_320 0x10e /* 320x200, 5:6:5 */ +#define M_VESA_FULL_320 0x10f /* 320x200, 8:8:8 */ +#define M_VESA_32K_640 0x110 /* 640x480, 5:5:5 */ +#define M_VESA_64K_640 0x111 /* 640x480, 5:6:5 */ +#define M_VESA_FULL_640 0x112 /* 640x480, 8:8:8 */ +#define M_VESA_32K_800 0x113 /* 800x600, 5:5:5 */ +#define M_VESA_64K_800 0x114 /* 800x600, 5:6:5 */ +#define M_VESA_FULL_800 0x115 /* 800x600, 8:8:8 */ +#define M_VESA_32K_1024 0x116 /* 1024x768, 5:5:5 */ +#define M_VESA_64K_1024 0x117 /* 1024x768, 5:6:5 */ +#define M_VESA_FULL_1024 0x118 /* 1024x768, 8:8:8 */ +#define M_VESA_32K_1280 0x119 /* 1280x1024, 5:5:5 */ +#define M_VESA_64K_1280 0x11a /* 1280x1024, 5:6:5 */ +#define M_VESA_FULL_1280 0x11b /* 1280x1024, 8:8:8 */ +#define M_VESA_MODE_MAX 0x1ff +#define M_VESA_USER 0x1ff + +#define SW_VESA_CG640x400 _IO('V', M_VESA_CG640x400 - M_VESA_BASE) +#define SW_VESA_CG640x480 _IO('V', M_VESA_CG640x480 - M_VESA_BASE) +#define SW_VESA_800x600 _IO('V', M_VESA_800x600 - M_VESA_BASE) +#define SW_VESA_CG800x600 _IO('V', M_VESA_CG800x600 - M_VESA_BASE) +#define SW_VESA_1024x768 _IO('V', M_VESA_1024x768 - M_VESA_BASE) +#define SW_VESA_CG1024x768 _IO('V', M_VESA_CG1024x768 - M_VESA_BASE) +#define SW_VESA_1280x1024 _IO('V', M_VESA_1280x1024 - M_VESA_BASE) +#define SW_VESA_CG1280x1024 _IO('V', M_VESA_CG1280x1024 - M_VESA_BASE) +#define SW_VESA_C80x60 _IO('V', M_VESA_C80x60 - M_VESA_BASE) +#define SW_VESA_C132x25 _IO('V', M_VESA_C132x25 - M_VESA_BASE) +#define SW_VESA_C132x43 _IO('V', M_VESA_C132x43 - M_VESA_BASE) +#define SW_VESA_C132x50 _IO('V', M_VESA_C132x50 - M_VESA_BASE) +#define SW_VESA_C132x60 _IO('V', M_VESA_C132x60 - M_VESA_BASE) +#define SW_VESA_32K_320 _IO('V', M_VESA_32K_320 - M_VESA_BASE) +#define SW_VESA_64K_320 _IO('V', M_VESA_64K_320 - M_VESA_BASE) +#define SW_VESA_FULL_320 _IO('V', M_VESA_FULL_320 - M_VESA_BASE) +#define SW_VESA_32K_640 _IO('V', M_VESA_32K_640 - M_VESA_BASE) +#define SW_VESA_64K_640 _IO('V', M_VESA_64K_640 - M_VESA_BASE) +#define SW_VESA_FULL_640 _IO('V', M_VESA_FULL_640 - M_VESA_BASE) +#define SW_VESA_32K_800 _IO('V', M_VESA_32K_800 - M_VESA_BASE) +#define SW_VESA_64K_800 _IO('V', M_VESA_64K_800 - M_VESA_BASE) +#define SW_VESA_FULL_800 _IO('V', M_VESA_FULL_800 - M_VESA_BASE) +#define SW_VESA_32K_1024 _IO('V', M_VESA_32K_1024 - M_VESA_BASE) +#define SW_VESA_64K_1024 _IO('V', M_VESA_64K_1024 - M_VESA_BASE) +#define SW_VESA_FULL_1024 _IO('V', M_VESA_FULL_1024 - M_VESA_BASE) +#define SW_VESA_32K_1280 _IO('V', M_VESA_32K_1280 - M_VESA_BASE) +#define SW_VESA_64K_1280 _IO('V', M_VESA_64K_1280 - M_VESA_BASE) +#define SW_VESA_FULL_1280 _IO('V', M_VESA_FULL_1280 - M_VESA_BASE) +#define SW_VESA_USER _IO('V', M_VESA_USER - M_VESA_BASE) + #endif /* !_MACHINE_CONSOLE_H_ */ + diff --git a/sys/i386/include/pc/vesa.h b/sys/i386/include/pc/vesa.h new file mode 100644 index 000000000000..4fa38eee14b3 --- /dev/null +++ b/sys/i386/include/pc/vesa.h @@ -0,0 +1,127 @@ +/*- + * Copyright (c) 1998 Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#ifndef _MACHINE_PC_VESA_H +#define _MACHINE_PC_VESA_H + +struct vesa_info +{ + /* mandatory fields */ + u_int8_t v_sig[4] __attribute__ ((packed)); /* VESA */ + u_int16_t v_version __attribute__ ((packed)); /* ver in BCD */ + u_int32_t v_oemstr __attribute__ ((packed)); /* OEM string */ + u_int32_t v_flags __attribute__ ((packed)); /* flags */ +#define V_DAC8 (1<<0) +#define V_NONVGA (1<<1) +#define V_SNOW (1<<2) + u_int32_t v_modetable __attribute__ ((packed)); /* modes */ + u_int16_t v_memsize __attribute__ ((packed)); /* in 64K */ + /* 2.0 */ + u_int16_t v_revision __attribute__ ((packed)); /* software rev */ + u_int32_t v_venderstr __attribute__ ((packed)); /* vender */ + u_int32_t v_prodstr __attribute__ ((packed)); /* product name */ + u_int32_t v_revstr __attribute__ ((packed)); /* product rev */ +}; + +struct vesa_mode +{ + /* mandatory fields */ + u_int16_t v_modeattr; +#define V_MODESUPP (1<<0) /* VESA mode attributes */ +#define V_MODEOPTINFO (1<<1) +#define V_MODEBIOSOUT (1<<2) +#define V_MODECOLOR (1<<3) +#define V_MODEGRAPHICS (1<<4) +#define V_MODENONVGA (1<<5) +#define V_MODENONBANK (1<<6) +#define V_MODELFB (1<<7) +#define V_MODEVESA (1<<16) /* Private attributes */ + u_int8_t v_waattr; + u_int8_t v_wbattr; +#define V_WATTREXIST (1<<0) +#define V_WATTRREAD (1<<1) +#define V_WATTRWRITE (1<<2) + u_int16_t v_wgran; + u_int16_t v_wsize; + u_int16_t v_waseg; + u_int16_t v_wbseg; + u_int32_t v_posfunc; + u_int16_t v_bpscanline; + /* fields optional for 1.0/1.1 implementations */ + u_int16_t v_width; + u_int16_t v_height; + u_int8_t v_cwidth; + u_int8_t v_cheight; + u_int8_t v_planes; + u_int8_t v_bpp; + u_int8_t v_banks; + u_int8_t v_memmodel; +#define V_MMTEXT 0 +#define V_MMCGA 1 +#define V_MMHGC 2 +#define V_MMEGA 3 +#define V_MMPACKED 4 +#define V_MMSEQU256 5 +#define V_MMDIRCOLOR 6 +#define V_MMYUV 7 + u_int8_t v_banksize; + u_int8_t v_ipages; + u_int8_t v_reserved0; + /* fields for 1.2+ implementations */ + u_int8_t v_redmasksize; + u_int8_t v_redfieldpos; + u_int8_t v_greenmasksize; + u_int8_t v_greenfieldpos; + u_int8_t v_bluemasksize; + u_int8_t v_bluefieldpos; + u_int8_t v_resmasksize; + u_int8_t v_resfieldpos; + u_int8_t v_dircolormode; + /* 2.0 implementations */ + u_int32_t v_lfb; + u_int32_t v_offscreen; + u_int8_t v_offscreensize; +}; + +#ifdef KERNEL + +#define VESA_MODE(x) ((x) >= M_VESA_BASE) + +int vesa_load_ioctl(void); +int vesa_unload_ioctl(void); + +#ifndef VESA_MODULE +int vesa_load(void); +#endif + +#endif /* KERNEL */ + +#endif /* !_MACHINE_PC_VESA_H */ diff --git a/sys/i386/isa/kbdtables.h b/sys/i386/isa/kbdtables.h index d36b39a33e7a..61376f48b919 100644 --- a/sys/i386/isa/kbdtables.h +++ b/sys/i386/isa/kbdtables.h @@ -1,18 +1,18 @@ /*- - * Copyright (c) 1992-1995 Søren Schmidt + * Copyright (c) 1992-1998 Søren Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. + * notice, this list of conditions and the following disclaimer, + * without modification, immediately at the beginning of the file. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products - * derived from this software withough specific prior written permission + * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES @@ -25,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: kbdtables.h,v 1.39 1998/01/28 08:45:18 yokota Exp $ + * $Id$ */ #define SET8 0x80 /* set eight bit on */ diff --git a/sys/i386/isa/pcaudio.c b/sys/i386/isa/pcaudio.c index 25b5237a76dc..e2b0c6557835 100644 --- a/sys/i386/isa/pcaudio.c +++ b/sys/i386/isa/pcaudio.c @@ -1,18 +1,18 @@ /*- - * Copyright (c) 1994 Søren Schmidt + * Copyright (c) 1994-1998 Søren Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. + * notice, this list of conditions and the following disclaimer, + * without modification, immediately at the beginning of the file. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products - * derived from this software withough specific prior written permission + * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES @@ -25,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: pcaudio.c,v 1.41 1998/06/07 17:10:48 dfr Exp $ + * $Id$ */ #include "pca.h" diff --git a/sys/i386/isa/scvesactl.c b/sys/i386/isa/scvesactl.c new file mode 100644 index 000000000000..9678177d4011 --- /dev/null +++ b/sys/i386/isa/scvesactl.c @@ -0,0 +1,150 @@ +/*- + * Copyright (c) 1998 Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#include "sc.h" +#include "opt_vesa.h" +#include "opt_vm86.h" + +#if (NSC > 0 && defined(VESA) && defined(VM86)) || defined(VESA_MODULE) + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +static int (*prev_user_ioctl)(dev_t dev, int cmd, caddr_t data, int flag, + struct proc *p); + +extern struct tty *scdevtotty(dev_t dev); + +int +vesa_ioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) +{ + scr_stat *scp; + struct tty *tp; + video_info_t info; + video_adapter_t *adp; + int mode; + int error; + int s; + + tp = scdevtotty(dev); + if (!tp) + return ENXIO; + scp = sc_get_scr_stat(tp->t_dev); + + switch (cmd) { + case SW_VESA_USER: + + mode = (int)data; + if ((*biosvidsw.get_info)(scp->adp, mode, &info)) + return ENODEV; + if (info.vi_flags & V_INFO_GRAPHICS) + goto vesa_graphics; + else + goto vesa_text; + + /* text modes */ + case SW_VESA_C80x60: + case SW_VESA_C132x25: + case SW_VESA_C132x43: + case SW_VESA_C132x50: + case SW_VESA_C132x60: + adp = get_adapter(scp); + if (!(adp->va_flags & V_ADP_MODECHANGE)) + return ENODEV; + mode = (cmd & 0xff) + M_VESA_BASE; +vesa_text: + return sc_set_text_mode(scp, tp, mode, 0, 0, 0); + + /* graphics modes */ + case SW_VESA_32K_320: case SW_VESA_64K_320: + case SW_VESA_FULL_320: + + case SW_VESA_CG640x400: + + case SW_VESA_CG640x480: + case SW_VESA_32K_640: case SW_VESA_64K_640: + case SW_VESA_FULL_640: + + case SW_VESA_800x600: case SW_VESA_CG800x600: + case SW_VESA_32K_800: case SW_VESA_64K_800: + case SW_VESA_FULL_800: + + case SW_VESA_1024x768: case SW_VESA_CG1024x768: + case SW_VESA_32K_1024: case SW_VESA_64K_1024: + case SW_VESA_FULL_1024: + + case SW_VESA_1280x1024: case SW_VESA_CG1280x1024: + case SW_VESA_32K_1280: case SW_VESA_64K_1280: + case SW_VESA_FULL_1280: + adp = get_adapter(scp); + if (!(adp->va_flags & V_ADP_MODECHANGE)) + return ENODEV; + mode = (cmd & 0xff) + M_VESA_BASE; +vesa_graphics: + return sc_set_graphics_mode(scp, tp, mode); + } + + if (prev_user_ioctl) + return (*prev_user_ioctl)(dev, cmd, data, flag, p); + else + return ENOIOCTL; +} + +int +vesa_load_ioctl(void) +{ + if (prev_user_ioctl) + return EBUSY; + prev_user_ioctl = sc_user_ioctl; + sc_user_ioctl = vesa_ioctl; + return 0; +} + +int +vesa_unload_ioctl(void) +{ + if (sc_user_ioctl != vesa_ioctl) + return EBUSY; + sc_user_ioctl = prev_user_ioctl; + prev_user_ioctl = NULL; + return 0; +} + +#endif /* (NSC > 0 && VESA && VM86) || VESA_MODULE */ diff --git a/sys/i386/isa/scvidctl.c b/sys/i386/isa/scvidctl.c new file mode 100644 index 000000000000..464933edb112 --- /dev/null +++ b/sys/i386/isa/scvidctl.c @@ -0,0 +1,486 @@ +/*- + * Copyright (c) 1998 Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#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 u_short *Crtat; +extern int fonts_loaded; +extern int sc_history_size; +extern u_char palette[]; + +int +sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, int xsize, int ysize, + int fontsize) +{ + video_adapter_t *adp; + video_info_t info; + int error; + int s; + int i; + + if ((*biosvidsw.get_info)(scp->adp, mode, &info)) + return ENODEV; + adp = get_adapter(scp); + + /* adjust argument values */ + if (fontsize <= 0) + fontsize = info.vi_cheight; + if (fontsize < 14) { + fontsize = 8; + if (!(fonts_loaded & FONT_8)) + return EINVAL; + } else if (fontsize >= 16) { + fontsize = 16; + if (!(fonts_loaded & FONT_16)) + return EINVAL; + } else { + fontsize = 14; + if (!(fonts_loaded & FONT_14)) + return EINVAL; + } + if ((xsize <= 0) || (xsize > info.vi_width)) + xsize = info.vi_width; + if ((ysize <= 0) || (ysize > info.vi_height)) + ysize = info.vi_height; + + /* stop screen saver, etc */ + s = spltty(); + if ((error = sc_clean_up(scp))) { + splx(s); + return error; + } + + /* set up scp */ + if (scp->history != NULL) + i = imax(scp->history_size / scp->xsize + - imax(sc_history_size, scp->ysize), 0); + else + i = 0; + /* + * This is a kludge to fend off scrn_update() while we + * muck around with scp. XXX + */ + scp->status |= UNKNOWN_MODE; + scp->status &= ~(GRAPHICS_MODE | PIXEL_MODE); + scp->mode = mode; + scp->font_size = fontsize; + scp->xsize = xsize; + scp->ysize = ysize; + scp->xpixel = scp->xsize*8; + scp->ypixel = scp->ysize*fontsize; + + /* allocate buffers */ + sc_alloc_scr_buffer(scp, TRUE, TRUE); + if (ISMOUSEAVAIL(adp->va_flags)) + sc_alloc_cut_buffer(scp, FALSE); + sc_alloc_history_buffer(scp, sc_history_size, i, FALSE); + splx(s); + + if (scp == cur_console) + set_mode(scp); + scp->status &= ~UNKNOWN_MODE; + + if (tp == NULL) + return 0; + if (tp->t_winsize.ws_col != scp->xsize + || tp->t_winsize.ws_row != scp->ysize) { + tp->t_winsize.ws_col = scp->xsize; + tp->t_winsize.ws_row = scp->ysize; + pgsignal(tp->t_pgrp, SIGWINCH, 1); + } + + return 0; +} + +int +sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode) +{ + video_adapter_t *adp; + video_info_t info; + int error; + int s; + + if ((*biosvidsw.get_info)(scp->adp, mode, &info)) + return ENODEV; + adp = get_adapter(scp); + + /* stop screen saver, etc */ + s = spltty(); + if ((error = sc_clean_up(scp))) { + splx(s); + return error; + } + + /* set up scp */ + scp->status |= (UNKNOWN_MODE | GRAPHICS_MODE); + scp->status &= ~PIXEL_MODE; + scp->mode = mode; + scp->xpixel = info.vi_width; + scp->ypixel = info.vi_height; + scp->xsize = info.vi_width/8; + scp->ysize = info.vi_height/info.vi_cheight; + scp->font_size = FONT_NONE; + /* move the mouse cursor at the center of the screen */ + sc_move_mouse(scp, scp->xpixel / 2, scp->ypixel / 2); + splx(s); + + if (scp == cur_console) + set_mode(scp); + /* clear_graphics();*/ + scp->status &= ~UNKNOWN_MODE; + + if (tp == NULL) + return 0; + if (tp->t_winsize.ws_xpixel != scp->xpixel + || tp->t_winsize.ws_ypixel != scp->ypixel) { + tp->t_winsize.ws_xpixel = scp->xpixel; + tp->t_winsize.ws_ypixel = scp->ypixel; + pgsignal(tp->t_pgrp, SIGWINCH, 1); + } + + return 0; +} + +int +sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize, + int fontsize) +{ + video_adapter_t *adp; + video_info_t info; + int error; + int s; + int i; + + if ((*biosvidsw.get_info)(scp->adp, scp->mode, &info)) + return ENODEV; /* this shouldn't happen */ + adp = get_adapter(scp); + +#ifdef SC_VIDEO_DEBUG + if (scp->scr_buf != NULL) { + printf("set_pixel_mode(): mode:%x, col:%d, row:%d, font:%d\n", + scp->mode, xsize, ysize, fontsize); + } +#endif + + /* adjust argument values */ + if ((fontsize <= 0) || (fontsize == FONT_NONE)) + fontsize = info.vi_cheight; + if (fontsize < 14) { + fontsize = 8; + if (!(fonts_loaded & FONT_8)) + return EINVAL; + } else if (fontsize >= 16) { + fontsize = 16; + if (!(fonts_loaded & FONT_16)) + return EINVAL; + } else { + fontsize = 14; + if (!(fonts_loaded & FONT_14)) + return EINVAL; + } + if (xsize <= 0) + xsize = info.vi_width/8; + if (ysize <= 0) + ysize = info.vi_height/fontsize; + +#ifdef SC_VIDEO_DEBUG + if (scp->scr_buf != NULL) { + printf("set_pixel_mode(): mode:%x, col:%d, row:%d, font:%d\n", + scp->mode, xsize, ysize, fontsize); + printf("set_pixel_mode(): Crtat:%x, %dx%d, xoff:%d, yoff:%d\n", + Crtat, info.vi_width, info.vi_height, + (info.vi_width/8 - xsize)/2, + (info.vi_height/fontsize - ysize)/2); + } +#endif + + /* stop screen saver, etc */ + s = spltty(); + if ((error = sc_clean_up(scp))) { + splx(s); + return error; + } + + /* set up scp */ + if (scp->history != NULL) + i = imax(scp->history_size / scp->xsize + - imax(sc_history_size, scp->ysize), 0); + else + i = 0; + scp->status |= (UNKNOWN_MODE | PIXEL_MODE); + scp->status &= ~(GRAPHICS_MODE | MOUSE_ENABLED); + scp->xsize = xsize; + scp->ysize = ysize; + scp->font_size = fontsize; + scp->xoff = (scp->xpixel/8 - xsize)/2; + scp->yoff = (scp->ypixel/fontsize - ysize)/2; + + /* allocate buffers */ + sc_alloc_scr_buffer(scp, TRUE, TRUE); + if (ISMOUSEAVAIL(adp->va_flags)) + sc_alloc_cut_buffer(scp, FALSE); + sc_alloc_history_buffer(scp, sc_history_size, i, FALSE); + splx(s); + + /* FIXME */ + if (scp == cur_console) + bzero(Crtat, scp->xpixel*scp->ypixel/8); + + scp->status &= ~UNKNOWN_MODE; + +#ifdef SC_VIDEO_DEBUG + printf("set_pixel_mode(): status:%x\n", scp->status); +#endif + + if (tp == NULL) + return 0; + if (tp->t_winsize.ws_col != scp->xsize + || tp->t_winsize.ws_row != scp->ysize) { + tp->t_winsize.ws_col = scp->xsize; + tp->t_winsize.ws_row = scp->ysize; + pgsignal(tp->t_pgrp, SIGWINCH, 1); + } + + return 0; +} + +int +sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p) +{ + scr_stat *scp; + video_adapter_t *adp; + int error; + int s; + + scp = sc_get_scr_stat(tp->t_dev); + + switch (cmd) { + + case CONS_CURRENT: /* get current adapter type */ + adp = get_adapter(scp); + *(int *)data = adp->va_type; + return 0; + + case CONS_CURRENTADP: /* get current adapter index */ + *(int *)data = scp->adp; + return 0; + + case CONS_ADPINFO: /* adapter information */ + adp = (*biosvidsw.adapter)(((video_adapter_t *)data)->va_index); + if (adp == NULL) + return ENODEV; + bcopy(adp, data, sizeof(*adp)); + return 0; + + case CONS_GET: /* get current video mode */ + *(int *)data = scp->mode; + return 0; + + case CONS_MODEINFO: /* get mode information */ + return ((*biosvidsw.get_info)(scp->adp, + ((video_info_t *)data)->vi_mode, (video_info_t *)data) + ? ENODEV : 0); + + case CONS_FINDMODE: /* find a matching video mode */ + return ((*biosvidsw.query_mode)(scp->adp, (video_info_t *)data) + ? ENODEV : 0); + + case CONS_SETWINORG: + return ((*biosvidsw.set_win_org)(scp->adp, *(u_int *)data) + ? ENODEV : 0); + + /* VGA TEXT MODES */ + case SW_VGA_C40x25: + case SW_VGA_C80x25: case SW_VGA_M80x25: + case SW_VGA_C80x30: case SW_VGA_M80x30: + case SW_VGA_C80x50: case SW_VGA_M80x50: + case SW_VGA_C80x60: case SW_VGA_M80x60: + case SW_B40x25: case SW_C40x25: + case SW_B80x25: case SW_C80x25: + case SW_ENH_B40x25: case SW_ENH_C40x25: + case SW_ENH_B80x25: case SW_ENH_C80x25: + case SW_ENH_B80x43: case SW_ENH_C80x43: + case SW_EGAMONO80x25: + adp = get_adapter(scp); + if (!(adp->va_flags & V_ADP_MODECHANGE)) + return ENODEV; + return sc_set_text_mode(scp, tp, cmd & 0xff, 0, 0, 0); + + /* GRAPHICS MODES */ + case SW_BG320: case SW_BG640: + case SW_CG320: case SW_CG320_D: case SW_CG640_E: + case SW_CG640x350: case SW_ENH_CG640: + case SW_BG640x480: case SW_CG640x480: case SW_VGA_CG320: + case SW_VGA_MODEX: + adp = get_adapter(scp); + if (!(adp->va_flags & V_ADP_MODECHANGE)) + return ENODEV; + return sc_set_graphics_mode(scp, tp, cmd & 0xff); + + case KDSETMODE: /* set current mode of this (virtual) console */ + switch (*data) { + case KD_TEXT: /* switch to TEXT (known) mode */ + /* + * If scp->mode is of graphics modes, we don't know which + * text mode to switch back to... + */ + if (scp->status & GRAPHICS_MODE) + return EINVAL; + /* restore fonts & palette ! */ +#if 0 + adp = get_adapter(scp); + if (ISFONTAVAIL(adp->va_flags) + && !(scp->status & (GRAPHICS_MODE | PIXEL_MODE))) + /* + * FONT KLUDGE + * Don't load fonts for now... XXX + */ + if (fonts_loaded & FONT_8) + copy_font(scp, LOAD, 8, font_8); + if (fonts_loaded & FONT_14) + copy_font(scp, LOAD, 14, font_14); + if (fonts_loaded & FONT_16) + copy_font(scp, LOAD, 16, font_16); + } +#endif + load_palette(scp, palette); + + /* move hardware cursor out of the way */ + (*biosvidsw.set_hw_cursor)(scp->adp, -1, -1); + + /* FALL THROUGH */ + + case KD_TEXT1: /* switch to TEXT (known) mode */ + /* + * If scp->mode is of graphics modes, we don't know which + * text/pixel mode to switch back to... + */ + if (scp->status & GRAPHICS_MODE) + return EINVAL; + s = spltty(); + if ((error = sc_clean_up(scp))) { + splx(s); + return error; + } + scp->status |= UNKNOWN_MODE; + splx(s); + /* no restore fonts & palette */ + if (scp == cur_console) { + set_mode(scp); + /* FIXME */ + if (scp->status & PIXEL_MODE) + bzero(Crtat, scp->xpixel*scp->ypixel/8); + } + sc_clear_screen(scp); + scp->status &= ~UNKNOWN_MODE; + return 0; + + case KD_PIXEL: /* pixel (raster) display */ + if (!(scp->status & (GRAPHICS_MODE | PIXEL_MODE))) + return EINVAL; + if (!(scp->status & PIXEL_MODE)) + return sc_set_pixel_mode(scp, tp, scp->xsize, scp->ysize, + scp->font_size); + s = spltty(); + if ((error = sc_clean_up(scp))) { + splx(s); + return error; + } + scp->status |= (UNKNOWN_MODE | PIXEL_MODE); + splx(s); + if (scp == cur_console) { + set_mode(scp); + load_palette(scp, palette); + /* FIXME */ + bzero(Crtat, scp->xpixel*scp->ypixel/8); + } + sc_clear_screen(scp); + scp->status &= ~UNKNOWN_MODE; + return 0; + + case KD_GRAPHICS: /* switch to GRAPHICS (unknown) mode */ + s = spltty(); + if ((error = sc_clean_up(scp))) { + splx(s); + return error; + } + scp->status |= UNKNOWN_MODE; + splx(s); + return 0; + + default: + return EINVAL; + } + /* NOT REACHED */ + + case KDRASTER: /* set pixel (raster) display mode */ + if (ISUNKNOWNSC(scp) || ISTEXTSC(scp)) + return ENODEV; + return sc_set_pixel_mode(scp, tp, ((int *)data)[0], ((int *)data)[1], + ((int *)data)[2]); + + case KDGETMODE: /* get current mode of this (virtual) console */ + /* + * From the user program's point of view, KD_PIXEL is the same + * as KD_TEXT... + */ + *data = ISGRAPHSC(scp) ? KD_GRAPHICS : KD_TEXT; + return 0; + + case KDSBORDER: /* set border color of this (virtual) console */ + scp->border = *data; + if (scp == cur_console) + set_border(cur_console, scp->border); + return 0; + } + + return ENOIOCTL; +} + +#endif /* NSC > 0 */ diff --git a/sys/i386/isa/syscons.c b/sys/i386/isa/syscons.c index ebc243f52ba7..50e0f199c0fb 100644 --- a/sys/i386/isa/syscons.c +++ b/sys/i386/isa/syscons.c @@ -1,18 +1,18 @@ /*- - * Copyright (c) 1992-1997 Søren Schmidt + * Copyright (c) 1992-1998 Søren Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. + * notice, this list of conditions and the following disclaimer, + * without modification, immediately at the beginning of the file. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products - * derived from this software withough specific prior written permission + * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES @@ -25,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.276 1998/08/23 08:26:41 bde Exp $ + * $Id$ */ #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 @@ -70,6 +72,7 @@ #include #include #include +#include #include #if !defined(MAXCONS) @@ -96,11 +99,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!? */ @@ -159,6 +157,7 @@ static int blinkrate = 0; u_int crtc_addr = MONO_BASE; char crtc_type = KD_MONO; char crtc_vga = FALSE; +static int adp_flags = 0; static u_char shfts = 0, ctls = 0, alts = 0, agrs = 0, metas = 0; static u_char accents = 0; static u_char nlkcnt = 0, clkcnt = 0, slkcnt = 0, alkcnt = 0; @@ -172,7 +171,7 @@ static int run_scrn_saver = FALSE; /* should run the saver? */ static int scrn_idle = FALSE; /* about to run the saver */ u_char scr_map[256]; u_char scr_rmap[256]; - char *video_mode_ptr = NULL; +static int initial_video_mode; /* initial video mode # */ static int bios_video_mode; /* video mode # set by BIOS */ int fonts_loaded = 0 #ifdef STD8X16FONT @@ -180,19 +179,15 @@ static int bios_video_mode; /* video mode # set by BIOS */ #endif ; - char font_8[256*8]; - char font_14[256*14]; + u_char font_8[256*8]; + u_char font_14[256*14]; #ifdef STD8X16FONT extern #endif - unsigned char font_16[256*16]; - char palette[256*3]; -static char *mode_map[MODE_MAP_SIZE]; -static char vgaregs[MODE_PARAM_SIZE]; -static char vgaregs2[MODE_PARAM_SIZE]; -static int rows_offset = 1; -static char *cut_buffer; -static int cut_buffer_size; + u_char font_16[256*16]; + u_char palette[256*3]; +static u_char *cut_buffer = NULL; +static int cut_buffer_size = 0; static int mouse_level = 0; /* sysmouse protocol level */ static mousestatus_t mouse_status = { 0, 0, 0, 0, 0, 0 }; static u_short mouse_and_mask[16] = { @@ -208,13 +203,14 @@ static u_short mouse_or_mask[16] = { 0x0000, 0x0000, 0x0000, 0x0000 }; -static int extra_history_size = + int sc_history_size = SC_HISTORY_SIZE; +static int extra_history_size = SC_MAX_HISTORY_SIZE - SC_HISTORY_SIZE * MAXCONS; static void none_saver(int blank) { } static void (*current_saver)(int blank) = none_saver; static void (*default_saver)(int blank) = none_saver; -int (*sc_user_ioctl)(dev_t dev, int cmd, caddr_t data, + int (*sc_user_ioctl)(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) = NULL; static int sticky_splash = FALSE; @@ -233,8 +229,6 @@ static struct tty sccons[MAXCONS+2]; #endif #define SC_MOUSE 128 #define SC_CONSOLE 255 -#define MONO_BUF pa_to_va(0xB0000) -#define CGA_BUF pa_to_va(0xB8000) u_short *Crtat; static const int nsccons = MAXCONS+2; @@ -243,9 +237,6 @@ static const int nsccons = MAXCONS+2; + (offset)) % (scp->history_size))) #define ISSIGVALID(sig) ((sig) > 0 && (sig) < NSIG) -/* this should really be in `rtc.h' */ -#define RTC_EQUIPMENT 0x14 - /* prototypes */ static int scattach(struct isa_device *dev); static int scparam(struct tty *tp, struct termios *t); @@ -256,30 +247,26 @@ static void scstart(struct tty *tp); static void scmousestart(struct tty *tp); static void scinit(void); static void scshutdown(int howto, void *arg); -static void map_mode_table(char *map[], char *table, int max); -static int map_mode_num(int mode); -static char *get_mode_param(scr_stat *scp, int mode); static u_int scgetc(u_int flags); #define SCGETC_CN 1 #define SCGETC_NONBLOCK 2 static void sccnupdate(scr_stat *scp); -static scr_stat *get_scr_stat(dev_t dev); static scr_stat *alloc_scp(void); static void init_scp(scr_stat *scp); static void sc_bcopy(scr_stat *scp, u_short *p, int from, int to, int mark); static int get_scr_num(void); static timeout_t scrn_timer; static void scrn_update(scr_stat *scp, int show_cursor); +static void scrn_saver(void (*saver)(int), int blank); static void stop_scrn_saver(void (*saver)(int)); static int wait_scrn_saver_stop(void); -static void clear_screen(scr_stat *scp); static int switch_scr(scr_stat *scp, u_int next_scr); static void exchange_scr(void); -static void move_crsr(scr_stat *scp, int x, int y); static void scan_esc(scr_stat *scp, u_char c); +static void ansi_put(scr_stat *scp, u_char *buf, int len); static void draw_cursor_image(scr_stat *scp); static void remove_cursor_image(scr_stat *scp); -static void ansi_put(scr_stat *scp, u_char *buf, int len); +static void move_crsr(scr_stat *scp, int x, int y); static u_char *get_fstr(u_int c, u_int *len); static void history_to_screen(scr_stat *scp); static int history_up_line(scr_stat *scp); @@ -287,16 +274,6 @@ static int history_down_line(scr_stat *scp); static int mask2attr(struct term_stat *term); static void set_keyboard(int command, int data); static void update_leds(int which); -static void set_vgaregs(char *modetable); -static void read_vgaregs(char *buf); -#define COMP_IDENTICAL 0 -#define COMP_SIMILAR 1 -#define COMP_DIFFERENT 2 -static int comp_vgaregs(u_char *buf1, u_char *buf2); -static void dump_vgaregs(u_char *buf); -#define PARAM_BUFSIZE 6 -static void set_font_mode(u_char *buf); -static void set_normal_mode(u_char *buf); static void set_destructive_cursor(scr_stat *scp); static void set_mouse_pos(scr_stat *scp); static int skip_spc_right(scr_stat *scp, u_short *p); @@ -312,12 +289,11 @@ static void draw_mouse_image(scr_stat *scp); static void remove_mouse_image(scr_stat *scp); static void draw_cutmarking(scr_stat *scp); static void remove_cutmarking(scr_stat *scp); -static void save_palette(void); static void do_bell(scr_stat *scp, int pitch, int duration); static timeout_t blink_screen; #ifdef SC_SPLASH_SCREEN -static void scsplash_init(void); -static void scsplash(int show); +static void scsplash_init(scr_stat *scp); +static void scsplash_saver(int show); #define scsplash_stick(stick) (sticky_splash = (stick)) #else #define scsplash_stick(stick) @@ -332,7 +308,7 @@ static d_close_t scclose; static d_read_t scread; static d_write_t scwrite; static d_ioctl_t scioctl; -static d_devtotty_t scdevtotty; + d_devtotty_t scdevtotty; static d_mmap_t scmmap; #define CDEV_MAJOR 12 @@ -353,7 +329,7 @@ draw_cursor_image(scr_stat *scp) u_short cursor_image, *ptr = Crtat + (scp->cursor_pos - scp->scr_buf); u_short prev_image; - if (VESA_MODE(scp->mode)) { + if (ISPIXELSC(scp)) { sc_bcopy(scp, scp->scr_buf, scp->cursor_pos - scp->scr_buf, scp->cursor_pos - scp->scr_buf, 1); return; @@ -405,7 +381,7 @@ draw_cursor_image(scr_stat *scp) static void remove_cursor_image(scr_stat *scp) { - if (VESA_MODE(scp->mode)) + if (ISPIXELSC(scp)) sc_bcopy(scp, scp->scr_buf, scp->cursor_oldpos - scp->scr_buf, scp->cursor_oldpos - scp->scr_buf, 0); else @@ -436,6 +412,12 @@ scprobe(struct isa_device *dev) printf("sc%d: no video adapter is found.\n", dev->id_unit); return (0); } + (*biosvidsw.diag)(bootverbose); +#if defined(VESA) && defined(VM86) + if (vesa_load()) + return FALSE; + (*biosvidsw.diag)(bootverbose); +#endif sc_port = dev->id_iobase; if (sckbdprobe(dev->id_unit, dev->id_flags)) @@ -448,99 +430,24 @@ 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; + video_adapter_t *adp; /* 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. - */ - 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 ((*biosvidsw.init)() <= 0) + return FALSE; + if ((adp = (*biosvidsw.adapter)(V_ADP_PRIMARY)) == NULL) + return FALSE; - 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; - } - - /* 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); - } - } - } + 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; return TRUE; } @@ -728,48 +635,42 @@ static int scattach(struct isa_device *dev) { scr_stat *scp; + video_info_t info; dev_t cdev = makedev(CDEV_MAJOR, 0); - char *p; #ifdef DEVFS int vc; #endif scinit(); flags = dev->id_flags; - if (crtc_type != KD_VGA || VESA_MODE(bios_video_mode)) + if (!ISFONTAVAIL(adp_flags)) flags &= ~CHAR_CURSOR; scp = console[0]; - if (crtc_type == KD_VGA) { - cut_buffer_size = scp->xsize * scp->ysize + 1; - cut_buffer = (char *)malloc(cut_buffer_size, M_DEVBUF, M_NOWAIT); - if (cut_buffer != NULL) - cut_buffer[0] = '\0'; - } - - scp->scr_buf = (u_short *)malloc(scp->xsize*scp->ysize*sizeof(u_short), - M_DEVBUF, M_NOWAIT); - /* copy temporary buffer to final buffer */ - bcopy(sc_buffer, scp->scr_buf, scp->xsize * scp->ysize * sizeof(u_short)); + scp->scr_buf = NULL; + sc_alloc_scr_buffer(scp, FALSE, FALSE); + bcopy(sc_buffer, scp->scr_buf, scp->xsize*scp->ysize*sizeof(u_short)); - scp->cursor_pos = scp->cursor_oldpos = - scp->scr_buf + scp->xpos + scp->ypos * scp->xsize; - scp->mouse_pos = scp->mouse_oldpos = - scp->scr_buf + ((scp->mouse_ypos/scp->font_size)*scp->xsize + - scp->mouse_xpos/8); + /* cut buffer is available only when the mouse pointer is used */ + if (ISMOUSEAVAIL(adp_flags)) + sc_alloc_cut_buffer(scp, FALSE); /* initialize history buffer & pointers */ - scp->history_head = scp->history_pos = - (u_short *)malloc(scp->history_size*sizeof(u_short), - M_DEVBUF, M_NOWAIT); - if (scp->history_head != NULL) - bzero(scp->history_head, scp->history_size*sizeof(u_short)); - scp->history = scp->history_head; + sc_alloc_history_buffer(scp, sc_history_size, 0, FALSE); + +#if defined(VESA) && defined(VM86) + if ((flags & VESA800X600) + && ((*biosvidsw.get_info)(scp->adp, M_VESA_800x600, &info) == 0)) { + sc_set_graphics_mode(scp, NULL, M_VESA_800x600); + sc_set_pixel_mode(scp, NULL, COL, ROW, 16); + initial_video_mode = M_VESA_800x600; + } +#endif /* VESA && VM86 */ /* initialize cursor stuff */ - if (!(scp->status & UNKNOWN_MODE)) + if (!ISGRAPHSC(scp)) draw_cursor_image(scp); /* get screen update going */ @@ -777,42 +678,13 @@ scattach(struct isa_device *dev) update_leds(scp->status); - 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); - printf("sc%d: ", dev->id_unit); switch(crtc_type) { case KD_VGA: - if (VESA_MODE(bios_video_mode)) - printf("Graphics display (VESA mode = 0x%x)", bios_video_mode); - else if (crtc_addr == MONO_BASE) - printf("VGA mono"); - else - printf("VGA color"); + printf("VGA %s", (adp_flags & V_ADP_COLOR) ? "color" : "mono"); break; case KD_EGA: - if (crtc_addr == MONO_BASE) - printf("EGA mono"); - else - printf("EGA color"); + printf("EGA %s", (adp_flags & V_ADP_COLOR) ? "color" : "mono"); break; case KD_CGA: printf("CGA"); @@ -820,7 +692,7 @@ scattach(struct isa_device *dev) case KD_MONO: case KD_HERCULES: default: - printf("MDA/hercules"); + printf("MDA/Hercules"); break; } printf(" <%d virtual consoles, flags=0x%x>\n", MAXCONS, flags); @@ -896,6 +768,8 @@ scopen(dev_t dev, int flag, int mode, struct proc *p) return(EBUSY); if (minor(dev) < MAXCONS && !console[minor(dev)]) { console[minor(dev)] = alloc_scp(); + if (ISGRAPHSC(console[minor(dev)])) + sc_set_pixel_mode(console[minor(dev)], NULL, COL, ROW, 16); } if (minor(dev)t_winsize.ws_col && !tp->t_winsize.ws_row) { tp->t_winsize.ws_col = console[minor(dev)]->xsize; @@ -913,7 +787,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 @@ -927,9 +801,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; @@ -1008,10 +882,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 @@ -1030,21 +911,25 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) u_int i; struct tty *tp; scr_stat *scp; - u_short *usp; - char *mp; + video_adapter_t *adp; int s; tp = scdevtotty(dev); if (!tp) return ENXIO; - scp = get_scr_stat(tp->t_dev); + scp = sc_get_scr_stat(tp->t_dev); /* If there is a user_ioctl function call that first */ if (sc_user_ioctl) { - if (error = (*sc_user_ioctl)(dev, cmd, data, flag, p)) + error = (*sc_user_ioctl)(dev, cmd, data, flag, p); + if (error != ENOIOCTL) return error; } + error = sc_vid_ioctl(tp, cmd, data, flag, p); + if (error != ENOIOCTL) + return error; + switch (cmd) { /* process console hardware related ioctl's */ case GIO_ATTR: /* get current attributes */ @@ -1052,18 +937,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) return 0; case GIO_COLOR: /* is this a color console ? */ - if (crtc_addr == COLOR_BASE) - *(int*)data = 1; - else - *(int*)data = 0; - return 0; - - case CONS_CURRENT: /* get current adapter type */ - *(int *)data = crtc_type; - return 0; - - case CONS_GET: /* get current video mode */ - *(int*)data = scp->mode; + *(int *)data = (adp_flags & V_ADP_COLOR) ? 1 : 0; return 0; case CONS_BLANKTIME: /* set screen saver timeout (0 = no saver) */ @@ -1081,7 +955,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) else flags &= ~BLINK_CURSOR; if ((*(int*)data) & 0x02) { - if (crtc_type != KD_VGA || VESA_MODE(bios_video_mode)) + if (!ISFONTAVAIL(get_adapter(scp)->va_flags)) return ENXIO; flags |= CHAR_CURSOR; } else @@ -1090,7 +964,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) * The cursor shape is global property; all virtual consoles * are affected. Update the cursor in the current console... */ - if (!(cur_console->status & UNKNOWN_MODE)) { + if (!ISGRAPHSC(cur_console)) { remove_cursor_image(cur_console); if (flags & CHAR_CURSOR) set_destructive_cursor(cur_console); @@ -1117,37 +991,22 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) lines = imax(*(int *)data, scp->ysize); lines0 = (scp->history != NULL) ? scp->history_size / scp->xsize : scp->ysize; + if (lines0 > imax(sc_history_size, scp->ysize)) + i = lines0 - imax(sc_history_size, scp->ysize); + else + i = 0; /* * syscons unconditionally allocates buffers upto SC_HISTORY_SIZE * lines or scp->ysize lines, whichever is larger. A value * greater than that is allowed, subject to extra_history_size. */ - if (lines > imax(lines0, SC_HISTORY_SIZE) + extra_history_size) - return EINVAL; + if (lines > imax(sc_history_size, scp->ysize)) + if (lines - imax(sc_history_size, scp->ysize) > + extra_history_size + i) + return EINVAL; if (cur_console->status & BUFFER_SAVED) return EBUSY; - usp = scp->history; - scp->history = NULL; - if (usp != NULL) - free(usp, M_DEVBUF); - scp->history_size = lines * scp->xsize; - /* - * extra_history_size += - * (lines0 > imax(SC_HISTORY_SIZE, scp->ysize)) ? - * lines0 - imax(SC_HISTORY_SIZE, scp->ysize)) : 0; - * extra_history_size -= - * (lines > imax(SC_HISTORY_SIZE, scp->ysize)) ? - * lines - imax(SC_HISTORY_SIZE, scp->ysize)) : 0; - * lines0 >= ysize && lines >= ysize... Hey, the above can be - * reduced to the following... - */ - extra_history_size += - imax(lines0, SC_HISTORY_SIZE) - imax(lines, SC_HISTORY_SIZE); - usp = (u_short *)malloc(scp->history_size * sizeof(u_short), - M_DEVBUF, M_WAITOK); - bzero(usp, scp->history_size * sizeof(u_short)); - scp->history_head = scp->history_pos = usp; - scp->history = usp; + sc_alloc_history_buffer(scp, lines, i, TRUE); return 0; } else @@ -1171,7 +1030,8 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) mouse_info_t *mouse = (mouse_info_t*)data; mouse_info_t buf; - if (crtc_type != KD_VGA || VESA_MODE(bios_video_mode)) + /* FIXME: */ + if (!ISMOUSEAVAIL(get_adapter(scp)->va_flags)) return ENODEV; if (cmd == OLD_CONS_MOUSECTL) { @@ -1220,7 +1080,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); @@ -1231,7 +1091,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; @@ -1276,7 +1136,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) { @@ -1321,7 +1181,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); @@ -1358,7 +1218,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) { @@ -1387,7 +1247,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) { @@ -1567,18 +1427,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; @@ -1597,226 +1480,6 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) splx(s); return 0; - /* VGA TEXT MODES */ - case SW_VGA_C40x25: - case SW_VGA_C80x25: case SW_VGA_M80x25: - case SW_VGA_C80x30: case SW_VGA_M80x30: - case SW_VGA_C80x50: case SW_VGA_M80x50: - case SW_VGA_C80x60: case SW_VGA_M80x60: - case SW_B40x25: case SW_C40x25: - case SW_B80x25: case SW_C80x25: - case SW_ENH_B40x25: case SW_ENH_C40x25: - case SW_ENH_B80x25: case SW_ENH_C80x25: - case SW_ENH_B80x43: case SW_ENH_C80x43: - case SW_EGAMONO80x25: - - if (crtc_type != KD_VGA) - return ENODEV; - mp = get_mode_param(scp, cmd & 0xff); - if (mp == NULL) - return ENODEV; - - s = spltty(); - if ((error = wait_scrn_saver_stop())) { - splx(s); - return error; - } - - scp->status &= ~MOUSE_VISIBLE; - remove_cutmarking(scp); - if (scp->history != NULL) - i = imax(scp->history_size / scp->xsize - - imax(SC_HISTORY_SIZE, scp->ysize), 0); - else - i = 0; - switch (cmd & 0xff) { - case M_VGA_C80x60: case M_VGA_M80x60: - if (!(fonts_loaded & FONT_8)) { - splx(s); - return EINVAL; - } - /* - * This is a kludge to fend off scrn_update() while we - * muck around with scp. XXX - */ - scp->status |= UNKNOWN_MODE; - scp->xsize = 80; - scp->ysize = 60; - scp->font_size = 8; - break; - case M_VGA_C80x50: case M_VGA_M80x50: - if (!(fonts_loaded & FONT_8)) { - splx(s); - return EINVAL; - } - scp->status |= UNKNOWN_MODE; - scp->xsize = 80; - scp->ysize = 50; - scp->font_size = 8; - break; - case M_ENH_B80x43: case M_ENH_C80x43: - if (!(fonts_loaded & FONT_8)) { - splx(s); - return EINVAL; - } - scp->status |= UNKNOWN_MODE; - scp->xsize = 80; - scp->ysize = 43; - scp->font_size = 8; - break; - case M_VGA_C80x30: case M_VGA_M80x30: - scp->status |= UNKNOWN_MODE; - scp->xsize = 80; - scp->ysize = 30; - scp->font_size = mp[2]; - break; - case M_ENH_C40x25: case M_ENH_B40x25: - case M_ENH_C80x25: case M_ENH_B80x25: - case M_EGAMONO80x25: - if (!(fonts_loaded & FONT_14)) { - splx(s); - return EINVAL; - } - /* FALL THROUGH */ - default: - if ((cmd & 0xff) > M_VGA_CG320) { - splx(s); - return EINVAL; - } - scp->status |= UNKNOWN_MODE; - scp->xsize = mp[0]; - scp->ysize = mp[1] + rows_offset; - scp->font_size = mp[2]; - break; - } - - scp->mode = cmd & 0xff; - scp->xpixel = scp->xsize * 8; - scp->ypixel = scp->ysize * scp->font_size; - free(scp->scr_buf, M_DEVBUF); - scp->scr_buf = (u_short *) - malloc(scp->xsize*scp->ysize*sizeof(u_short), M_DEVBUF, M_WAITOK); - /* move the text cursor to the home position */ - move_crsr(scp, 0, 0); - /* move the mouse cursor at the center of the screen */ - scp->mouse_xpos = scp->xpixel / 2; - scp->mouse_ypos = scp->ypixel / 2; - scp->mouse_pos = scp->mouse_oldpos = - scp->scr_buf + (scp->mouse_ypos / scp->font_size) * scp->xsize - + scp->mouse_xpos / 8; - /* allocate a larger cut buffer if necessary */ - if ((cut_buffer == NULL) - || (cut_buffer_size < scp->xsize * scp->ysize + 1)) { - if (cut_buffer != NULL) - free(cut_buffer, M_DEVBUF); - cut_buffer_size = scp->xsize * scp->ysize + 1; - cut_buffer = (char *)malloc(cut_buffer_size, M_DEVBUF, M_NOWAIT); - if (cut_buffer != NULL) - cut_buffer[0] = '\0'; - } - splx(s); - - usp = scp->history; - scp->history = NULL; - if (usp != NULL) { - free(usp, M_DEVBUF); - extra_history_size += i; - } - scp->history_size = imax(SC_HISTORY_SIZE, scp->ysize) * scp->xsize; - usp = (u_short *)malloc(scp->history_size * sizeof(u_short), - M_DEVBUF, M_NOWAIT); - if (usp != NULL) - bzero(usp, scp->history_size * sizeof(u_short)); - scp->history_head = scp->history_pos = usp; - scp->history = usp; - if (scp == cur_console) - set_mode(scp); - clear_screen(scp); - scp->status &= ~UNKNOWN_MODE; - - if (tp->t_winsize.ws_col != scp->xsize - || tp->t_winsize.ws_row != scp->ysize) { - tp->t_winsize.ws_col = scp->xsize; - tp->t_winsize.ws_row = scp->ysize; - pgsignal(tp->t_pgrp, SIGWINCH, 1); - } - return 0; - - /* GRAPHICS MODES */ - case SW_BG320: case SW_BG640: - case SW_CG320: case SW_CG320_D: case SW_CG640_E: - case SW_CG640x350: case SW_ENH_CG640: - case SW_BG640x480: case SW_CG640x480: case SW_VGA_CG320: - - if (crtc_type != KD_VGA) - return ENODEV; - mp = get_mode_param(scp, cmd & 0xff); - if (mp == NULL) - return ENODEV; - - s = spltty(); - if ((error = wait_scrn_saver_stop())) { - splx(s); - return error; - } - - scp->status &= ~MOUSE_VISIBLE; - remove_cutmarking(scp); - scp->status |= UNKNOWN_MODE; /* graphics mode */ - scp->mode = cmd & 0xFF; - scp->xpixel = mp[0] * 8; - scp->ypixel = (mp[1] + rows_offset) * mp[2]; - scp->font_size = FONT_NONE; - /* move the mouse cursor at the center of the screen */ - scp->mouse_xpos = scp->xpixel / 2; - scp->mouse_ypos = scp->ypixel / 2; - splx(s); - - if (scp == cur_console) - set_mode(scp); - /* clear_graphics();*/ - - if (tp->t_winsize.ws_xpixel != scp->xpixel - || tp->t_winsize.ws_ypixel != scp->ypixel) { - tp->t_winsize.ws_xpixel = scp->xpixel; - tp->t_winsize.ws_ypixel = scp->ypixel; - pgsignal(tp->t_pgrp, SIGWINCH, 1); - } - return 0; - - case SW_VGA_MODEX: - if (crtc_type != KD_VGA) - return ENODEV; - mp = get_mode_param(scp, cmd & 0xff); - if (mp == NULL) - return ENODEV; - - s = spltty(); - if ((error = wait_scrn_saver_stop())) { - splx(s); - return error; - } - - scp->status &= ~MOUSE_VISIBLE; - remove_cutmarking(scp); - scp->status |= UNKNOWN_MODE; /* graphics mode */ - scp->mode = cmd & 0xFF; - scp->xpixel = 320; - scp->ypixel = 240; - scp->font_size = FONT_NONE; - splx(s); - - if (scp == cur_console) - set_mode(scp); - /* clear_graphics();*/ - if (tp->t_winsize.ws_xpixel != scp->xpixel - || tp->t_winsize.ws_ypixel != scp->ypixel) { - tp->t_winsize.ws_xpixel = scp->xpixel; - tp->t_winsize.ws_ypixel = scp->ypixel; - pgsignal(tp->t_pgrp, SIGWINCH, 1); - } - return 0; - case VT_SETMODE: /* set screen switcher mode */ { struct vt_mode *mode; @@ -1839,7 +1502,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; @@ -1879,32 +1542,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 */ @@ -1920,102 +1583,28 @@ 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 */ - /* restore fonts & palette ! */ - if (crtc_type == KD_VGA) { - if (!VESA_MODE(scp->mode)) { -#if 0 - /* - * FONT KLUDGE - * Don't load fonts for now... XXX - */ - if (fonts_loaded & FONT_8) - copy_font(LOAD, FONT_8, font_8); - if (fonts_loaded & FONT_14) - copy_font(LOAD, FONT_14, font_14); - if (fonts_loaded & FONT_16) - copy_font(LOAD, FONT_16, font_16); -#endif - } - load_palette(palette); - } - - /* move hardware cursor out of the way */ - outb(crtc_addr, 14); - outb(crtc_addr + 1, 0xff); - outb(crtc_addr, 15); - outb(crtc_addr + 1, 0xff); - - /* FALL THROUGH */ - - case KD_TEXT1: /* switch to TEXT (known) mode */ - s = spltty(); - if ((error = wait_scrn_saver_stop())) { - splx(s); - return error; - } - scp->status &= ~MOUSE_VISIBLE; - remove_cutmarking(scp); - scp->status |= UNKNOWN_MODE; - splx(s); - /* no restore fonts & palette */ - if (crtc_type == KD_VGA) - set_mode(scp); - scp->status &= ~UNKNOWN_MODE; - clear_screen(scp); - return 0; - - case KD_GRAPHICS: /* switch to GRAPHICS (unknown) mode */ - s = spltty(); - if ((error = wait_scrn_saver_stop())) { - splx(s); - return error; - } - scp->status &= ~MOUSE_VISIBLE; - remove_cutmarking(scp); - scp->status |= UNKNOWN_MODE; - splx(s); - return 0; - default: - 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; + 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) */ - *data = scp->status & LOCK_KEY_MASK; + *(int *)data = scp->status & LOCK_KEY_MASK; return 0; case KDSETRAD: /* set keyboard repeat & delay rates */ - if (*data & 0x80) + if (*(int *)data & ~0x7f) return EINVAL; if (sc_kbdc != NULL) - set_keyboard(KBDC_SET_TYPEMATIC, *data); + set_keyboard(KBDC_SET_TYPEMATIC, *(int *)data); return 0; case KDSKBMODE: /* set keyboard mode */ - switch (*data) { + switch (*(int *)data) { case K_RAW: /* switch to RAW scancode mode */ scp->status &= ~KBD_CODE_MODE; scp->status |= KBD_RAW_MODE; @@ -2037,7 +1626,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; @@ -2074,21 +1663,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 */ @@ -2143,7 +1731,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) return 0; case PIO_FONT8x8: /* set 8x8 dot font */ - if (crtc_type != KD_VGA) + if (!ISFONTAVAIL(get_adapter(scp)->va_flags)) return ENXIO; bcopy(data, font_8, 8*256); fonts_loaded |= FONT_8; @@ -2152,17 +1740,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); @@ -2172,7 +1755,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; @@ -2181,17 +1764,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); @@ -2201,7 +1780,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; @@ -2210,17 +1789,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); @@ -2247,7 +1821,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? */ @@ -2329,7 +1903,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); @@ -2384,25 +1958,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); @@ -2461,6 +2038,8 @@ scrn_timer(void *arg) scintr(0); } + scp = cur_console; + /* should we stop the screen saver? */ getmicrouptime(&tv); if (panicstr || shutdown_in_progress) { @@ -2476,7 +2055,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 ? */ @@ -2488,14 +2067,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); @@ -2583,9 +2161,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; } @@ -2612,10 +2190,22 @@ remove_scrn_saver(void (*this_saver)(int)) return 0; } +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) @@ -2632,8 +2222,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) @@ -2642,8 +2232,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; @@ -2668,8 +2258,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; } @@ -2721,25 +2310,26 @@ exchange_scr(void) { move_crsr(old_scp, old_scp->xpos, old_scp->ypos); cur_console = new_scp; - if (old_scp->mode != new_scp->mode || (old_scp->status & UNKNOWN_MODE)){ - if (crtc_type == KD_VGA) + if (old_scp->mode != new_scp->mode || ISUNKNOWNSC(old_scp)) { + if (adp_flags & V_ADP_MODECHANGE) set_mode(new_scp); } move_crsr(new_scp, new_scp->xpos, new_scp->ypos); - if (!(new_scp->status & UNKNOWN_MODE) && (flags & CHAR_CURSOR)) + if (ISTEXTSC(new_scp) && (flags & CHAR_CURSOR)) set_destructive_cursor(new_scp); - if ((old_scp->status & UNKNOWN_MODE) && crtc_type == KD_VGA) - load_palette(palette); + if (ISGRAPHSC(old_scp)) + load_palette(new_scp, palette); if (old_scp->status & KBD_RAW_MODE || new_scp->status & KBD_RAW_MODE || old_scp->status & KBD_CODE_MODE || new_scp->status & KBD_CODE_MODE) shfts = ctls = alts = agrs = metas = accents = 0; - set_border(new_scp->border); + set_border(new_scp, new_scp->border); update_leds(new_scp->status); delayed_next_scr = FALSE; mark_all(new_scp); - if (new_scp->mode == 0x102) { - bzero(Crtat, 800*600/8); - } + + /* FIXME: the screen size may be larger than a 64K segment. */ + if (ISPIXELSC(new_scp)) + bzero(Crtat, new_scp->xpixel*new_scp->ypixel/8); } static void @@ -2788,7 +2378,7 @@ scan_esc(scr_stat *scp, u_char c) return; #endif case 'c': /* Clear screen & home */ - clear_screen(scp); + sc_clear_screen(scp); break; case '(': /* iso-2022: designate 94 character set to G0 */ @@ -2874,7 +2464,7 @@ scan_esc(scr_stat *scp, u_char c) scp->cursor_pos, scp->scr_buf + scp->xsize * scp->ysize - scp->cursor_pos); mark_for_update(scp, scp->cursor_pos - scp->scr_buf); - mark_for_update(scp, scp->xsize * scp->ysize); + mark_for_update(scp, scp->xsize * scp->ysize - 1); remove_cutmarking(scp); break; case 1: /* clear from beginning of display to cursor */ @@ -2936,7 +2526,7 @@ scan_esc(scr_stat *scp, u_char c) fillw(scp->term.cur_color | scr_map[0x20], src, n * scp->xsize); mark_for_update(scp, scp->ypos * scp->xsize); - mark_for_update(scp, scp->xsize * scp->ysize); + mark_for_update(scp, scp->xsize * scp->ysize - 1); break; case 'M': /* Delete n lines */ @@ -2951,7 +2541,7 @@ scan_esc(scr_stat *scp, u_char c) fillw(scp->term.cur_color | scr_map[0x20], src, n * scp->xsize); mark_for_update(scp, scp->ypos * scp->xsize); - mark_for_update(scp, scp->xsize * scp->ysize); + mark_for_update(scp, scp->xsize * scp->ysize - 1); break; case 'P': /* Delete n chars */ @@ -3192,7 +2782,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; @@ -3209,8 +2799,8 @@ scan_esc(scr_stat *scp, u_char c) flags |= BLINK_CURSOR; else flags &= ~BLINK_CURSOR; - if ((scp->term.param[0] & 0x02) && - crtc_type == KD_VGA && !VESA_MODE(bios_video_mode)) + if ((scp->term.param[0] & 0x02) + && ISFONTAVAIL(get_adapter(scp)->va_flags)) flags |= CHAR_CURSOR; else flags &= ~CHAR_CURSOR; @@ -3223,9 +2813,9 @@ scan_esc(scr_stat *scp, u_char c) * The cursor shape is global property; all virtual consoles * are affected. Update the cursor in the current console... */ - if (!(cur_console->status & UNKNOWN_MODE)) { + if (!ISGRAPHSC(cur_console)) { remove_cursor_image(cur_console); - if (crtc_type == KD_VGA && (flags & CHAR_CURSOR)) + if (flags & CHAR_CURSOR) set_destructive_cursor(cur_console); draw_cursor_image(cur_console); } @@ -3366,7 +2956,7 @@ ansi_put(scr_stat *scp, u_char *buf, int len) break; case 0x0c: /* form feed, clears screen */ - clear_screen(scp); + sc_clear_screen(scp); break; case 0x0d: /* return, return to pos 0 */ @@ -3413,42 +3003,17 @@ ansi_put(scr_stat *scp, u_char *buf, int len) static void scinit(void) { - u_int hw_cursor; + int col; + int row; u_int i; if (init_done != COLD) return; init_done = WARM; - /* - * Ensure a zero start address. This is mainly to recover after - * switching from pcvt using userconfig(). The registers are w/o - * for old hardware so it's too hard to relocate the active screen - * memory. - */ - outb(crtc_addr, 12); - outb(crtc_addr + 1, 0); - outb(crtc_addr, 13); - outb(crtc_addr + 1, 0); - - /* extract cursor location */ - outb(crtc_addr, 14); - hw_cursor = inb(crtc_addr + 1) << 8; - outb(crtc_addr, 15); - hw_cursor |= inb(crtc_addr + 1); - - /* - * Validate cursor location. It may be off the screen. Then we must - * not use it for the initial buffer offset. - */ - if (hw_cursor >= ROW * COL) - hw_cursor = (ROW - 1) * COL; - - /* move hardware cursor out of the way */ - outb(crtc_addr, 14); - outb(crtc_addr + 1, 0xff); - outb(crtc_addr, 15); - outb(crtc_addr + 1, 0xff); + /* extract the hardware cursor location and move it out of the way */ + (*biosvidsw.read_hw_cursor)(V_ADP_PRIMARY, &col, &row); + (*biosvidsw.set_hw_cursor)(V_ADP_PRIMARY, -1, -1); /* set up the first console */ current_default = &user_default; @@ -3456,51 +3021,22 @@ scinit(void) init_scp(console[0]); cur_console = console[0]; - /* discard the video mode table if we are not familiar with it... */ - if (video_mode_ptr) { - bzero(mode_map, sizeof(mode_map)); - bcopy(video_mode_ptr + MODE_PARAM_SIZE*console[0]->mode, - vgaregs2, sizeof(vgaregs2)); - switch (comp_vgaregs(vgaregs, video_mode_ptr - + MODE_PARAM_SIZE*console[0]->mode)) { - case COMP_IDENTICAL: - map_mode_table(mode_map, video_mode_ptr, M_VGA_CG320 + 1); - /* - * This is a kludge for Toshiba DynaBook SS433 whose BIOS video - * mode table entry has the actual # of rows at the offset 1; - * BIOSes from other manufacturers store the # of rows - 1 there. - * XXX - */ - rows_offset = vgaregs[1] + 1 - - video_mode_ptr[MODE_PARAM_SIZE*console[0]->mode + 1]; - break; - case COMP_SIMILAR: - map_mode_table(mode_map, video_mode_ptr, M_VGA_CG320 + 1); - mode_map[console[0]->mode] = vgaregs; - rows_offset = vgaregs[1] + 1 - - video_mode_ptr[MODE_PARAM_SIZE*console[0]->mode + 1]; - vgaregs[1] -= rows_offset - 1; - break; - case COMP_DIFFERENT: - default: - video_mode_ptr = NULL; - mode_map[console[0]->mode] = vgaregs; - rows_offset = 1; - break; - } - } - /* copy screen to temporary buffer */ - if (!VESA_MODE(console[0]->mode)) + if (ISTEXTSC(console[0])) generic_bcopy(Crtat, sc_buffer, console[0]->xsize * console[0]->ysize * sizeof(u_short)); console[0]->scr_buf = console[0]->mouse_pos = console[0]->mouse_oldpos = sc_buffer; - console[0]->cursor_pos = console[0]->cursor_oldpos = sc_buffer + hw_cursor; + if (col >= console[0]->xsize) + col = 0; + if (row >= console[0]->ysize) + row = console[0]->ysize - 1; + console[0]->xpos = col; + console[0]->ypos = row; + console[0]->cursor_pos = console[0]->cursor_oldpos = + sc_buffer + row*console[0]->xsize + col; console[0]->cursor_saveunder = *console[0]->cursor_pos; - console[0]->xpos = hw_cursor % COL; - console[0]->ypos = hw_cursor / COL; for (i=1; 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 } @@ -3551,52 +3085,79 @@ scshutdown(int howto, void *arg) shutdown_in_progress = TRUE; } -static void -map_mode_table(char *map[], char *table, int max) +int +sc_clean_up(scr_stat *scp) { - int i; + int error; - for(i = 0; i < max; ++i) - map[i] = table + i*MODE_PARAM_SIZE; - for(; i < MODE_MAP_SIZE; ++i) - map[i] = NULL; + if ((error = wait_scrn_saver_stop())) + return error; + scp->status &= ~MOUSE_VISIBLE; + remove_cutmarking(scp); + return 0; } -static int -map_mode_num(int mode) +void +sc_alloc_scr_buffer(scr_stat *scp, int wait, int clear) { - static struct { - int from; - int to; - } mode_map[] = { - { M_ENH_B80x43, M_ENH_B80x25 }, - { M_ENH_C80x43, M_ENH_C80x25 }, - { M_VGA_M80x30, M_VGA_M80x25 }, - { M_VGA_C80x30, M_VGA_C80x25 }, - { M_VGA_M80x50, M_VGA_M80x25 }, - { M_VGA_C80x50, M_VGA_C80x25 }, - { M_VGA_M80x60, M_VGA_M80x25 }, - { M_VGA_C80x60, M_VGA_C80x25 }, - { M_VGA_MODEX, M_VGA_CG320 }, - }; - int i; + if (scp->scr_buf) + free(scp->scr_buf, M_DEVBUF); + scp->scr_buf = (u_short *)malloc(scp->xsize*scp->ysize*sizeof(u_short), + M_DEVBUF, (wait) ? M_WAITOK : M_NOWAIT); - for (i = 0; i < sizeof(mode_map)/sizeof(mode_map[0]); ++i) { - if (mode_map[i].from == mode) - return mode_map[i].to; + if (clear) { + /* clear the screen and move the text cursor to the top-left position */ + sc_clear_screen(scp); + } else { + /* retain the current cursor position, but adjust pointers */ + move_crsr(scp, scp->xpos, scp->ypos); + scp->cursor_oldpos = scp->cursor_pos; } - return mode; + + /* move the mouse cursor at the center of the screen */ + sc_move_mouse(scp, scp->xpixel / 2, scp->ypixel / 2); } -static char -*get_mode_param(scr_stat *scp, int mode) +void +sc_alloc_cut_buffer(scr_stat *scp, int wait) { - if (mode >= MODE_MAP_SIZE) - mode = map_mode_num(mode); - if (mode < MODE_MAP_SIZE) - return mode_map[mode]; - else - return NULL; + if ((cut_buffer == NULL) + || (cut_buffer_size < scp->xsize * scp->ysize + 1)) { + if (cut_buffer != NULL) + free(cut_buffer, M_DEVBUF); + cut_buffer_size = scp->xsize * scp->ysize + 1; + cut_buffer = (u_char *)malloc(cut_buffer_size, + M_DEVBUF, (wait) ? M_WAITOK : M_NOWAIT); + if (cut_buffer != NULL) + cut_buffer[0] = '\0'; + } +} + +void +sc_alloc_history_buffer(scr_stat *scp, int lines, int extra, int wait) +{ + u_short *usp; + + if (lines < scp->ysize) + lines = scp->ysize; + + usp = scp->history; + scp->history = NULL; + if (usp != NULL) { + free(usp, M_DEVBUF); + if (extra > 0) + extra_history_size += extra; + } + + scp->history_size = lines * scp->xsize; + if (lines > imax(sc_history_size, scp->ysize)) + extra_history_size -= lines - imax(sc_history_size, scp->ysize); + usp = (u_short *)malloc(scp->history_size * sizeof(u_short), + M_DEVBUF, (wait) ? M_WAITOK : M_NOWAIT); + if (usp != NULL) + bzero(usp, scp->history_size * sizeof(u_short)); + scp->history_head = scp->history_pos = usp; + scp->history = usp; } static scr_stat @@ -3606,22 +3167,15 @@ static scr_stat scp = (scr_stat *)malloc(sizeof(scr_stat), M_DEVBUF, M_WAITOK); init_scp(scp); - scp->scr_buf = scp->cursor_pos = scp->cursor_oldpos = - (u_short *)malloc(scp->xsize*scp->ysize*sizeof(u_short), - M_DEVBUF, M_WAITOK); - scp->mouse_pos = scp->mouse_oldpos = - scp->scr_buf + ((scp->mouse_ypos/scp->font_size)*scp->xsize + - scp->mouse_xpos/8); - scp->history_head = scp->history_pos = - (u_short *)malloc(scp->history_size*sizeof(u_short), - M_DEVBUF, M_WAITOK); - bzero(scp->history_head, scp->history_size*sizeof(u_short)); - scp->history = scp->history_head; + sc_alloc_scr_buffer(scp, TRUE, TRUE); + if (ISMOUSEAVAIL(get_adapter(scp)->va_flags)) + sc_alloc_cut_buffer(scp, TRUE); + sc_alloc_history_buffer(scp, sc_history_size, 0, TRUE); /* SOS - if (crtc_type == KD_VGA && video_mode_ptr) + if (get_adapter(scp)->va_flags & V_ADP_MODECHANGE) set_mode(scp); */ - clear_screen(scp); + sc_clear_screen(scp); scp->cursor_saveunder = *scp->cursor_pos; return scp; } @@ -3629,43 +3183,29 @@ static scr_stat static void init_scp(scr_stat *scp) { - switch(crtc_type) { - case KD_VGA: - if (VESA_MODE(bios_video_mode)) - scp->mode = bios_video_mode; - else if (crtc_addr == MONO_BASE) - scp->mode = M_VGA_M80x25; - else - scp->mode = M_VGA_C80x25; - scp->font_size = 16; - break; - case KD_CGA: - if (crtc_addr == MONO_BASE) - scp->mode = M_B80x25; - else - scp->mode = M_C80x25; - scp->font_size = 8; - break; - case KD_EGA: - if (crtc_addr == MONO_BASE) - scp->mode = M_B80x25; - else - scp->mode = M_C80x25; - scp->font_size = 14; - break; - case KD_MONO: - case KD_HERCULES: - default: - scp->mode = M_EGAMONO80x25; - scp->font_size = 14; - break; - } - scp->initial_mode = scp->mode; + video_info_t info; - scp->xsize = COL; - scp->ysize = ROW; - scp->xpixel = scp->xsize * 8; - scp->ypixel = scp->ysize * scp->font_size; + 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; scp->xpos = scp->ypos = 0; scp->saved_xpos = scp->saved_ypos = -1; scp->start = scp->xsize * scp->ysize; @@ -3677,8 +3217,8 @@ init_scp(scr_stat *scp) current_default->std_color; scp->term.rev_color = current_default->rev_color; scp->border = BG_BLACK; - 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); scp->mouse_xpos = scp->xsize*8/2; scp->mouse_ypos = scp->ysize*scp->font_size/2; scp->mouse_cut_start = scp->mouse_cut_end = NULL; @@ -3687,13 +3227,13 @@ init_scp(scr_stat *scp) scp->mouse_proc = NULL; scp->bell_pitch = BELL_PITCH; scp->bell_duration = BELL_DURATION; - 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; scp->pid = 0; scp->proc = NULL; scp->smode.mode = VT_AUTO; scp->history_head = scp->history_pos = scp->history = NULL; - scp->history_size = imax(SC_HISTORY_SIZE, scp->ysize) * scp->xsize; + scp->history_size = imax(sc_history_size, scp->ysize) * scp->xsize; } static u_char @@ -4140,9 +3680,9 @@ scgetc(u_int flags) 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); } } } @@ -4409,475 +3949,100 @@ update_leds(int which) set_keyboard(KBDC_SET_LEDS, xlate_leds[which & LED_MASK]); } -void +int set_mode(scr_stat *scp) { - char special_modetable[MODE_PARAM_SIZE]; - char *mp; - int s; - int i; + video_info_t info; + video_adapter_t *adp; + /* 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; - - /* - * 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)); + return 0; /* setup video hardware for the given mode */ - switch (scp->mode) { - case M_VGA_C80x60: case M_VGA_M80x60: - special_modetable[2] = 0x08; - special_modetable[19] = 0x47; - goto special_480l; + adp = get_adapter(scp); + (*biosvidsw.set_mode)(scp->adp, scp->mode); + Crtat = (u_short *)adp->va_window; - 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 */ + if (!(scp->status & GRAPHICS_MODE)) { + /* load appropriate font */ + if (!(scp->status & PIXEL_MODE) + && ISFONTAVAIL(get_adapter(scp)->va_flags)) { + if (scp->font_size < 14) { + if (fonts_loaded & FONT_8) + copy_font(scp, LOAD, 8, font_8); + } else if (scp->font_size >= 16) { + if (fonts_loaded & FONT_16) + copy_font(scp, LOAD, 16, font_16); + } else { + if (fonts_loaded & FONT_14) + copy_font(scp, LOAD, 14, font_14); + } + /* + * FONT KLUDGE: + * This is an interim kludge to display correct font. + * Always use the font page #0 on the video plane 2. + * Somehow we cannot show the font in other font pages on + * some video cards... XXX + */ + (*biosvidsw.show_font)(scp->adp, 0); } - /* - * FONT KLUDGE: - * This is an interim kludge to display correct font. - * Always use the font page #0 on the video plane 2. - * Somehow we cannot show the font in other font pages on - * some video cards... XXX - */ - i = 0x00; - s = splhigh(); - outb(TSIDX, 0x00); outb(TSREG, 0x01); - outb(TSIDX, 0x03); outb(TSREG, i); - outb(TSIDX, 0x00); outb(TSREG, 0x03); - splx(s); + mark_all(scp); + } + set_border(scp, scp->border); + + /* move hardware cursor out of the way */ + (*biosvidsw.set_hw_cursor)(scp->adp, -1, -1); + + return 0; +} + +void +copy_font(scr_stat *scp, int operation, int font_size, u_char *buf) +{ + /* + * 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 (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; + } else if (operation == SAVE) { + (*biosvidsw.save_font)(scp->adp, 0, font_size, buf, 0, 256); } - - /* set border color for this (virtual) console */ - set_border(scp->border); - return; -} - -void -set_border(u_char color) -{ - switch (crtc_type) { - case KD_EGA: - case KD_VGA: - inb(crtc_addr + 6); /* reset flip-flop */ - outb(ATC, 0x31); outb(ATC, color); - break; - case KD_CGA: - outb(crtc_addr + 5, color & 0x0f); /* color select register */ - break; - case KD_MONO: - case KD_HERCULES: - default: - break; - } -} - -static void -set_vgaregs(char *modetable) -{ - int i, s = splhigh(); - - outb(TSIDX, 0x00); outb(TSREG, 0x01); /* stop sequencer */ - for (i=0; i<4; i++) { /* program sequencer */ - outb(TSIDX, i+1); - outb(TSREG, modetable[i+5]); - } - outb(MISC, modetable[9]); /* set dot-clock */ - outb(TSIDX, 0x00); outb(TSREG, 0x03); /* start sequencer */ - outb(crtc_addr, 0x11); - outb(crtc_addr+1, inb(crtc_addr+1) & 0x7F); - for (i=0; i<25; i++) { /* program crtc */ - outb(crtc_addr, i); - if (i == 14 || i == 15) /* no hardware cursor */ - outb(crtc_addr+1, 0xff); - else - outb(crtc_addr+1, modetable[i+10]); - } - inb(crtc_addr+6); /* reset flip-flop */ - for (i=0; i<20; i++) { /* program attribute ctrl */ - outb(ATC, i); - outb(ATC, modetable[i+35]); - } - for (i=0; i<9; i++) { /* program graph data ctrl */ - outb(GDCIDX, i); - outb(GDCREG, modetable[i+55]); - } - inb(crtc_addr+6); /* reset flip-flop */ - outb(ATC, 0x20); /* enable palette */ - splx(s); -} - -static void -read_vgaregs(char *buf) -{ - int i, j; - int s; - - bzero(buf, MODE_PARAM_SIZE); - - s = splhigh(); - - outb(TSIDX, 0x00); outb(TSREG, 0x01); /* stop sequencer */ - for (i=0, j=5; i<4; i++) { - outb(TSIDX, i+1); - buf[j++] = inb(TSREG); - } - buf[9] = inb(MISC + 10); /* dot-clock */ - outb(TSIDX, 0x00); outb(TSREG, 0x03); /* start sequencer */ - - for (i=0, j=10; i<25; i++) { /* crtc */ - outb(crtc_addr, i); - buf[j++] = inb(crtc_addr+1); - } - for (i=0, j=35; i<20; i++) { /* attribute ctrl */ - inb(crtc_addr+6); /* reset flip-flop */ - outb(ATC, i); - buf[j++] = inb(ATC + 1); - } - for (i=0, j=55; i<9; i++) { /* graph data ctrl */ - outb(GDCIDX, i); - buf[j++] = inb(GDCREG); - } - inb(crtc_addr+6); /* reset flip-flop */ - outb(ATC, 0x20); /* enable palette */ - - buf[0] = *(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); -} - -void -copy_font(int operation, int font_type, char* font_image) -{ - int ch, line, segment, fontsize; - u_char buf[PARAM_BUFSIZE]; - u_char val; - - switch (font_type) { - default: - case FONT_8: - segment = 0x8000; - fontsize = 8; - break; - case FONT_14: - segment = 0x4000; - fontsize = 14; - break; - case FONT_16: - segment = 0x0000; - fontsize = 16; - break; - } - /* - * FONT KLUDGE - * Always use the font page #0. XXX - */ - segment = 0x0000; - outb(TSIDX, 0x01); val = inb(TSREG); /* disable screen */ - outb(TSIDX, 0x01); outb(TSREG, val | 0x20); - set_font_mode(buf); - for (ch=0; ch < 256; ch++) - for (line=0; line < fontsize; line++) - if (operation) - *(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 */ } static void set_destructive_cursor(scr_stat *scp) { - 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) || !ISTEXTSC(scp)) + 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) @@ -4902,9 +4067,18 @@ 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; +} + +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 @@ -4916,7 +4090,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) @@ -5146,35 +4320,26 @@ mouse_paste(scr_stat *scp) static void draw_mouse_image(scr_stat *scp) { - 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_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), @@ -5209,9 +4374,11 @@ draw_mouse_image(scr_stat *scp) /* wait for vertical retrace to avoid jitter on some videocards */ while (!(inb(crtc_addr+6) & 0x08)) /* idle */ ; #endif - set_font_mode(buf); - 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); @@ -5229,6 +4396,8 @@ remove_mouse_image(scr_stat *scp) { u_short *crt_pos = Crtat + (scp->mouse_oldpos - scp->scr_buf); + if (!ISTEXTSC(scp)) + return; *(crt_pos) = *(scp->mouse_oldpos); *(crt_pos+1) = *(scp->mouse_oldpos+1); *(crt_pos+scp->xsize) = *(scp->mouse_oldpos+scp->xsize); @@ -5278,30 +4447,6 @@ remove_cutmarking(scr_stat *scp) mark_all(scp); } -static void -save_palette(void) -{ - int i; - - outb(PALRADR, 0x00); - for (i=0x00; i<0x300; i++) - palette[i] = inb(PALDATA); - inb(crtc_addr+6); /* reset flip/flop */ -} - -void -load_palette(char *palette) -{ - int i; - - outb(PIXMASK, 0xFF); /* no pixelmask */ - outb(PALWADR, 0x00); - for (i=0x00; i<0x300; i++) - outb(PALDATA, palette[i]); - inb(crtc_addr+6); /* reset flip/flop */ - outb(ATC, 0x20); /* enable palette */ -} - static void do_bell(scr_stat *scp, int pitch, int duration) { @@ -5330,7 +4475,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) @@ -5351,25 +4496,41 @@ blink_screen(void *arg) void sc_bcopy(scr_stat *scp, u_short *p, int from, int to, int mark) { - if (!VESA_MODE(scp->mode)) { - generic_bcopy(p+from, Crtat+from, (to-from+1)*sizeof (u_short)); - } else if (scp->mode == 0x102) { - u_char *d, *e; - int i,j; + u_char *font; + u_char *d, *e; + u_char *f; + int font_size; + int line_length; + int xsize; + int i, j; + if (ISTEXTSC(scp)) { + generic_bcopy(p+from, Crtat+from, (to-from+1)*sizeof (u_short)); + } else /* if ISPIXELSC(scp) */ { if (mark) - mark = 255; - d = (u_char *)Crtat; - d += 10 + 6*16*100 + (from%80) + 16*100*(from/80); + mark = 255; + font_size = scp->font_size; + if (font_size < 14) + font = font_8; + else if (font_size >= 16) + font = font_16; + else + font = font_14; + line_length = scp->xpixel/8; + xsize = scp->xsize; + d = (u_char *)Crtat + + scp->xoff + scp->yoff*font_size*line_length + + (from%xsize) + font_size*line_length*(from/xsize); for (i = from ; i <= to ; i++) { e = d; - for (j = 0 ; j < 16; j++) { - *e = mark^font_16[(p[i]&0xff)*16+j]; - e+=100; + f = &font[(p[i] & 0x00ff)*font_size]; + for (j = 0 ; j < font_size; j++, f++) { + *e = mark^*f; + e += line_length; } d++; - if ((i % 80) == 79) - d += 20 + 15*100; + if ((i % xsize) == xsize - 1) + d += scp->xoff*2 + (font_size - 1)*line_length; } } } @@ -5377,34 +4538,36 @@ sc_bcopy(scr_stat *scp, u_short *p, int from, int to, int mark) #ifdef SC_SPLASH_SCREEN static void -scsplash_init(void) +scsplash_init(scr_stat *scp) { + video_info_t info; + /* * We currently assume the splash screen always use * VGA_CG320 mode and abort installation if this mode is not * supported with this video card. XXX */ - if (crtc_type != KD_VGA || get_mode_param(cur_console, M_VGA_CG320) == NULL) + if ((*biosvidsw.get_info)(scp->adp, M_VGA_CG320, &info)) return; - if (splash_load() == 0 && add_scrn_saver(scsplash) == 0) { - default_saver = scsplash; + if (scsplash_load(scp) == 0 && add_scrn_saver(scsplash_saver) == 0) { + default_saver = scsplash_saver; scrn_blank_time = DEFAULT_BLANKTIME; run_scrn_saver = TRUE; - if (!(boothowto & RB_CONFIG)) { + if (!(boothowto & (RB_VERBOSE | RB_CONFIG))) { scsplash_stick(TRUE); - scsplash(TRUE); + scsplash_saver(TRUE); } } } static void -scsplash(int show) +scsplash_saver(int show) { if (show) - splash(TRUE); + scsplash(TRUE); else if (!sticky_splash) - splash(FALSE); + scsplash(FALSE); } #endif /* SC_SPLASH_SCREEN */ diff --git a/sys/i386/isa/syscons.h b/sys/i386/isa/syscons.h index b23a2ae7c5da..315946b57305 100644 --- a/sys/i386/isa/syscons.h +++ b/sys/i386/isa/syscons.h @@ -1,18 +1,18 @@ /*- - * Copyright (c) 1995-1997 Søren Schmidt + * Copyright (c) 1995-1998 Søren Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. + * notice, this list of conditions and the following disclaimer, + * without modification, immediately at the beginning of the file. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission + * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES @@ -25,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.38 1998/08/03 09:09:35 yokota Exp $ + * $Id$ */ #ifndef _I386_ISA_SYSCONS_H_ @@ -65,6 +65,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 +77,7 @@ #define XT_KEYBD 0x00010 #define KBD_NORESET 0x00020 #define QUIET_BELL 0x00040 +#define VESA800X600 0x00080 /* attribute flags */ #define NORMAL_ATTR 0x00 @@ -84,9 +88,6 @@ #define FOREGROUND_CHANGED 0x10 #define BACKGROUND_CHANGED 0x20 -/* video hardware memory addresses */ -#define VIDEOMEM 0x000A0000 - /* misc defines */ #define FALSE 0 #define TRUE 1 @@ -104,20 +105,6 @@ #define FONT_14 4 #define FONT_16 8 -/* defines related to hardware addresses */ -#define MONO_BASE 0x3B4 /* crt controller base mono */ -#define COLOR_BASE 0x3D4 /* crt controller base color */ -#define MISC 0x3C2 /* misc output register */ -#define ATC IO_VGA+0x00 /* attribute controller */ -#define TSIDX IO_VGA+0x04 /* timing sequencer idx */ -#define TSREG IO_VGA+0x05 /* timing sequencer data */ -#define PIXMASK IO_VGA+0x06 /* pixel write mask */ -#define PALRADR IO_VGA+0x07 /* palette read address */ -#define PALWADR IO_VGA+0x08 /* palette write address */ -#define PALDATA IO_VGA+0x09 /* palette data register */ -#define GDCIDX IO_VGA+0x0E /* graph data controller idx */ -#define GDCREG IO_VGA+0x0F /* graph data controller data */ - /* special characters */ #define cntlc 0x03 #define cntld 0x04 @@ -141,6 +128,7 @@ typedef struct term_stat { } term_stat; typedef struct scr_stat { + int adp; /* video adapter index */ u_short *scr_buf; /* buffer when off screen */ int xpos; /* current X position */ int ypos; /* current Y position */ @@ -150,6 +138,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 */ @@ -186,7 +176,8 @@ 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 } scr_stat; @@ -195,18 +186,59 @@ typedef struct default_attr { int rev_color; /* reverse hardware color */ } default_attr; + +#define ISTEXTSC(scp) (!((scp)->status \ + & (UNKNOWN_MODE | GRAPHICS_MODE | PIXEL_MODE))) +#define ISGRAPHSC(scp) (((scp)->status \ + & (UNKNOWN_MODE | GRAPHICS_MODE))) +#define ISPIXELSC(scp) (((scp)->status \ + & (UNKNOWN_MODE | GRAPHICS_MODE | PIXEL_MODE))\ + == PIXEL_MODE) +#define ISUNKNOWNSC(scp) ((scp)->status & UNKNOWN_MODE) + +#define ISFONTAVAIL(af) ((af) & V_ADP_FONT) +#define ISMOUSEAVAIL(af) ((af) & V_ADP_FONT) +#define ISPALAVAIL(af) ((af) & V_ADP_PALETTE) + /* misc prototypes used by different syscons related LKM's */ -void set_border(u_char color); -void set_mode(scr_stat *scp); -void copy_font(int operation, int font_type, char* font_image); -void load_palette(char *palette); + +/* syscons.c */ +extern int (*sc_user_ioctl)(dev_t dev, int cmd, caddr_t data, int flag, + struct proc *p); + +int set_mode(scr_stat *scp); +scr_stat *sc_get_scr_stat(dev_t dev); + +void copy_font(scr_stat *scp, int operation, int font_size, u_char *font_image); +#define save_palette(scp, pal) (*biosvidsw.save_palette)((scp)->adp, pal) +#define load_palette(scp, pal) (*biosvidsw.load_palette)((scp)->adp, pal) +#define set_border(scp, col) (*biosvidsw.set_border)((scp)->adp, col) +#define get_adapter(scp) (*biosvidsw.adapter)((scp)->adp) + int add_scrn_saver(void (*this)(int)); int remove_scrn_saver(void (*this)(int)); +void sc_clear_screen(scr_stat *scp); +void sc_move_mouse(scr_stat *scp, int x, int y); +int sc_clean_up(scr_stat *scp); +void sc_alloc_scr_buffer(scr_stat *scp, int wait, int clear); +void sc_alloc_cut_buffer(scr_stat *scp, int wait); +void sc_alloc_history_buffer(scr_stat *scp, int lines, int extra, int wait); + +/* scvidctl.c */ +int sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, + int xsize, int ysize, int fontsize); +int sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode); +int sc_set_pixel_mode(scr_stat *scp, struct tty *tp, + int xsize, int ysize, int fontsize); +int sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, + struct proc *p); + #ifdef SC_SPLASH_SCREEN -void splash(int); -int splash_load(void); -int splash_unload(void); +/* splash.c */ +void scsplash(int); +int scsplash_load(scr_stat *scp); +int scsplash_unload(scr_stat *scp); #endif #endif /* !_I386_ISA_SYSCONS_H_ */ diff --git a/sys/i386/isa/vesa.c b/sys/i386/isa/vesa.c new file mode 100644 index 000000000000..768b647e5cd1 --- /dev/null +++ b/sys/i386/isa/vesa.c @@ -0,0 +1,868 @@ +/*- + * Copyright (c) 1998 Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#include "sc.h" +#include "opt_vesa.h" +#include "opt_vm86.h" + +#if (NSC > 0 && defined(VESA) && defined(VM86)) || defined(VESA_MODULE) + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#ifdef VESA_MODULE +#include +#include +#include + +MOD_MISC(vesa); +#endif + +/* VESA video adapter state buffer stub */ +struct adp_state { + int sig; +#define V_STATE_SIG 0x61736576 + u_char regs[1]; +}; +typedef struct adp_state adp_state_t; + +/* VESA video adapter */ +static video_adapter_t *vesa_adp = NULL; +static int vesa_state_buf_size = 0; +static void *vesa_state_buf = NULL; + +/* VESA functions */ +static vi_init_t vesa_init; +static vi_adapter_t vesa_adapter; +static vi_get_info_t vesa_get_info; +static vi_query_mode_t vesa_query_mode; +static vi_set_mode_t vesa_set_mode; +static vi_save_font_t vesa_save_font; +static vi_load_font_t vesa_load_font; +static vi_show_font_t vesa_show_font; +static vi_save_palette_t vesa_save_palette; +static vi_load_palette_t vesa_load_palette; +static vi_set_border_t vesa_set_border; +static vi_save_state_t vesa_save_state; +static vi_load_state_t vesa_load_state; +static vi_set_win_org_t vesa_set_origin; +static vi_read_hw_cursor_t vesa_read_hw_cursor; +static vi_set_hw_cursor_t vesa_set_hw_cursor; +static vi_diag_t vesa_diag; + +static struct vidsw vesavidsw = { + vesa_init, vesa_adapter, vesa_get_info, vesa_query_mode, + vesa_set_mode, vesa_save_font, vesa_load_font, vesa_show_font, + vesa_save_palette,vesa_load_palette,vesa_set_border,vesa_save_state, + vesa_load_state,vesa_set_origin,vesa_read_hw_cursor,vesa_set_hw_cursor, + vesa_diag, +}; + +static struct vidsw prevvidsw; + +/* VESA BIOS video modes */ +#define VESA_MAXMODES 64 +#define EOT (-1) +#define NA (-2) + +static video_info_t vesa_vmode[VESA_MAXMODES + 1] = { + { EOT, }, +}; + +static int vesa_init_done = FALSE; +static int has_vesa_bios = FALSE; +static struct vesa_info *vesa_adp_info = NULL; +static u_int16_t *vesa_vmodetab = NULL; + +/* local macros and functions */ +#define BIOS_SADDRTOLADDR(p) ((((p) & 0xffff0000) >> 12) + ((p) & 0x0000ffff)) + +static int vesa_bios_get_mode(int mode, struct vesa_mode *vmode); +static int vesa_bios_set_mode(int mode); +static int vesa_bios_set_dac(int bits); +static int vesa_bios_save_palette(int start, int colors, u_char *palette); +static int vesa_bios_load_palette(int start, int colors, u_char *palette); +#define STATE_SIZE 0 +#define STATE_SAVE 1 +#define STATE_LOAD 2 +#define STATE_HW (1<<0) +#define STATE_DATA (1<<1) +#define STATE_DAC (1<<2) +#define STATE_REG (1<<3) +#define STATE_MOST (STATE_HW | STATE_DATA | STATE_REG) +#define STATE_ALL (STATE_HW | STATE_DATA | STATE_DAC | STATE_REG) +static int vesa_bios_state_buf_size(void); +static int vesa_bios_save_restore(int code, void *p, size_t size); +static int translate_flags(u_int16_t vflags); +static int vesa_bios_init(void); +static void clear_modes(video_info_t *info, int color); + +static void +dump_buffer(u_char *buf, size_t len) +{ + int i; + + for(i = 0; i < len;) { + printf("%02x ", buf[i]); + if ((++i % 16) == 0) + printf("\n"); + } +} + +/* VESA BIOS calls */ +static int +vesa_bios_get_mode(int mode, struct vesa_mode *vmode) +{ + struct vm86frame vmf; + u_char buf[256]; + int err; + + bzero(&vmf, sizeof(vmf)); + bzero(buf, sizeof(buf)); + vmf.vmf_eax = 0x4f01; + vmf.vmf_ecx = mode; + err = vm86_datacall(0x10, &vmf, (char *)buf, sizeof(buf), + &vmf.vmf_es, &vmf.vmf_di); + if ((err != 0) || (vmf.vmf_eax != 0x4f)) + return 1; + bcopy(buf, vmode, sizeof(*vmode)); + return 0; +} + +static int +vesa_bios_set_mode(int mode) +{ + struct vm86frame vmf; + int err; + + bzero(&vmf, sizeof(vmf)); + vmf.vmf_eax = 0x4f02; + vmf.vmf_ebx = mode; + err = vm86_intcall(0x10, &vmf); + return ((err != 0) || (vmf.vmf_eax != 0x4f)); +} + +static int +vesa_bios_set_dac(int bits) +{ + struct vm86frame vmf; + int err; + + bzero(&vmf, sizeof(vmf)); + vmf.vmf_eax = 0x4f08; + vmf.vmf_ebx = (bits << 8); + err = vm86_intcall(0x10, &vmf); + return ((err != 0) || (vmf.vmf_eax != 0x4f)); +} + +static int +vesa_bios_save_palette(int start, int colors, u_char *palette) +{ + struct vm86frame vmf; + u_char *p; + int err; + int i; + + p = malloc(colors*4, M_DEVBUF, M_WAITOK); + + bzero(&vmf, sizeof(vmf)); + vmf.vmf_eax = 0x4f09; + vmf.vmf_ebx = 1; /* get primary palette data */ + vmf.vmf_ecx = colors; + vmf.vmf_edx = start; + err = vm86_datacall(0x10, &vmf, p, colors*4, &vmf.vmf_es, &vmf.vmf_di); + if ((err != 0) || (vmf.vmf_eax != 0x4f)) { + free(p, M_DEVBUF); + return 1; + } + + for (i = 0; i < colors; ++i) { + palette[i*3] = p[i*4 + 1]; + palette[i*3 + 1] = p[i*4 + 2]; + palette[i*3 + 2] = p[i*4 + 3]; + } + free(p, M_DEVBUF); + return 0; +} + +static int +vesa_bios_load_palette(int start, int colors, u_char *palette) +{ + struct vm86frame vmf; + u_char *p; + int err; + int i; + + p = malloc(colors*4, M_DEVBUF, M_WAITOK); + for (i = 0; i < colors; ++i) { + p[i*4] = 0; + p[i*4 + 1] = palette[i*3]; + p[i*4 + 2] = palette[i*3 + 1]; + p[i*4 + 3] = palette[i*3 + 2]; + } + + bzero(&vmf, sizeof(vmf)); + vmf.vmf_eax = 0x4f09; + vmf.vmf_ebx = 0; /* set primary palette data */ + vmf.vmf_ecx = colors; + vmf.vmf_edx = start; + err = vm86_datacall(0x10, &vmf, p, colors*4, &vmf.vmf_es, &vmf.vmf_di); + free(p, M_DEVBUF); + return ((err != 0) || (vmf.vmf_eax != 0x4f)); +} + +static int +vesa_bios_state_buf_size(void) +{ + struct vm86frame vmf; + int err; + + bzero(&vmf, sizeof(vmf)); + vmf.vmf_eax = 0x4f04; + vmf.vmf_ecx = STATE_MOST; + vmf.vmf_edx = STATE_SIZE; + err = vm86_intcall(0x10, &vmf); + if ((err != 0) || (vmf.vmf_eax != 0x4f)) + return 0; + return vmf.vmf_ebx*64; +} + +static int +vesa_bios_save_restore(int code, void *p, size_t size) +{ + struct vm86frame vmf; + int err; + + bzero(&vmf, sizeof(vmf)); + vmf.vmf_eax = 0x4f04; + vmf.vmf_ecx = STATE_MOST; + vmf.vmf_edx = code; /* STATE_SAVE/STATE_LOAD */ + err = vm86_datacall(0x10, &vmf, (char *)p, size, + &vmf.vmf_es, &vmf.vmf_bx); + return ((err != 0) || (vmf.vmf_eax != 0x4f)); +} + +static int +translate_flags(u_int16_t vflags) +{ + static struct { + u_int16_t mask; + int set; + int reset; + } ftable[] = { + { V_MODECOLOR, V_INFO_COLOR, 0 }, + { V_MODEGRAPHICS, V_INFO_GRAPHICS, 0 }, + { V_MODELFB, V_INFO_LENEAR, 0 }, + }; + int flags; + int i; + + for (flags = 0, i = 0; i < sizeof(ftable)/sizeof(ftable[0]); ++i) { + flags |= (vflags & ftable[i].mask) ? + ftable[i].set : ftable[i].reset; + } + return flags; +} + +static int +vesa_bios_init(void) +{ + static u_char buf[512]; + struct vm86frame vmf; + struct vesa_mode vmode; + u_int32_t p; + int modes; + int err; + int i; + + if (vesa_init_done) + return 0; + + has_vesa_bios = FALSE; + vesa_adp_info = NULL; + vesa_vmode[0].vi_mode = EOT; + + bzero(&vmf, sizeof(vmf)); /* paranoia */ + bzero(buf, sizeof(buf)); + bcopy("VBE2", buf, 4); /* try for VBE2 data */ + vmf.vmf_eax = 0x4f00; + err = vm86_datacall(0x10, &vmf, (char *)buf, sizeof(buf), + &vmf.vmf_es, &vmf.vmf_di); + if ((err != 0) || (vmf.vmf_eax != 0x4f) || bcmp("VESA", buf, 4)) + return 1; + vesa_adp_info = (struct vesa_info *)buf; + if (bootverbose) + dump_buffer(buf, 64); + if (vesa_adp_info->v_flags & V_NONVGA) + return 1; + + /* obtain video mode information */ + p = BIOS_SADDRTOLADDR(vesa_adp_info->v_modetable); + vesa_vmodetab = (u_int16_t *)BIOS_PADDRTOVADDR(p); + for (i = 0, modes = 0; vesa_vmodetab[i] != 0xffff; ++i) { + if (modes >= VESA_MAXMODES) + break; + if (vesa_bios_get_mode(vesa_vmodetab[i], &vmode)) + continue; + + /* reject unsupported modes */ +#if 0 + if ((vmode.v_modeattr & (V_MODESUPP | V_MODEOPTINFO + | V_MODENONVGA)) + != (V_MODESUPP | V_MODEOPTINFO)) + continue; +#else + if ((vmode.v_modeattr & (V_MODEOPTINFO | V_MODENONVGA)) + != (V_MODEOPTINFO)) + continue; +#endif + + /* copy some fields */ + bzero(&vesa_vmode[modes], sizeof(vesa_vmode[modes])); + vesa_vmode[modes].vi_mode = vesa_vmodetab[i]; + vesa_vmode[modes].vi_width = vmode.v_width; + vesa_vmode[modes].vi_height = vmode.v_height; + vesa_vmode[modes].vi_depth = vmode.v_bpp; + vesa_vmode[modes].vi_planes = vmode.v_planes; + vesa_vmode[modes].vi_cwidth = vmode.v_cwidth; + vesa_vmode[modes].vi_cheight = vmode.v_cheight; + vesa_vmode[modes].vi_window = (u_int)vmode.v_waseg << 4; + /* XXX window B */ + vesa_vmode[modes].vi_window_size = vmode.v_wsize; + vesa_vmode[modes].vi_window_gran = vmode.v_wgran; + vesa_vmode[modes].vi_buffer = vmode.v_lfb; + vesa_vmode[modes].vi_buffer_size = vmode.v_offscreen; + /* pixel format, memory model... */ + vesa_vmode[modes].vi_flags = translate_flags(vmode.v_modeattr) + | V_INFO_VESA; + ++modes; + } + vesa_vmode[modes].vi_mode = EOT; + if (bootverbose) + printf("VESA: %d mode(s) found\n", modes); + + has_vesa_bios = TRUE; + return 0; +} + +static void +clear_modes(video_info_t *info, int color) +{ + while (info->vi_mode != EOT) { + if ((info->vi_flags & V_INFO_COLOR) != color) + info->vi_mode = NA; + ++info; + } +} + +/* exported functions */ + +static int +vesa_init(void) +{ + int adapters; + int i; + + adapters = (*prevvidsw.init)(); + for (i = 0; i < adapters; ++i) { + if ((vesa_adp = (*prevvidsw.adapter)(i)) == NULL) + continue; + if (vesa_adp->va_type == KD_VGA) { + vesa_adp->va_flags |= V_ADP_VESA; + return adapters; + } + } + vesa_adp = NULL; + return adapters; +} + +static video_adapter_t +*vesa_adapter(int ad) +{ + return (*prevvidsw.adapter)(ad); +} + +static int +vesa_get_info(int ad, int mode, video_info_t *info) +{ + int i; + + if ((*prevvidsw.get_info)(ad, mode, info) == 0) + return 0; + + if (ad != vesa_adp->va_index) + return 1; + for (i = 0; vesa_vmode[i].vi_mode != EOT; ++i) { + if (vesa_vmode[i].vi_mode == NA) + continue; + if (vesa_vmode[i].vi_mode == mode) { + *info = vesa_vmode[i]; + return 0; + } + } + return 1; +} + +static int +vesa_query_mode(int ad, video_info_t *info) +{ + int i; + + if ((i = (*prevvidsw.query_mode)(ad, info)) != -1) + return i; + if (ad != vesa_adp->va_index) + return -1; + + for (i = 0; vesa_vmode[i].vi_mode != EOT; ++i) { + if ((info->vi_width != 0) + && (info->vi_width != vesa_vmode[i].vi_width)) + continue; + if ((info->vi_height != 0) + && (info->vi_height != vesa_vmode[i].vi_height)) + continue; + if ((info->vi_cwidth != 0) + && (info->vi_cwidth != vesa_vmode[i].vi_cwidth)) + continue; + if ((info->vi_cheight != 0) + && (info->vi_cheight != vesa_vmode[i].vi_cheight)) + continue; + if ((info->vi_depth != 0) + && (info->vi_depth != vesa_vmode[i].vi_depth)) + continue; + if ((info->vi_planes != 0) + && (info->vi_planes != vesa_vmode[i].vi_planes)) + continue; + /* pixel format, memory model */ + if ((info->vi_flags != 0) + && (info->vi_flags != vesa_vmode[i].vi_flags)) + continue; + return vesa_vmode[i].vi_mode; + } + return -1; +} + +static int +vesa_set_mode(int ad, int mode) +{ + video_info_t info; + size_t len; + + if (ad != vesa_adp->va_index) + return (*prevvidsw.set_mode)(ad, mode); + +#ifdef SC_VIDEO_DEBUG + printf("VESA: set_mode(): %d(%x) -> %d(%x)\n", + vesa_adp->va_mode, vesa_adp->va_mode, mode, mode); +#endif + /* + * If the current mode is a VESA mode and the new mode is not, + * restore the state of the adapter first, so that non-standard, + * extended SVGA registers are set to the state compatible with + * the standard VGA modes. Otherwise (*prevvidsw.set_mode)() + * may not be able to set up the new mode correctly. + */ + if (VESA_MODE(vesa_adp->va_mode)) { + if ((*prevvidsw.get_info)(ad, mode, &info) == 0) { + /* assert(vesa_state_buf != NULL); */ + if ((vesa_state_buf == NULL) + || vesa_load_state(ad, vesa_state_buf)) + return 1; + free(vesa_state_buf, M_DEVBUF); + vesa_state_buf = NULL; +#ifdef SC_VIDEO_DEBUG + printf("VESA: restored\n"); +#endif + } + /* + * once (*prevvidsw.get_info)() succeeded, + * (*prevvidsw.set_mode)() below won't fail... + */ + } + + /* we may not need to handle this mode after all... */ + if ((*prevvidsw.set_mode)(ad, mode) == 0) + return 0; + + /* is the new mode supported? */ + if (vesa_get_info(ad, mode, &info)) + return 1; + /* assert(VESA_MODE(mode)); */ + +#ifdef SC_VIDEO_DEBUG + printf("VESA: about to set a VESA mode...\n"); +#endif + /* + * If the current mode is not a VESA mode, save the current state + * so that the adapter state can be restored later when a non-VESA + * mode is to be set up. See above. + */ + if (!VESA_MODE(vesa_adp->va_mode) && (vesa_state_buf == NULL)) { + len = vesa_save_state(ad, NULL, 0); + vesa_state_buf = malloc(len, M_DEVBUF, M_WAITOK); + if (vesa_save_state(ad, vesa_state_buf, len)) { +#ifdef SC_VIDEO_DEBUG + printf("VESA: state save failed! (len=%d)\n", len); +#endif + free(vesa_state_buf, M_DEVBUF); + vesa_state_buf = NULL; + return 1; + } +#ifdef SC_VIDEO_DEBUG + printf("VESA: saved (len=%d)\n", len); + dump_buffer(vesa_state_buf, len); +#endif + } + + if (vesa_bios_set_mode(mode)) + return 1; + +#ifdef SC_VIDEO_DEBUG + printf("VESA: mode set!\n"); +#endif + vesa_adp->va_mode = mode; + vesa_adp->va_flags &= ~V_ADP_COLOR; + vesa_adp->va_flags |= + (info.vi_flags & V_INFO_COLOR) ? V_ADP_COLOR : 0; + vesa_adp->va_crtc_addr = + (vesa_adp->va_flags & V_ADP_COLOR) ? COLOR_BASE : MONO_BASE; + vesa_adp->va_window = BIOS_PADDRTOVADDR(info.vi_window); + vesa_adp->va_window_size = info.vi_window_size; + vesa_adp->va_window_gran = info.vi_window_gran; + if (info.vi_buffer_size == 0) { + vesa_adp->va_buffer = 0; + vesa_adp->va_buffer_size = 0; + } else { + vesa_adp->va_buffer = BIOS_PADDRTOVADDR(info.vi_buffer); + vesa_adp->va_buffer_size = info.vi_buffer_size; + } + + return 0; +} + +static int +vesa_save_font(int ad, int page, int fontsize, u_char *data, int ch, int count) +{ + return (*prevvidsw.save_font)(ad, page, fontsize, data, ch, count); +} + +static int +vesa_load_font(int ad, int page, int fontsize, u_char *data, int ch, int count) +{ + return (*prevvidsw.load_font)(ad, page, fontsize, data, ch, count); +} + +static int +vesa_show_font(int ad, int page) +{ + return (*prevvidsw.show_font)(ad, page); +} + +static int +vesa_save_palette(int ad, u_char *palette) +{ + if ((ad != vesa_adp->va_index) || !(vesa_adp_info->v_flags & V_DAC8) + || vesa_bios_set_dac(8)) + return (*prevvidsw.save_palette)(ad, palette); + + return vesa_bios_save_palette(0, 256, palette); +} + +static int +vesa_load_palette(int ad, u_char *palette) +{ + if ((ad != vesa_adp->va_index) || !(vesa_adp_info->v_flags & V_DAC8) + || vesa_bios_set_dac(8)) + return (*prevvidsw.load_palette)(ad, palette); + + return vesa_bios_load_palette(0, 256, palette); +} + +static int +vesa_set_border(int ad, int color) +{ + return (*prevvidsw.set_border)(ad, color); +} + +static int +vesa_save_state(int ad, void *p, size_t size) +{ + if (ad != vesa_adp->va_index) + return (*prevvidsw.save_state)(ad, p, size); + + if (vesa_state_buf_size == 0) + vesa_state_buf_size = vesa_bios_state_buf_size(); + if (size == 0) + return (sizeof(int) + vesa_state_buf_size); + else if (size < (sizeof(int) + vesa_state_buf_size)) + return 1; + + ((adp_state_t *)p)->sig = V_STATE_SIG; + bzero(((adp_state_t *)p)->regs, vesa_state_buf_size); + return vesa_bios_save_restore(STATE_SAVE, ((adp_state_t *)p)->regs, + vesa_state_buf_size); +} + +static int +vesa_load_state(int ad, void *p) +{ + if ((ad != vesa_adp->va_index) + || (((adp_state_t *)p)->sig != V_STATE_SIG)) + return (*prevvidsw.load_state)(ad, p); + + return vesa_bios_save_restore(STATE_LOAD, ((adp_state_t *)p)->regs, + vesa_state_buf_size); +} + +static int +vesa_set_origin(int ad, off_t offset) +{ + struct vm86frame vmf; + int err; + + /* + * This function should return as quickly as possible to + * maintain good performance of the system. For this reason, + * error checking is kept minimal and let the VESA BIOS to + * detect error. + */ + if (ad != vesa_adp->va_index) + return (*prevvidsw.set_win_org)(ad, offset); + + if (vesa_adp->va_window_gran == 0) + return 1; + bzero(&vmf, sizeof(vmf)); + vmf.vmf_eax = 0x4f05; + vmf.vmf_ebx = 0; /* WINDOW_A, XXX */ + vmf.vmf_edx = offset/vesa_adp->va_window_gran; + err = vm86_intcall(0x10, &vmf); + return ((err != 0) || (vmf.vmf_eax != 0x4f)); +} + +static int +vesa_read_hw_cursor(int ad, int *col, int *row) +{ + return (*prevvidsw.read_hw_cursor)(ad, col, row); +} + +static int +vesa_set_hw_cursor(int ad, int col, int row) +{ + return (*prevvidsw.set_hw_cursor)(ad, col, row); +} + +static int +vesa_diag(int level) +{ + struct vesa_mode vmode; + u_int32_t p; + int i; + + /* general adapter information */ + printf("VESA: v%d.%d, %dk memory, flags:0x%x, mode table:%p (%x)\n", + ((vesa_adp_info->v_version & 0xf000) >> 12) * 10 + + ((vesa_adp_info->v_version & 0x0f00) >> 8), + ((vesa_adp_info->v_version & 0x00f0) >> 4) * 10 + + (vesa_adp_info->v_version & 0x000f), + vesa_adp_info->v_memsize * 64, vesa_adp_info->v_flags, + vesa_vmodetab, vesa_adp_info->v_modetable); + /* OEM string */ + p = BIOS_SADDRTOLADDR(vesa_adp_info->v_oemstr); + if (p != 0) + printf("VESA: %s\n", (char *)BIOS_PADDRTOVADDR(p)); + + if (level <= 0) + return 0; + + if (vesa_adp_info->v_version >= 0x0200) { + /* vendor name */ + p = BIOS_SADDRTOLADDR(vesa_adp_info->v_venderstr); + if (p != 0) + printf("VESA: %s, ", (char *)BIOS_PADDRTOVADDR(p)); + /* product name */ + p = BIOS_SADDRTOLADDR(vesa_adp_info->v_prodstr); + if (p != 0) + printf("%s, ", (char *)BIOS_PADDRTOVADDR(p)); + /* product revision */ + p = BIOS_SADDRTOLADDR(vesa_adp_info->v_revstr); + if (p != 0) + printf("%s\n", (char *)BIOS_PADDRTOVADDR(p)); + } + + /* mode information */ + for (i = 0; vesa_vmodetab[i] != 0xffff; ++i) { + if (vesa_bios_get_mode(vesa_vmodetab[i], &vmode)) + continue; + + /* print something for diagnostic purpose */ + printf("VESA: mode:0x%03x, flags:0x%04x", + vesa_vmodetab[i], vmode.v_modeattr); + if (vmode.v_modeattr & V_MODEOPTINFO) { + if (vmode.v_modeattr & V_MODEGRAPHICS) { + printf(", G %dx%dx%d %d, ", + vmode.v_width, vmode.v_height, + vmode.v_bpp, vmode.v_planes); + } else { + printf(", T %dx%d, ", + vmode.v_width, vmode.v_height); + } + printf("font:%dx%d", + vmode.v_cwidth, vmode.v_cheight); + } + if (vmode.v_modeattr & V_MODELFB) { + printf(", mem:%d, LFB:0x%x, off:0x%x", + vmode.v_memmodel, vmode.v_lfb, + vmode.v_offscreen); + } + printf("\n"); + printf("VESA: window A:0x%x (%x), window B:0x%x (%x), ", + vmode.v_waseg, vmode.v_waattr, + vmode.v_wbseg, vmode.v_wbattr); + printf("size:%dk, gran:%dk\n", + vmode.v_wsize, vmode.v_wgran); + } + + return 0; +} + +/* module loading */ + +#ifdef VESA_MODULE +static int +vesa_load(struct lkm_table *lkmtp, int cmd) +#else +int +vesa_load(void) +#endif +{ + int adapters; + int error; + int s; + int i; + + if (vesa_init_done) + return 0; + + /* + * If the VESA module is statically linked to the kernel, or + * it has already been loaded, abort loading this module this time. + */ + vesa_adp = NULL; + adapters = (*biosvidsw.init)(); + for (i = 0; i < adapters; ++i) { + if ((vesa_adp = (*biosvidsw.adapter)(i)) == NULL) + continue; + if (vesa_adp->va_flags & V_ADP_VESA) + return ENXIO; + if (vesa_adp->va_type == KD_VGA) + break; + } + /* if a VGA adapter is not found, abort */ + if (i >= adapters) + return ENXIO; + + if (vesa_bios_init()) + return ENXIO; + vesa_adp->va_flags |= V_ADP_VESA; + + /* remove conflicting modes if we have more than one adapter */ + if (adapters > 1) { + clear_modes(vesa_vmode, + (vesa_adp->va_flags & V_ADP_COLOR) ? + V_INFO_COLOR : 0); + } + +#ifdef VESA_MODULE + s = spltty(); +#endif + if ((error = vesa_load_ioctl()) == 0) { + bcopy(&biosvidsw, &prevvidsw, sizeof(prevvidsw)); + bcopy(&vesavidsw, &biosvidsw, sizeof(vesavidsw)); + vesa_init_done = TRUE; + } +#ifdef VESA_MODULE + splx(s); + + if (error == 0) + vesa_diag(bootverbose); +#endif + + return error; +} + +#ifdef VESA_MODULE + +static int +vesa_unload(struct lkm_table *lkmtp, int cmd) +{ + int error; + int s; + + /* if the adapter is currently in a VESA mode, don't unload */ + if ((vesa_adp != NULL) && VESA_MODE(vesa_adp->va_mode)) + return EBUSY; + /* + * FIXME: if there is at least one vty which is in a VESA mode, + * we shouldn't be unloading! XXX + */ + + s = spltty(); + if ((error = vesa_unload_ioctl()) == 0) { + if (vesa_adp) + vesa_adp->va_flags &= ~V_ADP_VESA; + bcopy(&prevvidsw, &biosvidsw, sizeof(biosvidsw)); + } + splx(s); + + return error; +} + +int +vesa_mod(struct lkm_table *lkmtp, int cmd, int ver) +{ + MOD_DISPATCH(vesa, lkmtp, cmd, ver, + vesa_load, vesa_unload, lkm_nullcmd); +} + +#endif /* VESA_MODULE */ + +#endif /* (NSC > 0 && VESA && VM86) || VESA_MODULE */ diff --git a/sys/i386/isa/videoio.c b/sys/i386/isa/videoio.c new file mode 100644 index 000000000000..85c8f8d56ba8 --- /dev/null +++ b/sys/i386/isa/videoio.c @@ -0,0 +1,1612 @@ +/*- + * Copyright (c) 1998 Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#include "sc.h" +#include "opt_syscons.h" + +#if NSC > 0 + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +/* this should really be in `rtc.h' */ +#define RTC_EQUIPMENT 0x14 + +/* video adapter state buffer */ +struct adp_state { + int sig; +#define V_STATE_SIG 0x736f6962 + u_char regs[V_MODE_PARAM_SIZE]; +}; +typedef struct adp_state adp_state_t; + +/* video adapter information */ +#define DCC_MONO 0 +#define DCC_CGA40 1 +#define DCC_CGA80 2 +#define DCC_EGAMONO 3 +#define DCC_EGA40 4 +#define DCC_EGA80 5 + +/* + * NOTE: `va_window' should have a virtual address, but is initialized + * with a physical address in the following table, as verify_adapter() + * will perform address conversion at run-time. + */ +static video_adapter_t adapter_init_value[] = { + { 0, KD_MONO, 0, MONO_BASE, 0xb0000, 32, 32, 0, 0, 0, 7, 0 }, + { 0, KD_CGA, V_ADP_COLOR, COLOR_BASE, 0xb8000, 32, 32, 0, 0, 0, 3, 0 }, + { 0, KD_CGA, V_ADP_COLOR, COLOR_BASE, 0xb8000, 32, 32, 0, 0, 0, 3, 0 }, + { 0, KD_EGA, 0, MONO_BASE, 0xb0000, 32, 32, 0, 0, 0, 7, 0 }, + { 0, KD_EGA, V_ADP_COLOR, COLOR_BASE, 0xb8000, 32, 32, 0, 0, 0, 3, 0 }, + { 0, KD_EGA, V_ADP_COLOR, COLOR_BASE, 0xb8000, 32, 32, 0, 0, 0, 3, 0 }, +}; + +static video_adapter_t adapter[V_MAX_ADAPTERS]; +static int adapters = 0; + +/* VGA function entries */ +static vi_init_t vid_init; +static vi_adapter_t vid_adapter; +static vi_get_info_t vid_get_info; +static vi_query_mode_t vid_query_mode; +static vi_set_mode_t vid_set_mode; +static vi_save_font_t vid_save_font; +static vi_load_font_t vid_load_font; +static vi_show_font_t vid_show_font; +static vi_save_palette_t vid_save_palette; +static vi_load_palette_t vid_load_palette; +static vi_set_border_t vid_set_border; +static vi_save_state_t vid_save_state; +static vi_load_state_t vid_load_state; +static vi_set_win_org_t vid_set_origin; +static vi_read_hw_cursor_t vid_read_hw_cursor; +static vi_set_hw_cursor_t vid_set_hw_cursor; +static vi_diag_t vid_diag; + +struct vidsw biosvidsw = { + vid_init, vid_adapter, vid_get_info, vid_query_mode, + vid_set_mode, vid_save_font, vid_load_font, vid_show_font, + vid_save_palette,vid_load_palette,vid_set_border,vid_save_state, + vid_load_state, vid_set_origin, vid_read_hw_cursor, vid_set_hw_cursor, + vid_diag, +}; + +/* VGA BIOS standard video modes */ +#define EOT (-1) +#define NA (-2) + +static video_info_t bios_vmode[] = { + /* CGA */ + { M_B40x25, V_INFO_COLOR, 40, 25, 8, 8, 2, 1, 0xb8000, 32, 32, 0, 32 }, + { M_C40x25, V_INFO_COLOR, 40, 25, 8, 8, 4, 1, 0xb8000, 32, 32, 0, 32 }, + { M_B80x25, V_INFO_COLOR, 80, 25, 8, 8, 2, 1, 0xb8000, 32, 32, 0, 32 }, + { M_C80x25, V_INFO_COLOR, 80, 25, 8, 8, 4, 1, 0xb8000, 32, 32, 0, 32 }, + /* EGA */ + { M_ENH_B40x25, V_INFO_COLOR, 40, 25, 8, 14, 2, 1, 0xb8000, 32, 32, 0, 32 }, + { M_ENH_C40x25, V_INFO_COLOR, 40, 25, 8, 14, 4, 1, 0xb8000, 32, 32, 0, 32 }, + { M_ENH_B80x25, V_INFO_COLOR, 80, 25, 8, 14, 2, 1, 0xb8000, 32, 32, 0, 32 }, + { M_ENH_C80x25, V_INFO_COLOR, 80, 25, 8, 14, 4, 1, 0xb8000, 32, 32, 0, 32 }, + /* VGA */ + { M_VGA_C40x25, V_INFO_COLOR, 40, 25, 8, 16, 4, 1, 0xb8000, 32, 32, 0, 32 }, + { M_VGA_M80x25, 0, 80, 25, 8, 16, 2, 1, 0xb0000, 32, 32, 0, 32 }, + { M_VGA_C80x25, V_INFO_COLOR, 80, 25, 8, 16, 4, 1, 0xb8000, 32, 32, 0, 32 }, + /* MDA */ + { M_EGAMONO80x25, 0, 80, 25, 8, 14, 2, 1, 0xb0000, 32, 32, 0, 32 }, + /* EGA */ + { M_ENH_B80x43, V_INFO_COLOR, 80, 43, 8, 8, 2, 1, 0xb8000, 32, 32, 0, 32 }, + { M_ENH_C80x43, V_INFO_COLOR, 80, 43, 8, 8, 4, 1, 0xb8000, 32, 32, 0, 32 }, + /* VGA */ + { M_VGA_M80x30, 0, 80, 30, 8, 16, 2, 1, 0xb0000, 32, 32, 0, 32 }, + { M_VGA_C80x30, V_INFO_COLOR, 80, 30, 8, 16, 4, 1, 0xb8000, 32, 32, 0, 32 }, + { M_VGA_M80x50, 0, 80, 50, 8, 8, 2, 1, 0xb0000, 32, 32, 0, 32 }, + { M_VGA_C80x50, V_INFO_COLOR, 80, 50, 8, 8, 4, 1, 0xb8000, 32, 32, 0, 32 }, + { M_VGA_M80x60, 0, 80, 60, 8, 8, 2, 1, 0xb0000, 32, 32, 0, 32 }, + { M_VGA_C80x60, V_INFO_COLOR, 80, 60, 8, 8, 4, 1, 0xb8000, 32, 32, 0, 32 }, + /* CGA */ + { M_BG320, V_INFO_COLOR | V_INFO_GRAPHICS, + 320, 200, 8, 8, 2, 1, 0xb8000, 32, 32, 0, 32 }, + { M_CG320, V_INFO_COLOR | V_INFO_GRAPHICS, + 320, 200, 8, 8, 2, 1, 0xb8000, 32, 32, 0, 32 }, + { M_BG640, V_INFO_COLOR | V_INFO_GRAPHICS, + 640, 200, 8, 8, 1, 1, 0xb8000, 32, 32, 0, 32 }, + /* EGA */ + { M_CG320_D, V_INFO_COLOR | V_INFO_GRAPHICS, + 320, 200, 8, 8, 4, 4, 0xa0000, 64, 64, 0, 64 }, + { M_CG640_E, V_INFO_COLOR | V_INFO_GRAPHICS, + 640, 200, 8, 8, 4, 4, 0xa0000, 64, 64, 0, 64 }, + { M_EGAMONOAPA, V_INFO_GRAPHICS, + 640, 350, 8, 14, 4, 4, 0xa0000, 64, 64, 0, 64 }, + { M_ENHMONOAPA2,V_INFO_GRAPHICS, + 640, 350, 8, 14, 4, 4, 0xa0000, 64, 64, 0, 64 }, + { M_CG640x350, V_INFO_COLOR | V_INFO_GRAPHICS, + 640, 350, 8, 14, 2, 2, 0xa0000, 64, 64, 0, 64 }, + { M_ENH_CG640, V_INFO_COLOR | V_INFO_GRAPHICS, + 640, 350, 8, 14, 4, 4, 0xa0000, 64, 64, 0, 64 }, + /* VGA */ + { M_BG640x480, V_INFO_COLOR | V_INFO_GRAPHICS, + 640, 480, 8, 16, 4, 4, 0xa0000, 64, 64, 0, 64 }, + { M_CG640x480, V_INFO_COLOR | V_INFO_GRAPHICS, + 640, 480, 8, 16, 4, 4, 0xa0000, 64, 64, 0, 64 }, + { M_VGA_CG320, V_INFO_COLOR | V_INFO_GRAPHICS, + 320, 200, 8, 8, 8, 1, 0xa0000, 64, 64, 0, 64 }, + { M_VGA_MODEX, V_INFO_COLOR | V_INFO_GRAPHICS, + 320, 240, 8, 8, 8, 1, 0xa0000, 64, 64, 0, 64 }, + + { EOT }, +}; + +static int init_done = FALSE; +static u_char *video_mode_ptr = NULL; /* EGA/VGA */ +static u_char *video_mode_ptr2 = NULL; /* CGA/MDA */ +static u_char *mode_map[V_MODE_MAP_SIZE]; +static adp_state_t adpstate; +static adp_state_t adpstate2; +static int rows_offset = 1; + +/* local macros and functions */ +#define BIOS_SADDRTOLADDR(p) ((((p) & 0xffff0000) >> 12) + ((p) & 0x0000ffff)) + +static void map_mode_table(u_char *map[], u_char *table, int max); +static void clear_mode_map(int ad, u_char *map[], int max, int color); +static int map_mode_num(int mode); +static int map_bios_mode_num(int type, int color, int bios_mode); +static u_char *get_mode_param(int mode); +static void fill_adapter_param(int code, video_adapter_t *adp); +static int verify_adapter(video_adapter_t *adp); +#define COMP_IDENTICAL 0 +#define COMP_SIMILAR 1 +#define COMP_DIFFERENT 2 +static int comp_adpregs(u_char *buf1, u_char *buf2); + +#define PARAM_BUFSIZE 6 +static void set_font_mode(video_adapter_t *adp, u_char *buf); +static void set_normal_mode(video_adapter_t *adp, u_char *buf); + +static char *adapter_name(int type); +static void dump_adp_info(int ad, video_adapter_t *adp, int level); +static void dump_mode_info(int ad, video_info_t *info, int level); +static void dump_buffer(u_char *buf, size_t len); + +extern void generic_bcopy(const void *, void *, size_t); + +#define ISMAPPED(pa, width) \ + (((pa) <= (u_long)0x1000 - (width)) \ + || ((pa) >= ISA_HOLE_START && (pa) <= 0x100000 - (width))) + +#define prologue(ad, flag, err) \ + if (!init_done \ + || ((ad) < 0) || ((ad) >= adapters) \ + || !(adapter[(ad)].va_flags & (flag))) \ + return (err) + +/* construct the mode parameter map */ +static void +map_mode_table(u_char *map[], u_char *table, int max) +{ + int i; + + for(i = 0; i < max; ++i) + map[i] = table + i*V_MODE_PARAM_SIZE; + for(; i < V_MODE_MAP_SIZE; ++i) + map[i] = NULL; +} + +static void +clear_mode_map(int ad, u_char *map[], int max, int color) +{ + video_info_t info; + int i; + + /* + * NOTE: we don't touch `bios_vmode[]' because it is shared + * by all adapters. + */ + for(i = 0; i < max; ++i) { + if (vid_get_info(ad, i, &info)) + continue; + if ((info.vi_flags & V_INFO_COLOR) != color) + map[i] = NULL; + } +} + +/* the non-standard video mode is based on a standard mode... */ +static int +map_mode_num(int mode) +{ + static struct { + int from; + int to; + } mode_map[] = { + { M_ENH_B80x43, M_ENH_B80x25 }, + { M_ENH_C80x43, M_ENH_C80x25 }, + { M_VGA_M80x30, M_VGA_M80x25 }, + { M_VGA_C80x30, M_VGA_C80x25 }, + { M_VGA_M80x50, M_VGA_M80x25 }, + { M_VGA_C80x50, M_VGA_C80x25 }, + { M_VGA_M80x60, M_VGA_M80x25 }, + { M_VGA_C80x60, M_VGA_C80x25 }, + { M_VGA_MODEX, M_VGA_CG320 }, + }; + int i; + + for (i = 0; i < sizeof(mode_map)/sizeof(mode_map[0]); ++i) { + if (mode_map[i].from == mode) + return mode_map[i].to; + } + return mode; +} + +/* turn the BIOS video number into our video mode number */ +static int +map_bios_mode_num(int type, int color, int bios_mode) +{ + static int cga_modes[7] = { + M_B40x25, M_C40x25, /* 0, 1 */ + M_B80x25, M_C80x25, /* 2, 3 */ + M_BG320, M_CG320, + M_BG640, + }; + static int ega_modes[17] = { + M_ENH_B40x25, M_ENH_C40x25, /* 0, 1 */ + M_ENH_B80x25, M_ENH_C80x25, /* 2, 3 */ + M_BG320, M_CG320, + M_BG640, + M_EGAMONO80x25, /* 7 */ + 8, 9, 10, 11, 12, + M_CG320_D, + M_CG640_E, + M_ENHMONOAPA2, /* XXX: video momery > 64K */ + M_ENH_CG640, /* XXX: video momery > 64K */ + }; + static int vga_modes[20] = { + M_VGA_C40x25, M_VGA_C40x25, /* 0, 1 */ + M_VGA_C80x25, M_VGA_C80x25, /* 2, 3 */ + M_BG320, M_CG320, + M_BG640, + M_VGA_M80x25, /* 7 */ + 8, 9, 10, 11, 12, + M_CG320_D, + M_CG640_E, + M_ENHMONOAPA2, + M_ENH_CG640, + M_BG640x480, M_CG640x480, + M_VGA_CG320, + }; + + switch (type) { + + case KD_VGA: + if (bios_mode < sizeof(vga_modes)/sizeof(vga_modes[0])) + return vga_modes[bios_mode]; + else if (color) + return M_VGA_C80x25; + else + return M_VGA_M80x25; + break; + + case KD_EGA: + if (bios_mode < sizeof(ega_modes)/sizeof(ega_modes[0])) + return ega_modes[bios_mode]; + else if (color) + return M_ENH_C80x25; + else + return M_EGAMONO80x25; + break; + + case KD_CGA: + if (bios_mode < sizeof(cga_modes)/sizeof(cga_modes[0])) + return cga_modes[bios_mode]; + else + return M_C80x25; + break; + + case KD_MONO: + case KD_HERCULES: + return M_EGAMONO80x25; /* XXX: this name is confusing */ + + default: + break; + } + return -1; +} + +/* look up a parameter table entry */ +static u_char +*get_mode_param(int mode) +{ + if (mode >= V_MODE_MAP_SIZE) + mode = map_mode_num(mode); + if (mode < V_MODE_MAP_SIZE) + return mode_map[mode]; + else + return NULL; +} + +static void +fill_adapter_param(int code, video_adapter_t *adp) +{ + static struct { + int primary; + int secondary; + } dcc[] = { + { DCC_MONO, DCC_EGA40 /* CGA monitor */ }, + { DCC_MONO, DCC_EGA80 /* CGA monitor */ }, + { DCC_MONO, DCC_EGA80 /* CGA emulation */ }, + { DCC_MONO, DCC_EGA80 }, + { DCC_CGA40, DCC_EGAMONO }, + { DCC_CGA80, DCC_EGAMONO }, + { DCC_EGA40 /* CGA monitor */, DCC_MONO}, + { DCC_EGA80 /* CGA monitor */, DCC_MONO}, + { DCC_EGA80 /* CGA emulation */,DCC_MONO }, + { DCC_EGA80, DCC_MONO }, + { DCC_EGAMONO, DCC_CGA40 }, + { DCC_EGAMONO, DCC_CGA40 }, + }; + + if ((code < 0) || (code >= sizeof(dcc)/sizeof(dcc[0]))) { + adp[V_ADP_PRIMARY] = adapter_init_value[DCC_MONO]; + adp[V_ADP_SECONDARY] = adapter_init_value[DCC_CGA80]; + } else { + adp[V_ADP_PRIMARY] = adapter_init_value[dcc[code].primary]; + adp[V_ADP_SECONDARY] = adapter_init_value[dcc[code].secondary]; + } +} + +static int +verify_adapter(video_adapter_t *adp) +{ + u_short volatile *buf; + u_short v; + u_int32_t p; + + buf = (u_short *)BIOS_PADDRTOVADDR(adp->va_window); + v = *buf; + *buf = (u_short) 0xA55A; + if (*buf != 0xA55A) + return 1; + *buf = v; + + switch (adp->va_type) { + + case KD_EGA: + outb(adp->va_crtc_addr, 7); + if (inb(adp->va_crtc_addr) == 7) { + adp->va_type = KD_VGA; + adp->va_flags |= V_ADP_STATESAVE | V_ADP_PALETTE; + } + adp->va_flags |= V_ADP_STATELOAD | V_ADP_FONT | V_ADP_BORDER; + /* the color adapter may be in the 40x25 mode... XXX */ + + /* get the BIOS video mode pointer */ + p = *(u_int32_t *)BIOS_PADDRTOVADDR(0x4a8); + p = BIOS_SADDRTOLADDR(p); + if (ISMAPPED(p, sizeof(u_int32_t))) { + p = *(u_int32_t *)BIOS_PADDRTOVADDR(p); + p = BIOS_SADDRTOLADDR(p); + if (ISMAPPED(p, V_MODE_PARAM_SIZE)) + video_mode_ptr = (u_char *)BIOS_PADDRTOVADDR(p); + } + break; + + case KD_CGA: + adp->va_flags |= V_ADP_COLOR | V_ADP_BORDER; + /* may be in the 40x25 mode... XXX */ + break; + + case KD_MONO: + break; + } + + return 0; +} + +/* compare two parameter table entries */ +static int +comp_adpregs(u_char *buf1, u_char *buf2) +{ + static struct { + u_char mask; + } params[V_MODE_PARAM_SIZE] = { + 0xff, 0x00, 0xff, /* COLS, ROWS, POINTS */ + 0x00, 0x00, /* page length */ + 0xfe, 0xff, 0xff, 0xff, /* sequencer registers */ + 0xf3, /* misc register */ + 0xff, 0xff, 0xff, 0x7f, 0xff, /* CRTC */ + 0xff, 0xff, 0xff, 0x7f, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0x7f, 0xff, 0xff, + 0x7f, 0xff, 0xff, 0xef, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, /* attribute controller registers */ + 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf0, + 0xff, 0xff, 0xff, 0xff, 0xff, /* GDC register */ + 0xff, 0xff, 0xff, 0xff, + }; + int identical = TRUE; + int i; + + if ((buf1 == NULL) || (buf2 == NULL)) + return COMP_DIFFERENT; + + for (i = 0; i < sizeof(params)/sizeof(params[0]); ++i) { + if (params[i].mask == 0) /* don't care */ + continue; + if ((buf1[i] & params[i].mask) != (buf2[i] & params[i].mask)) + return COMP_DIFFERENT; + if (buf1[i] != buf2[i]) + identical = FALSE; + } + return (identical) ? COMP_IDENTICAL : COMP_SIMILAR; +} + +/* exported functions */ + +/* all adapters */ +static int +vid_init(void) +{ + video_adapter_t *adp; + video_info_t info; + u_char *mp; + int i; + + /* do this test only once */ + if (init_done) + return adapters; + init_done = TRUE; + + /* + * Locate display adapters. + * The AT architecture supports upto two adapters. `syscons' allows + * the following combinations of adapters: + * 1) MDA + CGA + * 2) MDA + EGA/VGA color + * 3) CGA + EGA/VGA mono + * Note that `syscons' doesn't bother with MCGA as it is only + * avaiable for low end PS/2 models which has 80286 or earlier CPUs, + * thus, they are not running FreeBSD! + * When there are two adapaters in the system, one becomes `primary' + * and the other `secondary'. The EGA adapter has a set of DIP + * switches on board for this information and the EGA BIOS copies + * it in the BIOS data area BIOSDATA_VIDEOSWITCH (40:88). + * The VGA BIOS has more sophisticated mechanism and has this + * information in BIOSDATA_DCCINDEX (40:8a), but it also maintains + * compatibility with the EGA BIOS by updating BIOSDATA_VIDEOSWITCH. + */ + + /* check rtc and BIOS date area */ + /* + * XXX: don't use BIOSDATA_EQUIPMENT, it is not a dead copy + * of RTC_EQUIPMENT. The bit 4 and 5 of the ETC_EQUIPMENT are + * zeros for EGA and VGA. However, the EGA/VGA BIOS will set + * these bits in BIOSDATA_EQUIPMENT according to the monitor + * type detected. + */ + switch ((rtcin(RTC_EQUIPMENT) >> 4) & 3) { /* bit 4 and 5 */ + case 0: + /* EGA/VGA */ + fill_adapter_param(*(u_int8_t *)BIOS_PADDRTOVADDR(0x488) & 0x0f, + adapter); + break; + case 1: + /* CGA 40x25 */ + /* FIXME: switch to the 80x25 mode? XXX */ + adapter[V_ADP_PRIMARY] = adapter_init_value[DCC_CGA40]; + adapter[V_ADP_SECONDARY] = adapter_init_value[DCC_MONO]; + break; + case 2: + /* CGA 80x25 */ + adapter[V_ADP_PRIMARY] = adapter_init_value[DCC_CGA80]; + adapter[V_ADP_SECONDARY] = adapter_init_value[DCC_MONO]; + break; + case 3: + /* MDA */ + adapter[V_ADP_PRIMARY] = adapter_init_value[DCC_MONO]; + adapter[V_ADP_SECONDARY] = adapter_init_value[DCC_CGA80]; + break; + } + + adapters = 0; + if (verify_adapter(&adapter[V_ADP_SECONDARY]) == 0) { + ++adapters; + adapter[V_ADP_SECONDARY].va_mode = + adapter[V_ADP_SECONDARY].va_initial_mode = + map_bios_mode_num(adapter[V_ADP_SECONDARY].va_type, + adapter[V_ADP_SECONDARY].va_flags & V_ADP_COLOR, + adapter[V_ADP_SECONDARY].va_initial_bios_mode); + } else { + adapter[V_ADP_SECONDARY].va_type = -1; + } + if (verify_adapter(&adapter[V_ADP_PRIMARY]) == 0) { + ++adapters; + adapter[V_ADP_PRIMARY].va_initial_bios_mode = + *(u_int8_t *)BIOS_PADDRTOVADDR(0x449); + adapter[V_ADP_PRIMARY].va_mode = + adapter[V_ADP_PRIMARY].va_initial_mode = + map_bios_mode_num(adapter[V_ADP_PRIMARY].va_type, + adapter[V_ADP_PRIMARY].va_flags & V_ADP_COLOR, + adapter[V_ADP_PRIMARY].va_initial_bios_mode); + } else { + adapter[V_ADP_PRIMARY] = adapter[V_ADP_SECONDARY]; + adapter[V_ADP_SECONDARY].va_type = -1; + } + if (adapters == 0) + return adapters; + adapter[V_ADP_PRIMARY].va_index = V_ADP_PRIMARY; + adapter[V_ADP_SECONDARY].va_index = V_ADP_SECONDARY; + +#if 0 + /* + * We cannot have two video adapter of the same type; there must be + * only one of color or mono adapter, or one each of them. + */ + if (adapters > 1) { + if (!((adapter[0].va_flags ^ adapter[1].va_flags) & V_ADP_COLOR)) + /* we have two mono or color adapters!! */ + return (adapters = 0); + } +#endif + + /* + * Ensure a zero start address. This is mainly to recover after + * switching from pcvt using userconfig(). The registers are w/o + * for old hardware so it's too hard to relocate the active screen + * memory. + * This must be done before vid_save_state() for VGA. + */ + outb(adapter[V_ADP_PRIMARY].va_crtc_addr, 12); + outb(adapter[V_ADP_PRIMARY].va_crtc_addr + 1, 0); + outb(adapter[V_ADP_PRIMARY].va_crtc_addr, 13); + outb(adapter[V_ADP_PRIMARY].va_crtc_addr + 1, 0); + + /* the video mode parameter table in EGA/VGA BIOS */ + /* NOTE: there can be only one EGA/VGA, wheather color or mono, + * recognized by the video BIOS. + */ + if ((adapter[V_ADP_PRIMARY].va_type == KD_EGA) || + (adapter[V_ADP_PRIMARY].va_type == KD_VGA)) { + adp = &adapter[V_ADP_PRIMARY]; + } else if ((adapter[V_ADP_SECONDARY].va_type == KD_EGA) || + (adapter[V_ADP_SECONDARY].va_type == KD_VGA)) { + adp = &adapter[V_ADP_SECONDARY]; + } else { + adp = NULL; + } + bzero(mode_map, sizeof(mode_map)); + if (adp != NULL) { + if (adp->va_type == KD_VGA) { + vid_save_state(adp - adapter, &adpstate, sizeof(adpstate)); + if (video_mode_ptr == NULL) { + mode_map[map_mode_num(adp->va_initial_mode)] = adpstate.regs; + rows_offset = 1; + } else { + /* discard the table if we are not familiar with it... */ + map_mode_table(mode_map, video_mode_ptr, M_VGA_CG320 + 1); + mp = get_mode_param(adp->va_initial_mode); + if (mp != NULL) + bcopy(mp, adpstate2.regs, sizeof(adpstate2.regs)); + switch (comp_adpregs(adpstate.regs, mp)) { + case COMP_IDENTICAL: + /* + * OK, this parameter table looks reasonably familiar + * to us... + */ + /* + * This is a kludge for Toshiba DynaBook SS433 + * whose BIOS video mode table entry has the actual # + * of rows at the offset 1; BIOSes from other + * manufacturers store the # of rows - 1 there. XXX + */ + rows_offset = adpstate.regs[1] + 1 - mp[1]; + break; + + case COMP_SIMILAR: + /* + * Not exactly the same, but similar enough to be + * trusted. However, use the saved register values + * for the initial mode and other modes which are + * based on the initial mode. + */ + mode_map[map_mode_num(adp->va_initial_mode)] = + adpstate.regs; + rows_offset = adpstate.regs[1] + 1 - mp[1]; + adpstate.regs[1] -= rows_offset - 1; + break; + + case COMP_DIFFERENT: + default: + /* + * Don't use the paramter table in BIOS. It doesn't + * look familiar to us. Video mode switching is allowed + * only if the new mode is the same as or based on + * the initial mode. + */ + video_mode_ptr = NULL; + bzero(mode_map, sizeof(mode_map)); + mode_map[map_mode_num(adp->va_initial_mode)] = + adpstate.regs; + rows_offset = 1; + break; + } + } + adp->va_flags |= V_ADP_MODECHANGE; + } else if (adp->va_type == KD_EGA) { + if (video_mode_ptr == NULL) { + adp->va_flags &= ~V_ADP_FONT; + rows_offset = 1; + } else { + map_mode_table(mode_map, video_mode_ptr, M_ENH_C80x25 + 1); + /* XXX how can one validate the EGA table... */ + mp = get_mode_param(adp->va_initial_mode); + if (mp != NULL) { + adp->va_flags |= V_ADP_MODECHANGE; + rows_offset = 1; + } else { + /* + * This is serious. We will not be able to switch video + * modes at all... + */ + adp->va_flags &= ~V_ADP_FONT; + video_mode_ptr = NULL; + bzero(mode_map, sizeof(mode_map)); + rows_offset = 1; + } + } + } + } + + /* remove conflicting modes if we have more than one adapter */ + if (adapters > 1) { + for (i = 0; i < adapters; ++i) { + if (!(adapter[i].va_flags & V_ADP_MODECHANGE)) + continue; + clear_mode_map(i, mode_map, M_VGA_CG320 + 1, + (adapter[i].va_flags & V_ADP_COLOR) ? + V_INFO_COLOR : 0); + } + } + + /* buffer address */ + vid_get_info(V_ADP_PRIMARY, + adapter[V_ADP_PRIMARY].va_initial_mode, &info); + adapter[V_ADP_PRIMARY].va_window = BIOS_PADDRTOVADDR(info.vi_window); + adapter[V_ADP_PRIMARY].va_window_size = info.vi_window_size; + adapter[V_ADP_PRIMARY].va_window_gran = info.vi_window_gran; + adapter[V_ADP_PRIMARY].va_buffer = BIOS_PADDRTOVADDR(info.vi_buffer); + adapter[V_ADP_PRIMARY].va_buffer_size = info.vi_buffer_size; + if (adapters > 1) { + vid_get_info(V_ADP_SECONDARY, + adapter[V_ADP_SECONDARY].va_initial_mode, &info); + adapter[V_ADP_SECONDARY].va_window = BIOS_PADDRTOVADDR(info.vi_window); + adapter[V_ADP_SECONDARY].va_window_size = info.vi_window_size; + adapter[V_ADP_SECONDARY].va_window_gran = info.vi_window_gran; + adapter[V_ADP_SECONDARY].va_buffer = BIOS_PADDRTOVADDR(info.vi_buffer); + adapter[V_ADP_SECONDARY].va_buffer_size = info.vi_buffer_size; + } + + /* + * XXX: we should verify the following values for the primary adapter... + * crtc I/O port address: *(u_int16_t *)BIOS_PADDRTOVADDR(0x463); + * color/mono display: (*(u_int8_t *)BIOS_PADDRTOVADDR(0x487) & 0x02) + * ? 0 : V_ADP_COLOR; + * columns: *(u_int8_t *)BIOS_PADDRTOVADDR(0x44a); + * rows: *(u_int8_t *)BIOS_PADDRTOVADDR(0x484); + * font size: *(u_int8_t *)BIOS_PADDRTOVADDR(0x485); + * buffer size: *(u_int16_t *)BIOS_PADDRTOVADDR(0x44c); + */ + + return adapters; +} + +/* all adapters */ +static video_adapter_t +*vid_adapter(int ad) +{ + if (!init_done) + return NULL; + if ((ad < 0) || (ad >= adapters)) + return NULL; + return &adapter[ad]; +} + +/* all adapters */ +static int +vid_get_info(int ad, int mode, video_info_t *info) +{ + int i; + + if (!init_done) + return 1; + if ((ad < 0) || (ad >= adapters)) + return 1; + + if (adapter[ad].va_flags & V_ADP_MODECHANGE) { + /* + * If the parameter table entry for this mode is not found, + * the mode is not supported... + */ + if (get_mode_param(mode) == NULL) + return 1; + } else { + /* + * Even if we don't support video mode switching on this adapter, + * the information on the initial (thus current) video mode + * should be made available. + */ + if (mode != adapter[ad].va_initial_mode) + return 1; + } + + for (i = 0; bios_vmode[i].vi_mode != EOT; ++i) { + if (bios_vmode[i].vi_mode == NA) + continue; + if (mode == bios_vmode[i].vi_mode) { + *info = bios_vmode[i]; + return 0; + } + } + return 1; +} + +/* all adapters */ +static int +vid_query_mode(int ad, video_info_t *info) +{ + video_info_t buf; + int i; + + if (!init_done) + return -1; + if ((ad < 0) || (ad >= adapters)) + return -1; + + for (i = 0; bios_vmode[i].vi_mode != EOT; ++i) { + if (bios_vmode[i].vi_mode == NA) + continue; + + if ((info->vi_width != 0) + && (info->vi_width != bios_vmode[i].vi_width)) + continue; + if ((info->vi_height != 0) + && (info->vi_height != bios_vmode[i].vi_height)) + continue; + if ((info->vi_cwidth != 0) + && (info->vi_cwidth != bios_vmode[i].vi_cwidth)) + continue; + if ((info->vi_cheight != 0) + && (info->vi_cheight != bios_vmode[i].vi_cheight)) + continue; + if ((info->vi_depth != 0) + && (info->vi_depth != bios_vmode[i].vi_depth)) + continue; + if ((info->vi_planes != 0) + && (info->vi_planes != bios_vmode[i].vi_planes)) + continue; + /* XXX: should check pixel format, memory model */ + if ((info->vi_flags != 0) + && (info->vi_flags != bios_vmode[i].vi_flags)) + continue; + + /* verify if this mode is supported on this adapter */ + if (vid_get_info(ad, bios_vmode[i].vi_mode, &buf)) + continue; + return bios_vmode[i].vi_mode; + } + return -1; +} + +/* EGA/VGA */ +static int +vid_set_mode(int ad, int mode) +{ + video_info_t info; + adp_state_t params; + + prologue(ad, V_ADP_MODECHANGE, 1); + + if (vid_get_info(ad, mode, &info)) + return 1; + params.sig = V_STATE_SIG; + bcopy(get_mode_param(mode), params.regs, sizeof(params.regs)); + + switch (mode) { + case M_VGA_C80x60: case M_VGA_M80x60: + params.regs[2] = 0x08; + params.regs[19] = 0x47; + goto special_480l; + + case M_VGA_C80x30: case M_VGA_M80x30: + params.regs[19] = 0x4f; +special_480l: + params.regs[9] |= 0xc0; + params.regs[16] = 0x08; + params.regs[17] = 0x3e; + params.regs[26] = 0xea; + params.regs[28] = 0xdf; + params.regs[31] = 0xe7; + params.regs[32] = 0x04; + goto setup_mode; + + case M_ENH_C80x43: case M_ENH_B80x43: + params.regs[28] = 87; + goto special_80x50; + + case M_VGA_C80x50: case M_VGA_M80x50: +special_80x50: + params.regs[2] = 8; + params.regs[19] = 7; + goto setup_mode; + + case M_VGA_C40x25: case M_VGA_C80x25: + case M_VGA_M80x25: + case M_B40x25: case M_C40x25: + case M_B80x25: case M_C80x25: + case M_ENH_B40x25: case M_ENH_C40x25: + case M_ENH_B80x25: case M_ENH_C80x25: + case M_EGAMONO80x25: + +setup_mode: + vid_load_state(ad, ¶ms); + break; + + case M_VGA_MODEX: + /* "unchain" the VGA mode */ + params.regs[5-1+0x04] &= 0xf7; + params.regs[5-1+0x04] |= 0x04; + /* turn off doubleword mode */ + params.regs[10+0x14] &= 0xbf; + /* turn off word adressing */ + params.regs[10+0x17] |= 0x40; + /* set logical screen width */ + params.regs[10+0x13] = 80; + /* set 240 lines */ + params.regs[10+0x11] = 0x2c; + params.regs[10+0x06] = 0x0d; + params.regs[10+0x07] = 0x3e; + params.regs[10+0x10] = 0xea; + params.regs[10+0x11] = 0xac; + params.regs[10+0x12] = 0xdf; + params.regs[10+0x15] = 0xe7; + params.regs[10+0x16] = 0x06; + /* set vertical sync polarity to reflect aspect ratio */ + params.regs[9] = 0xe3; + goto setup_grmode; + + case M_BG320: case M_CG320: case M_BG640: + case M_CG320_D: case M_CG640_E: + case M_CG640x350: case M_ENH_CG640: + case M_BG640x480: case M_CG640x480: case M_VGA_CG320: + +setup_grmode: + vid_load_state(ad, ¶ms); + break; + + default: + return 1; + } + + adapter[ad].va_mode = mode; + adapter[ad].va_flags &= ~V_ADP_COLOR; + adapter[ad].va_flags |= + (info.vi_flags & V_INFO_COLOR) ? V_ADP_COLOR : 0; + adapter[ad].va_crtc_addr = + (adapter[ad].va_flags & V_ADP_COLOR) ? COLOR_BASE : MONO_BASE; + adapter[ad].va_window = BIOS_PADDRTOVADDR(info.vi_window); + adapter[ad].va_window_size = info.vi_window_size; + adapter[ad].va_window_gran = info.vi_window_gran; + if (info.vi_buffer_size == 0) { + adapter[ad].va_buffer = 0; + adapter[ad].va_buffer_size = 0; + } else { + adapter[ad].va_buffer = BIOS_PADDRTOVADDR(info.vi_buffer); + adapter[ad].va_buffer_size = info.vi_buffer_size; + } + + return 0; +} + +static void +set_font_mode(video_adapter_t *adp, u_char *buf) +{ + u_char *mp; + int s; + + s = splhigh(); + + /* save register values */ + if (adp->va_type == KD_VGA) { + outb(TSIDX, 0x02); buf[0] = inb(TSREG); + outb(TSIDX, 0x04); buf[1] = inb(TSREG); + outb(GDCIDX, 0x04); buf[2] = inb(GDCREG); + outb(GDCIDX, 0x05); buf[3] = inb(GDCREG); + outb(GDCIDX, 0x06); buf[4] = inb(GDCREG); + inb(adp->va_crtc_addr + 6); + outb(ATC, 0x10); buf[5] = inb(ATC + 1); + } else /* if (adp->va_type == KD_EGA) */ { + /* + * EGA cannot be read; copy parameters from the mode parameter + * table. + */ + mp = get_mode_param(adp->va_mode); + buf[0] = mp[5 + 0x02 - 1]; + buf[1] = mp[5 + 0x04 - 1]; + buf[2] = mp[55 + 0x04]; + buf[3] = mp[55 + 0x05]; + buf[4] = mp[55 + 0x06]; + buf[5] = mp[35 + 0x10]; + } + + /* setup vga for loading fonts */ + inb(adp->va_crtc_addr + 6); /* reset flip-flop */ + outb(ATC, 0x10); outb(ATC, buf[5] & ~0x01); + inb(adp->va_crtc_addr + 6); /* reset flip-flop */ + outb(ATC, 0x20); /* enable palette */ + +#if SLOW_VGA +#ifndef SC_BAD_FLICKER + outb(TSIDX, 0x00); outb(TSREG, 0x01); +#endif + outb(TSIDX, 0x02); outb(TSREG, 0x04); + outb(TSIDX, 0x04); outb(TSREG, 0x07); +#ifndef SC_BAD_FLICKER + outb(TSIDX, 0x00); outb(TSREG, 0x03); +#endif + outb(GDCIDX, 0x04); outb(GDCREG, 0x02); + outb(GDCIDX, 0x05); outb(GDCREG, 0x00); + outb(GDCIDX, 0x06); outb(GDCREG, 0x04); +#else +#ifndef SC_BAD_FLICKER + outw(TSIDX, 0x0100); +#endif + outw(TSIDX, 0x0402); + outw(TSIDX, 0x0704); +#ifndef SC_BAD_FLICKER + outw(TSIDX, 0x0300); +#endif + outw(GDCIDX, 0x0204); + outw(GDCIDX, 0x0005); + outw(GDCIDX, 0x0406); /* addr = a0000, 64kb */ +#endif + + splx(s); +} + +static void +set_normal_mode(video_adapter_t *adp, u_char *buf) +{ + int s; + + s = splhigh(); + + /* setup vga for normal operation mode again */ + inb(adp->va_crtc_addr + 6); /* reset flip-flop */ + outb(ATC, 0x10); outb(ATC, buf[5]); + inb(adp->va_crtc_addr + 6); /* reset flip-flop */ + outb(ATC, 0x20); /* enable palette */ + +#if SLOW_VGA +#ifndef SC_BAD_FLICKER + outb(TSIDX, 0x00); outb(TSREG, 0x01); +#endif + outb(TSIDX, 0x02); outb(TSREG, buf[0]); + outb(TSIDX, 0x04); outb(TSREG, buf[1]); +#ifndef SC_BAD_FLICKER + outb(TSIDX, 0x00); outb(TSREG, 0x03); +#endif + outb(GDCIDX, 0x04); outb(GDCREG, buf[2]); + outb(GDCIDX, 0x05); outb(GDCREG, buf[3]); + if (adp->va_crtc_addr == MONO_BASE) { + outb(GDCIDX, 0x06); outb(GDCREG,(buf[4] & 0x03) | 0x08); + } else { + outb(GDCIDX, 0x06); outb(GDCREG,(buf[4] & 0x03) | 0x0c); + } +#else +#ifndef SC_BAD_FLICKER + outw(TSIDX, 0x0100); +#endif + outw(TSIDX, 0x0002 | (buf[0] << 8)); + outw(TSIDX, 0x0004 | (buf[1] << 8)); +#ifndef SC_BAD_FLICKER + outw(TSIDX, 0x0300); +#endif + outw(GDCIDX, 0x0004 | (buf[2] << 8)); + outw(GDCIDX, 0x0005 | (buf[3] << 8)); + if (adp->va_crtc_addr == MONO_BASE) + outw(GDCIDX, 0x0006 | (((buf[4] & 0x03) | 0x08)<<8)); + else + outw(GDCIDX, 0x0006 | (((buf[4] & 0x03) | 0x0c)<<8)); +#endif + + splx(s); +} + +/* EGA/VGA */ +static int +vid_save_font(int ad, int page, int fontsize, u_char *data, int ch, int count) +{ + u_char buf[PARAM_BUFSIZE]; + u_char val = 0; + u_int32_t segment; + int c; + int s; + + prologue(ad, V_ADP_FONT, 1); + + if (fontsize < 14) { + /* FONT_8 */ + fontsize = 8; + } else if (fontsize >= 32) { + fontsize = 32; + } else if (fontsize >= 16) { + /* FONT_16 */ + fontsize = 16; + } else { + /* FONT_14 */ + fontsize = 14; + } + + if (page < 0 || page >= 8) + return 1; + segment = VIDEOMEM + 0x4000*page; + if (page > 3) + segment -= 0xe000; + + if (adapter[ad].va_type == KD_VGA) { /* what about EGA? XXX */ + s = splhigh(); + outb(TSIDX, 0x00); outb(TSREG, 0x01); + outb(TSIDX, 0x01); val = inb(TSREG); /* disable screen */ + outb(TSIDX, 0x01); outb(TSREG, val | 0x20); + outb(TSIDX, 0x00); outb(TSREG, 0x03); + splx(s); + } + + set_font_mode(&adapter[ad], buf); + if (fontsize == 32) { + generic_bcopy((void *)BIOS_PADDRTOVADDR(segment + ch*32), data, + fontsize*count); + } else { + for (c = ch; count > 0; ++c, --count) { + generic_bcopy((void *)BIOS_PADDRTOVADDR(segment + c*32), data, + fontsize); + data += fontsize; + } + } + set_normal_mode(&adapter[ad], buf); + + if (adapter[ad].va_type == KD_VGA) { + s = splhigh(); + outb(TSIDX, 0x00); outb(TSREG, 0x01); + outb(TSIDX, 0x01); outb(TSREG, val & 0xdf); /* enable screen */ + outb(TSIDX, 0x00); outb(TSREG, 0x03); + splx(s); + } + + return 0; +} + +/* EGA/VGA */ +static int +vid_load_font(int ad, int page, int fontsize, u_char *data, int ch, int count) +{ + u_char buf[PARAM_BUFSIZE]; + u_char val = 0; + u_int32_t segment; + int c; + int s; + + prologue(ad, V_ADP_FONT, 1); + + if (fontsize < 14) { + /* FONT_8 */ + fontsize = 8; + } else if (fontsize >= 32) { + fontsize = 32; + } else if (fontsize >= 16) { + /* FONT_16 */ + fontsize = 16; + } else { + /* FONT_14 */ + fontsize = 14; + } + + if (page < 0 || page >= 8) + return 1; + segment = VIDEOMEM + 0x4000*page; + if (page > 3) + segment -= 0xe000; + + if (adapter[ad].va_type == KD_VGA) { /* what about EGA? XXX */ + s = splhigh(); + outb(TSIDX, 0x00); outb(TSREG, 0x01); + outb(TSIDX, 0x01); val = inb(TSREG); /* disable screen */ + outb(TSIDX, 0x01); outb(TSREG, val | 0x20); + outb(TSIDX, 0x00); outb(TSREG, 0x03); + splx(s); + } + + set_font_mode(&adapter[ad], buf); + if (fontsize == 32) { + generic_bcopy(data, (void *)BIOS_PADDRTOVADDR(segment + ch*32), + fontsize*count); + } else { + for (c = ch; count > 0; ++c, --count) { + generic_bcopy(data, (void *)BIOS_PADDRTOVADDR(segment + c*32), + fontsize); + data += fontsize; + } + } + set_normal_mode(&adapter[ad], buf); + + if (adapter[ad].va_type == KD_VGA) { + s = splhigh(); + outb(TSIDX, 0x00); outb(TSREG, 0x01); + outb(TSIDX, 0x01); outb(TSREG, val & 0xdf); /* enable screen */ + outb(TSIDX, 0x00); outb(TSREG, 0x03); + splx(s); + } + + return 0; +} + +/* EGA/VGA */ +static int +vid_show_font(int ad, int page) +{ + static u_char cg[] = { 0x00, 0x05, 0x0a, 0x0f, 0x30, 0x35, 0x3a, 0x3f }; + int s; + + prologue(ad, V_ADP_FONT, 1); + if (page < 0 || page >= 8) + return 1; + + s = splhigh(); + outb(TSIDX, 0x03); outb(TSREG, cg[page]); + splx(s); + + return 0; +} + +/* VGA */ +static int +vid_save_palette(int ad, u_char *palette) +{ + int i; + + prologue(ad, V_ADP_PALETTE, 1); + + /* + * We store 8 bit values in the palette buffer, while the standard + * VGA has 6 bit DAC . + */ + outb(PALRADR, 0x00); + for (i = 0; i < 256*3; ++i) + palette[i] = inb(PALDATA) << 2; + inb(adapter[ad].va_crtc_addr + 6); /* reset flip/flop */ + return 0; +} + +/* VGA */ +static int +vid_load_palette(int ad, u_char *palette) +{ + int i; + + prologue(ad, V_ADP_PALETTE, 1); + + outb(PIXMASK, 0xff); /* no pixelmask */ + outb(PALWADR, 0x00); + for (i = 0; i < 256*3; ++i) + outb(PALDATA, palette[i] >> 2); + inb(adapter[ad].va_crtc_addr + 6); /* reset flip/flop */ + outb(ATC, 0x20); /* enable palette */ + return 0; +} + +/* CGA/EGA/VGA */ +static int +vid_set_border(int ad, int color) +{ + prologue(ad, V_ADP_BORDER, 1); + + switch (adapter[ad].va_type) { + case KD_EGA: + case KD_VGA: + inb(adapter[ad].va_crtc_addr + 6); /* reset flip-flop */ + outb(ATC, 0x31); outb(ATC, color & 0xff); + break; + case KD_CGA: + outb(adapter[ad].va_crtc_addr + 5, color & 0x0f); /* color select register */ + break; + case KD_MONO: + case KD_HERCULES: + default: + break; + } + return 0; +} + +/* VGA */ +static int +vid_save_state(int ad, void *p, size_t size) +{ + video_info_t info; + u_char *buf; + int crtc_addr; + int i, j; + int s; + + if (size == 0) { + /* return the required buffer size */ + prologue(ad, V_ADP_STATESAVE, 0); + return sizeof(adp_state_t); + } else { + prologue(ad, V_ADP_STATESAVE, 1); + if (size < sizeof(adp_state_t)) + return 1; + } + + ((adp_state_t *)p)->sig = V_STATE_SIG; + buf = ((adp_state_t *)p)->regs; + bzero(buf, V_MODE_PARAM_SIZE); + crtc_addr = adapter[ad].va_crtc_addr; + + s = splhigh(); + + outb(TSIDX, 0x00); outb(TSREG, 0x01); /* stop sequencer */ + for (i = 0, j = 5; i < 4; i++) { + outb(TSIDX, i + 1); + buf[j++] = inb(TSREG); + } + buf[9] = inb(MISC + 10); /* dot-clock */ + outb(TSIDX, 0x00); outb(TSREG, 0x03); /* start sequencer */ + + for (i = 0, j = 10; i < 25; i++) { /* crtc */ + outb(crtc_addr, i); + buf[j++] = inb(crtc_addr + 1); + } + for (i = 0, j = 35; i < 20; i++) { /* attribute ctrl */ + inb(crtc_addr + 6); /* reset flip-flop */ + outb(ATC, i); + buf[j++] = inb(ATC + 1); + } + for (i = 0, j = 55; i < 9; i++) { /* graph data ctrl */ + outb(GDCIDX, i); + buf[j++] = inb(GDCREG); + } + inb(crtc_addr + 6); /* reset flip-flop */ + outb(ATC, 0x20); /* enable palette */ + + splx(s); + +#if 1 + if (vid_get_info(ad, adapter[ad].va_mode, &info) == 0) { + if (info.vi_flags & V_INFO_GRAPHICS) { + buf[0] = info.vi_width/info.vi_cwidth; /* COLS */ + buf[1] = info.vi_height/info.vi_cheight - 1; /* ROWS */ + } else { + buf[0] = info.vi_width; /* COLS */ + buf[1] = info.vi_height - 1; /* ROWS */ + } + buf[2] = info.vi_cheight; /* POINTS */ + } else { + /* XXX: shouldn't be happening... */ + printf("video#%d: failed to obtain mode info. (vid_save_state())\n", + ad); + } +#else + buf[0] = *(u_int8_t *)BIOS_PADDRTOVADDR(0x44a); /* COLS */ + buf[1] = *(u_int8_t *)BIOS_PADDRTOVADDR(0x484); /* ROWS */ + buf[2] = *(u_int8_t *)BIOS_PADDRTOVADDR(0x485); /* POINTS */ + buf[3] = *(u_int8_t *)BIOS_PADDRTOVADDR(0x44c); + buf[4] = *(u_int8_t *)BIOS_PADDRTOVADDR(0x44d); +#endif + + return 0; +} + +/* EGA/VGA */ +static int +vid_load_state(int ad, void *p) +{ + u_char *buf; + int crtc_addr; + int s; + int i; + + prologue(ad, V_ADP_STATELOAD, 1); + if (((adp_state_t *)p)->sig != V_STATE_SIG) + return 1; + + buf = ((adp_state_t *)p)->regs; + crtc_addr = adapter[ad].va_crtc_addr; + + s = splhigh(); + + outb(TSIDX, 0x00); outb(TSREG, 0x01); /* stop sequencer */ + for (i = 0; i < 4; ++i) { /* program sequencer */ + outb(TSIDX, i + 1); + outb(TSREG, buf[i + 5]); + } + outb(MISC, buf[9]); /* set dot-clock */ + outb(TSIDX, 0x00); outb(TSREG, 0x03); /* start sequencer */ + outb(crtc_addr, 0x11); + outb(crtc_addr + 1, inb(crtc_addr + 1) & 0x7F); + for (i = 0; i < 25; ++i) { /* program crtc */ + outb(crtc_addr, i); + outb(crtc_addr + 1, buf[i + 10]); + } + inb(crtc_addr+6); /* reset flip-flop */ + for (i = 0; i < 20; ++i) { /* program attribute ctrl */ + outb(ATC, i); + outb(ATC, buf[i + 35]); + } + for (i = 0; i < 9; ++i) { /* program graph data ctrl */ + outb(GDCIDX, i); + outb(GDCREG, buf[i + 55]); + } + inb(crtc_addr + 6); /* reset flip-flop */ + outb(ATC, 0x20); /* enable palette */ + + if (ad == V_ADP_PRIMARY) { + *(u_int8_t *)BIOS_PADDRTOVADDR(0x44a) = buf[0]; /* COLS */ + *(u_int8_t *)BIOS_PADDRTOVADDR(0x484) = buf[1] + rows_offset - 1; /* ROWS */ + *(u_int8_t *)BIOS_PADDRTOVADDR(0x485) = buf[2]; /* POINTS */ +#if 0 + *(u_int8_t *)BIOS_PADDRTOVADDR(0x44c) = buf[3]; + *(u_int8_t *)BIOS_PADDRTOVADDR(0x44d) = buf[4]; +#endif + } + + splx(s); + return 0; +} + +/* all */ +static int +vid_set_origin(int ad, off_t offset) +{ + /* + * The standard video modes do not require window mapping; + * always return error. + */ + return 1; +} + +/* all */ +static int +vid_read_hw_cursor(int ad, int *col, int *row) +{ + video_info_t info; + u_int16_t off; + + if (!init_done) + return 1; + if ((ad < 0) || (ad >= adapters)) + return 1; + + (*biosvidsw.get_info)(ad, adapter[ad].va_mode, &info); + if (info.vi_flags & V_INFO_GRAPHICS) + return 1; + + outb(adapter[ad].va_crtc_addr, 14); + off = inb(adapter[ad].va_crtc_addr + 1); + outb(adapter[ad].va_crtc_addr, 15); + off = (off << 8) | inb(adapter[ad].va_crtc_addr + 1); + + *row = off / info.vi_width; + *col = off % info.vi_width; + + return 0; +} + +/* all */ +static int +vid_set_hw_cursor(int ad, int col, int row) +{ + video_info_t info; + u_int16_t off; + + if (!init_done) + return 1; + if ((ad < 0) || (ad >= adapters)) + return 1; + + (*biosvidsw.get_info)(ad, adapter[ad].va_mode, &info); + if (info.vi_flags & V_INFO_GRAPHICS) + return 1; + + if ((col == -1) || (row == -1)) + off = 0xffff; + else + off = row*info.vi_width + col; + outb(adapter[ad].va_crtc_addr, 14); + outb(adapter[ad].va_crtc_addr + 1, off >> 8); + outb(adapter[ad].va_crtc_addr, 15); + outb(adapter[ad].va_crtc_addr + 1, off & 0x00ff); + + return 0; +} + +static char +*adapter_name(int type) +{ + static struct { + int type; + char *name; + } names[] = { + { KD_MONO, "MDA" }, + { KD_HERCULES, "Hercules" }, + { KD_CGA, "CGA" }, + { KD_EGA, "EGA" }, + { KD_VGA, "VGA" }, + { KD_PC98, "PC-98xx" }, + { -1, "Unknown" }, + }; + int i; + + for (i = 0; names[i].type != -1; ++i) + if (names[i].type == type) + break; + return names[i].name; +} + +static void +dump_adp_info(int ad, video_adapter_t *adp, int level) +{ + if (level <= 0) + return; + + printf("video#%d: adapter type:%s (%d), flags:0x%x, CRTC:0x%x\n", + ad, adapter_name(adp->va_type), adp->va_type, + adp->va_flags, adp->va_crtc_addr); + printf("video#%d: init mode:%d, bios mode:%d, current mode:%d\n", + ad, adp->va_initial_mode, adp->va_initial_bios_mode, adp->va_mode); + printf("video#%d: window:0x%x size:%dk gran:%dk, buf:0x%x size:%dk\n", + ad, + adp->va_window, adp->va_window_size, adp->va_window_gran, + adp->va_buffer, adp->va_buffer_size); +} + +static void +dump_mode_info(int ad, video_info_t *info, int level) +{ + if (level <= 0) + return; + + printf("video#%d: mode:%d, flags:0x%x ", + ad, info->vi_mode, info->vi_flags); + if (info->vi_flags & V_INFO_GRAPHICS) + printf("G %dx%dx%d, %d plane(s), font:%dx%d, ", + info->vi_width, info->vi_height, + info->vi_depth, info->vi_planes, + info->vi_cwidth, info->vi_cheight); + else + printf("T %dx%d, font:%dx%d, ", + info->vi_width, info->vi_height, + info->vi_cwidth, info->vi_cheight); + printf("win:0x%x\n", info->vi_window); +} + +static void +dump_buffer(u_char *buf, size_t len) +{ + int i; + + for(i = 0; i < len;) { + printf("%02x ", buf[i]); + if ((++i % 16) == 0) + printf("\n"); + } +} + +static int +vid_diag(int level) +{ + video_info_t info; + u_char *mp; + int ad; + int i; + + if (!init_done) + return 1; + + if (level > 0) { + printf("video: RTC equip. code:0x%02x, DCC code:0x%02x\n", + rtcin(RTC_EQUIPMENT), *(u_int8_t *)BIOS_PADDRTOVADDR(0x488)); + printf("video: CRTC:0x%x, video option:0x%02x, ", + *(u_int16_t *)BIOS_PADDRTOVADDR(0x463), + *(u_int8_t *)BIOS_PADDRTOVADDR(0x487)); + printf("rows:%d, cols:%d, font height:%d\n", + *(u_int8_t *)BIOS_PADDRTOVADDR(0x44a), + *(u_int8_t *)BIOS_PADDRTOVADDR(0x484) + 1, + *(u_int8_t *)BIOS_PADDRTOVADDR(0x485)); + printf("video: param table EGA/VGA:%p, CGA/MDA:%p\n", + video_mode_ptr, video_mode_ptr2); + printf("video: rows_offset:%d\n", rows_offset); + } + + for (ad = 0; ad < adapters; ++ad) { + dump_adp_info(ad, &adapter[ad], level); + + if (!(adapter[ad].va_flags & V_ADP_MODECHANGE)) { + vid_get_info(ad, adapter[ad].va_initial_mode, &info); + dump_mode_info(ad, &info, level); + } else { + for (i = 0; bios_vmode[i].vi_mode != EOT; ++i) { + if (bios_vmode[i].vi_mode == NA) + continue; + if (get_mode_param(bios_vmode[i].vi_mode) == NULL) + continue; + dump_mode_info(ad, &bios_vmode[i], level); + } + } + if ((adapter[ad].va_type != KD_EGA) && (adapter[ad].va_type != KD_VGA)) + continue; + + if (video_mode_ptr == NULL) + printf("video#%d: WARNING: video mode switching is not fully supported on this adapter\n", ad); + + if (level <= 0) + continue; + + if (adapter[ad].va_type == KD_VGA) { + printf("VGA parameters upon power-up\n"); + dump_buffer(adpstate.regs, sizeof(adpstate.regs)); + printf("VGA parameters in BIOS for mode %d\n", + adapter[ad].va_initial_mode); + dump_buffer(adpstate2.regs, sizeof(adpstate2.regs)); + } + + mp = get_mode_param(adapter[ad].va_initial_mode); + if (mp == NULL) /* this shouldn't be happening */ + continue; + printf("EGA/VGA parameters to be used for mode %d\n", + adapter[ad].va_initial_mode); + dump_buffer(mp, V_MODE_PARAM_SIZE); + } + + return 0; +} + +#endif /* NSC > 0 */ diff --git a/sys/i386/isa/videoio.h b/sys/i386/isa/videoio.h new file mode 100644 index 000000000000..74d17d0bf0ec --- /dev/null +++ b/sys/i386/isa/videoio.h @@ -0,0 +1,107 @@ +/*- + * Copyright (c) 1998 Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#ifndef _I386_ISA_VIDEOIO_H_ +#define _I386_ISA_VIDEOIO_H_ + +#ifdef KERNEL + +#define V_MAX_ADAPTERS 2 + +#define V_MODE_MAP_SIZE (M_VGA_CG320 + 1) +#define V_MODE_PARAM_SIZE 64 + +/* physical addresses */ +#define MONO_BUF BIOS_PADDRTOVADDR(0xb0000) +#define CGA_BUF BIOS_PADDRTOVADDR(0xb8000) +#define GRAPHICS_BUF BIOS_PADDRTOVADDR(0xa0000) +#define VIDEOMEM 0x000A0000 + +/* I/O port addresses */ +#define MONO_BASE 0x3B4 /* crt controller base mono */ +#define COLOR_BASE 0x3D4 /* crt controller base color */ +#define MISC 0x3C2 /* misc output register */ +#define ATC IO_VGA+0x00 /* attribute controller */ +#define TSIDX IO_VGA+0x04 /* timing sequencer idx */ +#define TSREG IO_VGA+0x05 /* timing sequencer data */ +#define PIXMASK IO_VGA+0x06 /* pixel write mask */ +#define PALRADR IO_VGA+0x07 /* palette read address */ +#define PALWADR IO_VGA+0x08 /* palette write address */ +#define PALDATA IO_VGA+0x09 /* palette data register */ +#define GDCIDX IO_VGA+0x0E /* graph data controller idx */ +#define GDCREG IO_VGA+0x0F /* graph data controller data */ + +/* video function table */ +typedef int vi_init_t(void); +typedef video_adapter_t *vi_adapter_t(int ad); +typedef int vi_get_info_t(int ad, int mode, video_info_t *info); +typedef int vi_query_mode_t(int ad, video_info_t *info); +typedef int vi_set_mode_t(int ad, int mode); +typedef int vi_save_font_t(int ad, int page, int size, u_char *data, + int c, int count); +typedef int vi_load_font_t(int ad, int page, int size, u_char *data, + int c, int count); +typedef int vi_show_font_t(int ad, int page); +typedef int vi_save_palette_t(int ad, u_char *palette); +typedef int vi_load_palette_t(int ad, u_char *palette); +typedef int vi_set_border_t(int ad, int border); +typedef int vi_save_state_t(int ad, void *p, size_t size); +typedef int vi_load_state_t(int ad, void *p); +typedef int vi_set_win_org_t(int ad, off_t offset); +typedef int vi_read_hw_cursor_t(int ad, int *col, int *row); +typedef int vi_set_hw_cursor_t(int ad, int col, int row); +typedef int vi_diag_t(int level); + +struct vidsw { + vi_init_t *init; /* all */ + vi_adapter_t *adapter; /* all */ + vi_get_info_t *get_info; /* all */ + vi_query_mode_t *query_mode; /* all */ + vi_set_mode_t *set_mode; /* EGA/VGA */ + vi_save_font_t *save_font; /* EGA/VGA */ + vi_load_font_t *load_font; /* EGA/VGA */ + vi_show_font_t *show_font; /* EGA/VGA */ + vi_save_palette_t *save_palette; /* VGA */ + vi_load_palette_t *load_palette; /* VGA */ + vi_set_border_t *set_border; /* CGA/EGA/VGA */ + vi_save_state_t *save_state; /* VGA */ + vi_load_state_t *load_state; /* EGA/VGA */ + vi_set_win_org_t *set_win_org; /* all */ + vi_read_hw_cursor_t *read_hw_cursor; /* all */ + vi_set_hw_cursor_t *set_hw_cursor; /* all */ + vi_diag_t *diag; /* all */ +}; + +extern struct vidsw biosvidsw; + +#endif /* KERNEL */ + +#endif /* !_I386_ISA_VIDEOIO_H_ */ diff --git a/sys/i386/isa/wst.c b/sys/i386/isa/wst.c index 390eb2c35efb..ff5f5435f31e 100644 --- a/sys/i386/isa/wst.c +++ b/sys/i386/isa/wst.c @@ -6,13 +6,13 @@ * 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: wst.c,v 1.10 1998/08/24 02:28:16 bde Exp $ + * $Id$ */ #include "wdc.h" diff --git a/sys/modules/syscons/blank/blank_saver.c b/sys/modules/syscons/blank/blank_saver.c index 451dc9a4b241..d5f4cf0bf560 100644 --- a/sys/modules/syscons/blank/blank_saver.c +++ b/sys/modules/syscons/blank/blank_saver.c @@ -1,18 +1,18 @@ /*- - * Copyright (c) 1995 Søren Schmidt + * Copyright (c) 1995-1998 Søren Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. + * notice, this list of conditions and the following disclaimer, + * without modification, immediately at the beginning of the file. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products - * derived from this software 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,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: blank_saver.c,v 1.10 1997/07/15 14:49:09 yokota Exp $ + * $Id$ */ #include diff --git a/sys/modules/syscons/daemon/daemon_saver.c b/sys/modules/syscons/daemon/daemon_saver.c index f3cf3dce7736..688df41f274a 100644 --- a/sys/modules/syscons/daemon/daemon_saver.c +++ b/sys/modules/syscons/daemon/daemon_saver.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: daemon_saver.c,v 1.8 1998/01/16 17:58:43 bde Exp $ + * $Id: daemon_saver.c,v 1.9 1998/08/06 09:14:20 yokota Exp $ */ #include @@ -205,7 +205,7 @@ daemon_saver(int blank) /* clear the screen and set the border color */ fillw(((FG_LIGHTGREY|BG_BLACK) << 8) | scr_map[0x20], Crtat, scp->xsize * scp->ysize); - set_border(0); + set_border(scp, 0); xlen = ylen = tlen = 0; } if (scrn_blanked++ < 2) @@ -322,7 +322,7 @@ daemon_saver(int blank) draw_string(txpos, typos, toff, (char *)message, tlen); } else { if (scrn_blanked > 0) { - set_border(scp->border); + set_border(scp, scp->border); scrn_blanked = 0; } } diff --git a/sys/modules/syscons/fade/fade_saver.c b/sys/modules/syscons/fade/fade_saver.c index 341f7e8d240c..41176e76e092 100644 --- a/sys/modules/syscons/fade/fade_saver.c +++ b/sys/modules/syscons/fade/fade_saver.c @@ -1,18 +1,18 @@ /*- - * Copyright (c) 1995-1997 Søren Schmidt + * Copyright (c) 1995-1998 Søren Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. + * notice, this list of conditions and the following disclaimer, + * without modification, immediately at the beginning of the file. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products - * derived from this software 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,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: fade_saver.c,v 1.11 1997/07/15 14:49:25 yokota Exp $ + * $Id$ */ #include @@ -84,7 +84,7 @@ fade_saver(int blank) else { switch (crtc_type) { case KD_VGA: - load_palette(palette); + load_palette(cur_console, palette); count = 0; break; case KD_EGA: diff --git a/sys/modules/syscons/green/green_saver.c b/sys/modules/syscons/green/green_saver.c index b8c82958ac34..667866284681 100644 --- a/sys/modules/syscons/green/green_saver.c +++ b/sys/modules/syscons/green/green_saver.c @@ -1,18 +1,18 @@ /*- - * Copyright (c) 1995 Søren Schmidt + * Copyright (c) 1995-1998 Søren Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. + * notice, this list of conditions and the following disclaimer, + * without modification, immediately at the beginning of the file. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products - * derived from this software 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,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: green_saver.c,v 1.10 1997/07/15 14:49:29 yokota Exp $ + * $Id$ */ #include diff --git a/sys/modules/syscons/saver.h b/sys/modules/syscons/saver.h index 7118e4588e22..96cc010e9b81 100644 --- a/sys/modules/syscons/saver.h +++ b/sys/modules/syscons/saver.h @@ -1,18 +1,18 @@ /*- - * Copyright (c) 1995-1997 Søren Schmidt + * Copyright (c) 1995-1998 Søren Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. + * notice, this list of conditions and the following disclaimer, + * without modification, immediately at the beginning of the file. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products - * derived from this software 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,12 +25,12 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: saver.h,v 1.9 1997/07/15 14:48:11 yokota Exp $ + * $Id$ */ - #include #include +#include #include extern scr_stat *cur_console; diff --git a/sys/modules/syscons/snake/snake_saver.c b/sys/modules/syscons/snake/snake_saver.c index c3fa1fe7ce38..c5011d04bac2 100644 --- a/sys/modules/syscons/snake/snake_saver.c +++ b/sys/modules/syscons/snake/snake_saver.c @@ -1,18 +1,18 @@ /*- - * Copyright (c) 1995 Søren Schmidt + * Copyright (c) 1995-1998 Søren Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. + * notice, this list of conditions and the following disclaimer, + * without modification, immediately at the beginning of the file. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products - * derived from this software 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,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: snake_saver.c,v 1.16 1998/01/16 17:58:50 bde Exp $ + * $Id$ */ #include @@ -63,7 +63,7 @@ snake_saver(int blank) if (scrn_blanked <= 0) { fillw((FG_LIGHTGREY|BG_BLACK)<<8 | scr_map[0x20], Crtat, scp->xsize * scp->ysize); - set_border(0); + set_border(scp, 0); dirx = (scp->xpos ? 1 : -1); diry = (scp->ypos ? scp->xsize : -scp->xsize); @@ -99,7 +99,7 @@ snake_saver(int blank) } else { if (scrn_blanked > 0) { - set_border(scp->border); + set_border(scp, scp->border); scrn_blanked = 0; } } diff --git a/sys/modules/syscons/star/star_saver.c b/sys/modules/syscons/star/star_saver.c index 517a5579968f..8ac65bdba71c 100644 --- a/sys/modules/syscons/star/star_saver.c +++ b/sys/modules/syscons/star/star_saver.c @@ -1,18 +1,18 @@ /*- - * Copyright (c) 1995 Søren Schmidt + * Copyright (c) 1995-1998 Søren Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. + * notice, this list of conditions and the following disclaimer, + * without modification, immediately at the beginning of the file. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products - * derived from this software 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,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: star_saver.c,v 1.13 1998/01/16 17:58:55 bde Exp $ + * $Id$ */ #include @@ -62,7 +62,7 @@ star_saver(int blank) scrn_blanked = 1; fillw((FG_LIGHTGREY|BG_BLACK)<<8|scr_map[0x20], Crtat, scp->xsize * scp->ysize); - set_border(0); + set_border(scp, 0); for(i=0; ixsize*scp->ysize); @@ -80,7 +80,7 @@ star_saver(int blank) } else { if (scrn_blanked > 0) { - set_border(scp->border); + set_border(scp, scp->border); scrn_blanked = 0; } } diff --git a/sys/pc98/pc98/wst.c b/sys/pc98/pc98/wst.c index 390eb2c35efb..ff5f5435f31e 100644 --- a/sys/pc98/pc98/wst.c +++ b/sys/pc98/pc98/wst.c @@ -6,13 +6,13 @@ * 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: wst.c,v 1.10 1998/08/24 02:28:16 bde Exp $ + * $Id$ */ #include "wdc.h" diff --git a/usr.sbin/vidcontrol/vidcontrol.1 b/usr.sbin/vidcontrol/vidcontrol.1 index aea546717aec..f4c9d211a55c 100644 --- a/usr.sbin/vidcontrol/vidcontrol.1 +++ b/usr.sbin/vidcontrol/vidcontrol.1 @@ -11,7 +11,7 @@ .\" documentation and/or other materials provided with the distribution. .\" .\" @(#)vidcontrol.1 -.\" $Id: vidcontrol.1,v 1.11 1997/07/24 23:46:35 wosch Exp $ +.\" $Id: vidcontrol.1,v 1.12 1997/10/27 07:52:08 charnier Exp $ .\" .Dd May 22, 1994 .Dt VIDCONTROL 1 @@ -25,6 +25,7 @@ .Op Fl b Ar color .Op Fl c Ar appearance .Op Fl d +.Op Fl i Ar adapter|mode .Op Fl l Ar scrmap .Op Fl L .Op Fl m Ar on|off @@ -84,6 +85,10 @@ Install screen output map file from .Ar scrmap .It Fl L Install default screen output map. +.It Fl i Ar adapter +Shows info about the current videoadapter. +.It Fl i Ar mode +Shows the possible videomodes with the current video hardware. .It Fl m Ar on|off Switch the mousepointer .Ar on diff --git a/usr.sbin/vidcontrol/vidcontrol.c b/usr.sbin/vidcontrol/vidcontrol.c index 81f13da223e9..4c97cabf2166 100644 --- a/usr.sbin/vidcontrol/vidcontrol.c +++ b/usr.sbin/vidcontrol/vidcontrol.c @@ -28,7 +28,7 @@ #ifndef lint static const char rcsid[] = - "$Id: vidcontrol.c,v 1.18 1997/10/27 07:52:10 charnier Exp $"; + "$Id: vidcontrol.c,v 1.19 1998/07/14 10:32:27 bde Exp $"; #endif /* not lint */ #include @@ -259,6 +259,7 @@ void video_mode(int argc, char **argv, int *index) { unsigned long mode; + int size[3]; if (*index < argc) { if (!strcmp(argv[*index], "VGA_40x25")) @@ -277,10 +278,27 @@ video_mode(int argc, char **argv, int *index) mode = SW_ENH_C80x25; else if (!strcmp(argv[*index], "EGA_80x43")) mode = SW_ENH_C80x43; + else if (!strcmp(argv[*index], "VESA_132x25")) + mode = SW_VESA_C132x25; + else if (!strcmp(argv[*index], "VESA_132x43")) + mode = SW_VESA_C132x43; + else if (!strcmp(argv[*index], "VESA_132x50")) + mode = SW_VESA_C132x50; + else if (!strcmp(argv[*index], "VESA_132x60")) + mode = SW_VESA_C132x60; + else if (!strcmp(argv[*index], "VESA_800x600")) + mode = SW_VESA_800x600; else return; if (ioctl(0, mode, NULL) < 0) warn("cannot set videomode"); + if (mode == SW_VESA_800x600) { + size[0] = 80; /* columns */ + size[1] = 25; /* rows */ + size[2] = 16; /* font size */ + if (ioctl(0, KDRASTER, size)) + warn("cannot activate raster display"); + } (*index)++; } return; @@ -375,6 +393,103 @@ set_mouse(char *arg) ioctl(0, CONS_MOUSECTL, &mouse); } +static char +*adapter_name(int type) +{ + static struct { + int type; + char *name; + } names[] = { + { KD_MONO, "MDA" }, + { KD_HERCULES, "Hercules" }, + { KD_CGA, "CGA" }, + { KD_EGA, "EGA" }, + { KD_VGA, "VGA" }, + { KD_PC98, "PC-98xx" }, + { -1, "Unknown" }, + }; + int i; + + for (i = 0; names[i].type != -1; ++i) + if (names[i].type == type) + break; + return names[i].name; +} + +void +show_adapter_info(void) +{ + struct video_adapter ad; + + ad.va_index = 0; + if (ioctl(0, CONS_ADPINFO, &ad)) { + warn("failed to obtain adapter information"); + return; + } + + printf("adapter %d:\n", ad.va_index); + printf(" type:%s%s (%d), flags:0x%08x, CRTC:0x%x\n", + (ad.va_flags & V_ADP_VESA) ? "VESA " : "", + adapter_name(ad.va_type), ad.va_type, + ad.va_flags, ad.va_crtc_addr); + printf(" initial mode:%d, current mode:%d, BIOS mode:%d\n", + ad.va_initial_mode, ad.va_mode, ad.va_initial_bios_mode); +} + +void +show_mode_info(void) +{ + struct video_info info; + char buf[80]; + int mode; + int c; + + printf(" mode# flags type size " + "font window linear buffer\n"); + printf("---------------------------------------" + "---------------------------------------\n"); + for (mode = 0; mode < M_VESA_MODE_MAX; ++mode) { + info.vi_mode = mode; + if (ioctl(0, CONS_MODEINFO, &info)) + continue; + + printf("%3d (0x%03x)", mode, mode); + printf(" 0x%08x", info.vi_flags); + if (info.vi_flags & V_INFO_GRAPHICS) { + c = 'G'; + snprintf(buf, sizeof(buf), "%dx%dx%d %d", + info.vi_width, info.vi_height, + info.vi_depth, info.vi_planes); + } else { + c = 'T'; + snprintf(buf, sizeof(buf), "%dx%d", + info.vi_width, info.vi_height); + } + printf(" %c %-15s", c, buf); + snprintf(buf, sizeof(buf), "%dx%d", + info.vi_cwidth, info.vi_cheight); + printf(" %-5s", buf); + printf(" 0x%05x %2dk %2dk", + info.vi_window, info.vi_window_size, + info.vi_window_gran); + printf(" 0x%08x %2dk\n", + info.vi_buffer, info.vi_buffer_size); + } +} + +void +show_info(char *arg) +{ + if (!strcmp(arg, "adapter")) + show_adapter_info(); + else if (!strcmp(arg, "mode")) + show_mode_info(); + else { + warnx("argument to -i must either adapter or mode"); + return; + } +} + void test_frame() { @@ -402,7 +517,7 @@ main(int argc, char **argv) info.size = sizeof(info); if (ioctl(0, CONS_GETINFO, &info) < 0) err(1, "must be on a virtual console"); - while((opt = getopt(argc, argv, "b:c:df:l:Lm:r:s:t:x")) != -1) + while((opt = getopt(argc, argv, "b:c:df:i:l:Lm:r:s:t:x")) != -1) switch(opt) { case 'b': set_border_color(optarg); @@ -417,6 +532,9 @@ main(int argc, char **argv) load_font(optarg, nextarg(argc, argv, &optind, 'f')); break; + case 'i': + show_info(optarg); + break; case 'l': load_scrnmap(optarg); break;