16e8394b8SKazutaka YOKOTA /*- 2*718cf2ccSPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause 3*718cf2ccSPedro F. Giffuni * 46e8394b8SKazutaka YOKOTA * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp> 59a14aa01SUlrich Spörlein * Copyright (c) 1992-1998 Søren Schmidt 66e8394b8SKazutaka YOKOTA * All rights reserved. 76e8394b8SKazutaka YOKOTA * 86e8394b8SKazutaka YOKOTA * Redistribution and use in source and binary forms, with or without 96e8394b8SKazutaka YOKOTA * modification, are permitted provided that the following conditions 106e8394b8SKazutaka YOKOTA * are met: 116e8394b8SKazutaka YOKOTA * 1. Redistributions of source code must retain the above copyright 126e8394b8SKazutaka YOKOTA * notice, this list of conditions and the following disclaimer as 136e8394b8SKazutaka YOKOTA * the first lines of this file unmodified. 146e8394b8SKazutaka YOKOTA * 2. Redistributions in binary form must reproduce the above copyright 156e8394b8SKazutaka YOKOTA * notice, this list of conditions and the following disclaimer in the 166e8394b8SKazutaka YOKOTA * documentation and/or other materials provided with the distribution. 176e8394b8SKazutaka YOKOTA * 3. The name of the author may not be used to endorse or promote products 186e8394b8SKazutaka YOKOTA * derived from this software without specific prior written permission. 196e8394b8SKazutaka YOKOTA * 206e8394b8SKazutaka YOKOTA * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 216e8394b8SKazutaka YOKOTA * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 226e8394b8SKazutaka YOKOTA * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 236e8394b8SKazutaka YOKOTA * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, 246e8394b8SKazutaka YOKOTA * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 256e8394b8SKazutaka YOKOTA * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 266e8394b8SKazutaka YOKOTA * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 276e8394b8SKazutaka YOKOTA * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 286e8394b8SKazutaka YOKOTA * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 296e8394b8SKazutaka YOKOTA * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 306e8394b8SKazutaka YOKOTA * 316e8394b8SKazutaka YOKOTA */ 326e8394b8SKazutaka YOKOTA 33aad970f1SDavid E. O'Brien #include <sys/cdefs.h> 34aad970f1SDavid E. O'Brien __FBSDID("$FreeBSD$"); 35aad970f1SDavid E. O'Brien 366e8394b8SKazutaka YOKOTA #include "opt_vga.h" 376e8394b8SKazutaka YOKOTA #include "opt_fb.h" 38f4e98881SRuslan Ermilov #ifndef FB_DEBUG 39f4e98881SRuslan Ermilov #define FB_DEBUG 0 40f4e98881SRuslan Ermilov #endif 416e8394b8SKazutaka YOKOTA #include "opt_syscons.h" /* should be removed in the future, XXX */ 426e8394b8SKazutaka YOKOTA 436e8394b8SKazutaka YOKOTA #include <sys/param.h> 446e8394b8SKazutaka YOKOTA #include <sys/systm.h> 456e8394b8SKazutaka YOKOTA #include <sys/kernel.h> 466e8394b8SKazutaka YOKOTA #include <sys/conf.h> 476e8394b8SKazutaka YOKOTA #include <sys/fcntl.h> 486e8394b8SKazutaka YOKOTA #include <sys/malloc.h> 496e8394b8SKazutaka YOKOTA #include <sys/fbio.h> 506e8394b8SKazutaka YOKOTA 516e8394b8SKazutaka YOKOTA #include <vm/vm.h> 526e8394b8SKazutaka YOKOTA #include <vm/vm_param.h> 536e8394b8SKazutaka YOKOTA #include <vm/pmap.h> 546e8394b8SKazutaka YOKOTA 556e8394b8SKazutaka YOKOTA #include <machine/md_var.h> 5621691935SPeter Wemm #if defined(__i386__) || defined(__amd64__) 576e8394b8SKazutaka YOKOTA #include <machine/pc/bios.h> 588c376570SPeter Wemm #endif 5921c3015aSDoug Rabson #include <machine/bus.h> 606e8394b8SKazutaka YOKOTA 616e8394b8SKazutaka YOKOTA #include <dev/fb/fbreg.h> 626e8394b8SKazutaka YOKOTA #include <dev/fb/vgareg.h> 636e8394b8SKazutaka YOKOTA 646e8394b8SKazutaka YOKOTA #include <isa/isareg.h> 656e8394b8SKazutaka YOKOTA 666e8394b8SKazutaka YOKOTA #ifndef VGA_DEBUG 676e8394b8SKazutaka YOKOTA #define VGA_DEBUG 0 686e8394b8SKazutaka YOKOTA #endif 696e8394b8SKazutaka YOKOTA 70ae3c9affSMarcel Moolenaar /* XXX machine/pc/bios.h has got too much i386-specific stuff in it */ 718c376570SPeter Wemm #ifndef BIOS_PADDRTOVADDR 72ae3c9affSMarcel Moolenaar #define BIOS_PADDRTOVADDR(x) (x) 73ae3c9affSMarcel Moolenaar #endif 74ae3c9affSMarcel Moolenaar 756e8394b8SKazutaka YOKOTA int 766e8394b8SKazutaka YOKOTA vga_probe_unit(int unit, video_adapter_t *buf, int flags) 776e8394b8SKazutaka YOKOTA { 786e8394b8SKazutaka YOKOTA video_adapter_t *adp; 796e8394b8SKazutaka YOKOTA video_switch_t *sw; 806e8394b8SKazutaka YOKOTA int error; 816e8394b8SKazutaka YOKOTA 826e8394b8SKazutaka YOKOTA sw = vid_get_switch(VGA_DRIVER_NAME); 836e8394b8SKazutaka YOKOTA if (sw == NULL) 846e8394b8SKazutaka YOKOTA return 0; 856e8394b8SKazutaka YOKOTA error = (*sw->probe)(unit, &adp, NULL, flags); 866e8394b8SKazutaka YOKOTA if (error) 876e8394b8SKazutaka YOKOTA return error; 886e8394b8SKazutaka YOKOTA bcopy(adp, buf, sizeof(*buf)); 896e8394b8SKazutaka YOKOTA return 0; 906e8394b8SKazutaka YOKOTA } 916e8394b8SKazutaka YOKOTA 926e8394b8SKazutaka YOKOTA int 936e8394b8SKazutaka YOKOTA vga_attach_unit(int unit, vga_softc_t *sc, int flags) 946e8394b8SKazutaka YOKOTA { 956e8394b8SKazutaka YOKOTA video_switch_t *sw; 966e8394b8SKazutaka YOKOTA int error; 976e8394b8SKazutaka YOKOTA 986e8394b8SKazutaka YOKOTA sw = vid_get_switch(VGA_DRIVER_NAME); 996e8394b8SKazutaka YOKOTA if (sw == NULL) 1006e8394b8SKazutaka YOKOTA return ENXIO; 1016e8394b8SKazutaka YOKOTA 1026e8394b8SKazutaka YOKOTA error = (*sw->probe)(unit, &sc->adp, NULL, flags); 1036e8394b8SKazutaka YOKOTA if (error) 1046e8394b8SKazutaka YOKOTA return error; 1056e8394b8SKazutaka YOKOTA return (*sw->init)(unit, sc->adp, flags); 1066e8394b8SKazutaka YOKOTA } 1076e8394b8SKazutaka YOKOTA 1086e8394b8SKazutaka YOKOTA /* cdev driver functions */ 1096e8394b8SKazutaka YOKOTA 1106e8394b8SKazutaka YOKOTA #ifdef FB_INSTALL_CDEV 1116e8394b8SKazutaka YOKOTA 1126e8394b8SKazutaka YOKOTA int 11389c9c53dSPoul-Henning Kamp vga_open(struct cdev *dev, vga_softc_t *sc, int flag, int mode, struct thread *td) 1146e8394b8SKazutaka YOKOTA { 1156e8394b8SKazutaka YOKOTA if (sc == NULL) 1166e8394b8SKazutaka YOKOTA return ENXIO; 1176e8394b8SKazutaka YOKOTA if (mode & (O_CREAT | O_APPEND | O_TRUNC)) 1186e8394b8SKazutaka YOKOTA return ENODEV; 1196e8394b8SKazutaka YOKOTA 120b40ce416SJulian Elischer return genfbopen(&sc->gensc, sc->adp, flag, mode, td); 1216e8394b8SKazutaka YOKOTA } 1226e8394b8SKazutaka YOKOTA 1236e8394b8SKazutaka YOKOTA int 12489c9c53dSPoul-Henning Kamp vga_close(struct cdev *dev, vga_softc_t *sc, int flag, int mode, struct thread *td) 1256e8394b8SKazutaka YOKOTA { 126b40ce416SJulian Elischer return genfbclose(&sc->gensc, sc->adp, flag, mode, td); 1276e8394b8SKazutaka YOKOTA } 1286e8394b8SKazutaka YOKOTA 1296e8394b8SKazutaka YOKOTA int 13089c9c53dSPoul-Henning Kamp vga_read(struct cdev *dev, vga_softc_t *sc, struct uio *uio, int flag) 1316e8394b8SKazutaka YOKOTA { 1326e8394b8SKazutaka YOKOTA return genfbread(&sc->gensc, sc->adp, uio, flag); 1336e8394b8SKazutaka YOKOTA } 1346e8394b8SKazutaka YOKOTA 1356e8394b8SKazutaka YOKOTA int 13689c9c53dSPoul-Henning Kamp vga_write(struct cdev *dev, vga_softc_t *sc, struct uio *uio, int flag) 1376e8394b8SKazutaka YOKOTA { 1386e8394b8SKazutaka YOKOTA return genfbread(&sc->gensc, sc->adp, uio, flag); 1396e8394b8SKazutaka YOKOTA } 1406e8394b8SKazutaka YOKOTA 1416e8394b8SKazutaka YOKOTA int 14289c9c53dSPoul-Henning Kamp vga_ioctl(struct cdev *dev, vga_softc_t *sc, u_long cmd, caddr_t arg, int flag, 143b40ce416SJulian Elischer struct thread *td) 1446e8394b8SKazutaka YOKOTA { 145b40ce416SJulian Elischer return genfbioctl(&sc->gensc, sc->adp, cmd, arg, flag, td); 1466e8394b8SKazutaka YOKOTA } 1476e8394b8SKazutaka YOKOTA 1486e8394b8SKazutaka YOKOTA int 149cfd7baceSRobert Noland vga_mmap(struct cdev *dev, vga_softc_t *sc, vm_ooffset_t offset, 150cfd7baceSRobert Noland vm_offset_t *paddr, int prot, vm_memattr_t *memattr) 1516e8394b8SKazutaka YOKOTA { 152cfd7baceSRobert Noland return genfbmmap(&sc->gensc, sc->adp, offset, paddr, prot, memattr); 1536e8394b8SKazutaka YOKOTA } 1546e8394b8SKazutaka YOKOTA 1556e8394b8SKazutaka YOKOTA #endif /* FB_INSTALL_CDEV */ 1566e8394b8SKazutaka YOKOTA 1576e8394b8SKazutaka YOKOTA /* LOW-LEVEL */ 1586e8394b8SKazutaka YOKOTA 15936bff1ebSPoul-Henning Kamp #include <isa/rtc.h> 1608c376570SPeter Wemm #ifdef __i386__ 161ee5e90daSXin LI #include <dev/fb/vesa.h> 1628c376570SPeter Wemm #endif 1636e8394b8SKazutaka YOKOTA 1646e8394b8SKazutaka YOKOTA #define probe_done(adp) ((adp)->va_flags & V_ADP_PROBED) 1656e8394b8SKazutaka YOKOTA #define init_done(adp) ((adp)->va_flags & V_ADP_INITIALIZED) 1666e8394b8SKazutaka YOKOTA #define config_done(adp) ((adp)->va_flags & V_ADP_REGISTERED) 1676e8394b8SKazutaka YOKOTA 1686e8394b8SKazutaka YOKOTA /* for compatibility with old kernel options */ 1696e8394b8SKazutaka YOKOTA #ifdef SC_ALT_SEQACCESS 1706e8394b8SKazutaka YOKOTA #undef SC_ALT_SEQACCESS 1716e8394b8SKazutaka YOKOTA #undef VGA_ALT_SEQACCESS 1726e8394b8SKazutaka YOKOTA #define VGA_ALT_SEQACCESS 1 1736e8394b8SKazutaka YOKOTA #endif 1746e8394b8SKazutaka YOKOTA 1756e8394b8SKazutaka YOKOTA #ifdef SLOW_VGA 1766e8394b8SKazutaka YOKOTA #undef SLOW_VGA 1776e8394b8SKazutaka YOKOTA #undef VGA_SLOW_IOACCESS 178f4e98881SRuslan Ermilov #define VGA_SLOW_IOACCESS 1796e8394b8SKazutaka YOKOTA #endif 1806e8394b8SKazutaka YOKOTA 1816e8394b8SKazutaka YOKOTA /* architecture dependent option */ 182b53c4efaSXin LI #if !defined(__i386__) && !defined(__amd64__) 1836e8394b8SKazutaka YOKOTA #define VGA_NO_BIOS 1 1846e8394b8SKazutaka YOKOTA #endif 1856e8394b8SKazutaka YOKOTA 1866e8394b8SKazutaka YOKOTA /* this should really be in `rtc.h' */ 1876e8394b8SKazutaka YOKOTA #define RTC_EQUIPMENT 0x14 1886e8394b8SKazutaka YOKOTA 1896e8394b8SKazutaka YOKOTA /* various sizes */ 1906e8394b8SKazutaka YOKOTA #define V_MODE_MAP_SIZE (M_VGA_CG320 + 1) 1916e8394b8SKazutaka YOKOTA #define V_MODE_PARAM_SIZE 64 1926e8394b8SKazutaka YOKOTA 1936e8394b8SKazutaka YOKOTA /* video adapter state buffer */ 1946e8394b8SKazutaka YOKOTA struct adp_state { 1956e8394b8SKazutaka YOKOTA int sig; 1966e8394b8SKazutaka YOKOTA #define V_STATE_SIG 0x736f6962 1976e8394b8SKazutaka YOKOTA u_char regs[V_MODE_PARAM_SIZE]; 1986e8394b8SKazutaka YOKOTA }; 1996e8394b8SKazutaka YOKOTA typedef struct adp_state adp_state_t; 2006e8394b8SKazutaka YOKOTA 2016e8394b8SKazutaka YOKOTA /* video adapter information */ 2026e8394b8SKazutaka YOKOTA #define DCC_MONO 0 2036e8394b8SKazutaka YOKOTA #define DCC_CGA40 1 2046e8394b8SKazutaka YOKOTA #define DCC_CGA80 2 2056e8394b8SKazutaka YOKOTA #define DCC_EGAMONO 3 2066e8394b8SKazutaka YOKOTA #define DCC_EGA40 4 2076e8394b8SKazutaka YOKOTA #define DCC_EGA80 5 2086e8394b8SKazutaka YOKOTA 2096e8394b8SKazutaka YOKOTA /* 2106e8394b8SKazutaka YOKOTA * NOTE: `va_window' should have a virtual address, but is initialized 2116e8394b8SKazutaka YOKOTA * with a physical address in the following table, as verify_adapter() 2126e8394b8SKazutaka YOKOTA * will perform address conversion at run-time. 2136e8394b8SKazutaka YOKOTA */ 2146e8394b8SKazutaka YOKOTA static video_adapter_t adapter_init_value[] = { 2156e8394b8SKazutaka YOKOTA /* DCC_MONO */ 2166e8394b8SKazutaka YOKOTA { 0, KD_MONO, "mda", 0, 0, 0, IO_MDA, IO_MDASIZE, MONO_CRTC, 2176e8394b8SKazutaka YOKOTA MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE, 2186e8394b8SKazutaka YOKOTA 0, 0, 0, 0, 7, 0, }, 2196e8394b8SKazutaka YOKOTA /* DCC_CGA40 */ 2206e8394b8SKazutaka YOKOTA { 0, KD_CGA, "cga", 0, 0, V_ADP_COLOR, IO_CGA, IO_CGASIZE, COLOR_CRTC, 2216e8394b8SKazutaka YOKOTA CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 2226e8394b8SKazutaka YOKOTA 0, 0, 0, 0, 3, 0, }, 2236e8394b8SKazutaka YOKOTA /* DCC_CGA80 */ 2246e8394b8SKazutaka YOKOTA { 0, KD_CGA, "cga", 0, 0, V_ADP_COLOR, IO_CGA, IO_CGASIZE, COLOR_CRTC, 2256e8394b8SKazutaka YOKOTA CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 2266e8394b8SKazutaka YOKOTA 0, 0, 0, 0, 3, 0, }, 2276e8394b8SKazutaka YOKOTA /* DCC_EGAMONO */ 2286e8394b8SKazutaka YOKOTA { 0, KD_EGA, "ega", 0, 0, 0, IO_MDA, 48, MONO_CRTC, 2296e8394b8SKazutaka YOKOTA EGA_BUF_BASE, EGA_BUF_SIZE, MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE, 2306e8394b8SKazutaka YOKOTA 0, 0, 0, 0, 7, 0, }, 2316e8394b8SKazutaka YOKOTA /* DCC_EGA40 */ 2326e8394b8SKazutaka YOKOTA { 0, KD_EGA, "ega", 0, 0, V_ADP_COLOR, IO_MDA, 48, COLOR_CRTC, 2336e8394b8SKazutaka YOKOTA EGA_BUF_BASE, EGA_BUF_SIZE, CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 2346e8394b8SKazutaka YOKOTA 0, 0, 0, 0, 3, 0, }, 2356e8394b8SKazutaka YOKOTA /* DCC_EGA80 */ 2366e8394b8SKazutaka YOKOTA { 0, KD_EGA, "ega", 0, 0, V_ADP_COLOR, IO_MDA, 48, COLOR_CRTC, 2376e8394b8SKazutaka YOKOTA EGA_BUF_BASE, EGA_BUF_SIZE, CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 2386e8394b8SKazutaka YOKOTA 0, 0, 0, 0, 3, 0, }, 2396e8394b8SKazutaka YOKOTA }; 2406e8394b8SKazutaka YOKOTA 2416e8394b8SKazutaka YOKOTA static video_adapter_t biosadapter[2]; 2426e8394b8SKazutaka YOKOTA static int biosadapters = 0; 2436e8394b8SKazutaka YOKOTA 2446e8394b8SKazutaka YOKOTA /* video driver declarations */ 2456e8394b8SKazutaka YOKOTA static int vga_configure(int flags); 2466e8394b8SKazutaka YOKOTA int (*vga_sub_configure)(int flags); 2470fc85147SPeter Wemm #if 0 2486e8394b8SKazutaka YOKOTA static int vga_nop(void); 2490fc85147SPeter Wemm #endif 2506e8394b8SKazutaka YOKOTA static int vga_error(void); 2516e8394b8SKazutaka YOKOTA static vi_probe_t vga_probe; 2526e8394b8SKazutaka YOKOTA static vi_init_t vga_init; 2536e8394b8SKazutaka YOKOTA static vi_get_info_t vga_get_info; 2546e8394b8SKazutaka YOKOTA static vi_query_mode_t vga_query_mode; 2556e8394b8SKazutaka YOKOTA static vi_set_mode_t vga_set_mode; 2566e8394b8SKazutaka YOKOTA static vi_save_font_t vga_save_font; 2576e8394b8SKazutaka YOKOTA static vi_load_font_t vga_load_font; 2586e8394b8SKazutaka YOKOTA static vi_show_font_t vga_show_font; 2596e8394b8SKazutaka YOKOTA static vi_save_palette_t vga_save_palette; 2606e8394b8SKazutaka YOKOTA static vi_load_palette_t vga_load_palette; 2616e8394b8SKazutaka YOKOTA static vi_set_border_t vga_set_border; 2626e8394b8SKazutaka YOKOTA static vi_save_state_t vga_save_state; 2636e8394b8SKazutaka YOKOTA static vi_load_state_t vga_load_state; 2646e8394b8SKazutaka YOKOTA static vi_set_win_org_t vga_set_origin; 2656e8394b8SKazutaka YOKOTA static vi_read_hw_cursor_t vga_read_hw_cursor; 2666e8394b8SKazutaka YOKOTA static vi_set_hw_cursor_t vga_set_hw_cursor; 2676e8394b8SKazutaka YOKOTA static vi_set_hw_cursor_shape_t vga_set_hw_cursor_shape; 2686e8394b8SKazutaka YOKOTA static vi_blank_display_t vga_blank_display; 2696e8394b8SKazutaka YOKOTA static vi_mmap_t vga_mmap_buf; 2706e8394b8SKazutaka YOKOTA static vi_ioctl_t vga_dev_ioctl; 2716e8394b8SKazutaka YOKOTA #ifndef VGA_NO_MODE_CHANGE 2726e8394b8SKazutaka YOKOTA static vi_clear_t vga_clear; 2736e8394b8SKazutaka YOKOTA static vi_fill_rect_t vga_fill_rect; 2746e8394b8SKazutaka YOKOTA static vi_bitblt_t vga_bitblt; 2756e8394b8SKazutaka YOKOTA #else /* VGA_NO_MODE_CHANGE */ 2766e8394b8SKazutaka YOKOTA #define vga_clear (vi_clear_t *)vga_error 2776e8394b8SKazutaka YOKOTA #define vga_fill_rect (vi_fill_rect_t *)vga_error 2786e8394b8SKazutaka YOKOTA #define vga_bitblt (vi_bitblt_t *)vga_error 2796e8394b8SKazutaka YOKOTA #endif 2806e8394b8SKazutaka YOKOTA static vi_diag_t vga_diag; 2816e8394b8SKazutaka YOKOTA 2826e8394b8SKazutaka YOKOTA static video_switch_t vgavidsw = { 2836e8394b8SKazutaka YOKOTA vga_probe, 2846e8394b8SKazutaka YOKOTA vga_init, 2856e8394b8SKazutaka YOKOTA vga_get_info, 2866e8394b8SKazutaka YOKOTA vga_query_mode, 2876e8394b8SKazutaka YOKOTA vga_set_mode, 2886e8394b8SKazutaka YOKOTA vga_save_font, 2896e8394b8SKazutaka YOKOTA vga_load_font, 2906e8394b8SKazutaka YOKOTA vga_show_font, 2916e8394b8SKazutaka YOKOTA vga_save_palette, 2926e8394b8SKazutaka YOKOTA vga_load_palette, 2936e8394b8SKazutaka YOKOTA vga_set_border, 2946e8394b8SKazutaka YOKOTA vga_save_state, 2956e8394b8SKazutaka YOKOTA vga_load_state, 2966e8394b8SKazutaka YOKOTA vga_set_origin, 2976e8394b8SKazutaka YOKOTA vga_read_hw_cursor, 2986e8394b8SKazutaka YOKOTA vga_set_hw_cursor, 2996e8394b8SKazutaka YOKOTA vga_set_hw_cursor_shape, 3006e8394b8SKazutaka YOKOTA vga_blank_display, 3016e8394b8SKazutaka YOKOTA vga_mmap_buf, 3026e8394b8SKazutaka YOKOTA vga_dev_ioctl, 3036e8394b8SKazutaka YOKOTA vga_clear, 3046e8394b8SKazutaka YOKOTA vga_fill_rect, 3056e8394b8SKazutaka YOKOTA vga_bitblt, 3066e8394b8SKazutaka YOKOTA vga_error, 3076e8394b8SKazutaka YOKOTA vga_error, 3086e8394b8SKazutaka YOKOTA vga_diag, 3096e8394b8SKazutaka YOKOTA }; 3106e8394b8SKazutaka YOKOTA 3116e8394b8SKazutaka YOKOTA VIDEO_DRIVER(mda, vgavidsw, NULL); 3126e8394b8SKazutaka YOKOTA VIDEO_DRIVER(cga, vgavidsw, NULL); 3136e8394b8SKazutaka YOKOTA VIDEO_DRIVER(ega, vgavidsw, NULL); 3146e8394b8SKazutaka YOKOTA VIDEO_DRIVER(vga, vgavidsw, vga_configure); 3156e8394b8SKazutaka YOKOTA 3166e8394b8SKazutaka YOKOTA /* VGA BIOS standard video modes */ 3176e8394b8SKazutaka YOKOTA #define EOT (-1) 3186e8394b8SKazutaka YOKOTA #define NA (-2) 3196e8394b8SKazutaka YOKOTA 3206e8394b8SKazutaka YOKOTA static video_info_t bios_vmode[] = { 3216e8394b8SKazutaka YOKOTA /* CGA */ 3226e8394b8SKazutaka YOKOTA { M_B40x25, V_INFO_COLOR, 40, 25, 8, 8, 2, 1, 3236e8394b8SKazutaka YOKOTA CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, 3246e8394b8SKazutaka YOKOTA { M_C40x25, V_INFO_COLOR, 40, 25, 8, 8, 4, 1, 3256e8394b8SKazutaka YOKOTA CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, 3266e8394b8SKazutaka YOKOTA { M_B80x25, V_INFO_COLOR, 80, 25, 8, 8, 2, 1, 3276e8394b8SKazutaka YOKOTA CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, 3286e8394b8SKazutaka YOKOTA { M_C80x25, V_INFO_COLOR, 80, 25, 8, 8, 4, 1, 3296e8394b8SKazutaka YOKOTA CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, 3306e8394b8SKazutaka YOKOTA /* EGA */ 3316e8394b8SKazutaka YOKOTA { M_ENH_B40x25, V_INFO_COLOR, 40, 25, 8, 14, 2, 1, 3326e8394b8SKazutaka YOKOTA CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, 3336e8394b8SKazutaka YOKOTA { M_ENH_C40x25, V_INFO_COLOR, 40, 25, 8, 14, 4, 1, 3346e8394b8SKazutaka YOKOTA CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, 3356e8394b8SKazutaka YOKOTA { M_ENH_B80x25, V_INFO_COLOR, 80, 25, 8, 14, 2, 1, 3366e8394b8SKazutaka YOKOTA CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, 3376e8394b8SKazutaka YOKOTA { M_ENH_C80x25, V_INFO_COLOR, 80, 25, 8, 14, 4, 1, 3386e8394b8SKazutaka YOKOTA CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, 3396e8394b8SKazutaka YOKOTA /* VGA */ 3406e8394b8SKazutaka YOKOTA { M_VGA_C40x25, V_INFO_COLOR, 40, 25, 8, 16, 4, 1, 3416e8394b8SKazutaka YOKOTA CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, 3426e8394b8SKazutaka YOKOTA { M_VGA_M80x25, 0, 80, 25, 8, 16, 2, 1, 3436e8394b8SKazutaka YOKOTA MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, 3446e8394b8SKazutaka YOKOTA { M_VGA_C80x25, V_INFO_COLOR, 80, 25, 8, 16, 4, 1, 3456e8394b8SKazutaka YOKOTA CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, 3466e8394b8SKazutaka YOKOTA /* MDA */ 3476e8394b8SKazutaka YOKOTA { M_EGAMONO80x25, 0, 80, 25, 8, 14, 2, 1, 3486e8394b8SKazutaka YOKOTA MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, 3496e8394b8SKazutaka YOKOTA /* EGA */ 35089a1e6c3SBruce Evans { M_ENH_B80x43, V_INFO_COLOR, 80, 43, 8, 8, 2, 1, 3516e8394b8SKazutaka YOKOTA CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, 3526e8394b8SKazutaka YOKOTA { M_ENH_C80x43, V_INFO_COLOR, 80, 43, 8, 8, 4, 1, 3536e8394b8SKazutaka YOKOTA CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, 3546e8394b8SKazutaka YOKOTA /* VGA */ 3556e8394b8SKazutaka YOKOTA { M_VGA_M80x30, 0, 80, 30, 8, 16, 2, 1, 3566e8394b8SKazutaka YOKOTA MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, 3576e8394b8SKazutaka YOKOTA { M_VGA_C80x30, V_INFO_COLOR, 80, 30, 8, 16, 4, 1, 3586e8394b8SKazutaka YOKOTA CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, 3596e8394b8SKazutaka YOKOTA { M_VGA_M80x50, 0, 80, 50, 8, 8, 2, 1, 3606e8394b8SKazutaka YOKOTA MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, 3616e8394b8SKazutaka YOKOTA { M_VGA_C80x50, V_INFO_COLOR, 80, 50, 8, 8, 4, 1, 3626e8394b8SKazutaka YOKOTA CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, 3636e8394b8SKazutaka YOKOTA { M_VGA_M80x60, 0, 80, 60, 8, 8, 2, 1, 3646e8394b8SKazutaka YOKOTA MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, 3656e8394b8SKazutaka YOKOTA { M_VGA_C80x60, V_INFO_COLOR, 80, 60, 8, 8, 4, 1, 3666e8394b8SKazutaka YOKOTA CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, 3676e8394b8SKazutaka YOKOTA 3686e8394b8SKazutaka YOKOTA #ifndef VGA_NO_MODE_CHANGE 3696e8394b8SKazutaka YOKOTA 3706e8394b8SKazutaka YOKOTA #ifdef VGA_WIDTH90 3716e8394b8SKazutaka YOKOTA { M_VGA_M90x25, 0, 90, 25, 8, 16, 2, 1, 3726e8394b8SKazutaka YOKOTA MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, 3736e8394b8SKazutaka YOKOTA { M_VGA_C90x25, V_INFO_COLOR, 90, 25, 8, 16, 4, 1, 3746e8394b8SKazutaka YOKOTA CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, 3756e8394b8SKazutaka YOKOTA { M_VGA_M90x30, 0, 90, 30, 8, 16, 2, 1, 3766e8394b8SKazutaka YOKOTA MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, 3776e8394b8SKazutaka YOKOTA { M_VGA_C90x30, V_INFO_COLOR, 90, 30, 8, 16, 4, 1, 3786e8394b8SKazutaka YOKOTA CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, 3796e8394b8SKazutaka YOKOTA { M_VGA_M90x43, 0, 90, 43, 8, 8, 2, 1, 38089a1e6c3SBruce Evans MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, 3816e8394b8SKazutaka YOKOTA { M_VGA_C90x43, V_INFO_COLOR, 90, 43, 8, 8, 4, 1, 3826e8394b8SKazutaka YOKOTA CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, 3836e8394b8SKazutaka YOKOTA { M_VGA_M90x50, 0, 90, 50, 8, 8, 2, 1, 3846e8394b8SKazutaka YOKOTA MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, 3856e8394b8SKazutaka YOKOTA { M_VGA_C90x50, V_INFO_COLOR, 90, 50, 8, 8, 4, 1, 3866e8394b8SKazutaka YOKOTA CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, 3876e8394b8SKazutaka YOKOTA { M_VGA_M90x60, 0, 90, 60, 8, 8, 2, 1, 3886e8394b8SKazutaka YOKOTA MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, 3896e8394b8SKazutaka YOKOTA { M_VGA_C90x60, V_INFO_COLOR, 90, 60, 8, 8, 4, 1, 3906e8394b8SKazutaka YOKOTA CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_TEXT }, 3916e8394b8SKazutaka YOKOTA #endif /* VGA_WIDTH90 */ 3926e8394b8SKazutaka YOKOTA 3936e8394b8SKazutaka YOKOTA /* CGA */ 3946e8394b8SKazutaka YOKOTA { M_BG320, V_INFO_COLOR | V_INFO_GRAPHICS, 320, 200, 8, 8, 2, 1, 3956e8394b8SKazutaka YOKOTA CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_CGA }, 3966e8394b8SKazutaka YOKOTA { M_CG320, V_INFO_COLOR | V_INFO_GRAPHICS, 320, 200, 8, 8, 2, 1, 3976e8394b8SKazutaka YOKOTA CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_CGA }, 3986e8394b8SKazutaka YOKOTA { M_BG640, V_INFO_COLOR | V_INFO_GRAPHICS, 640, 200, 8, 8, 1, 1, 3996e8394b8SKazutaka YOKOTA CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 0, 0, V_INFO_MM_CGA }, 4006e8394b8SKazutaka YOKOTA /* EGA */ 4016e8394b8SKazutaka YOKOTA { M_CG320_D, V_INFO_COLOR | V_INFO_GRAPHICS, 320, 200, 8, 8, 4, 4, 4026e8394b8SKazutaka YOKOTA GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0, 4036e8394b8SKazutaka YOKOTA V_INFO_MM_PLANAR }, 4046e8394b8SKazutaka YOKOTA { M_CG640_E, V_INFO_COLOR | V_INFO_GRAPHICS, 640, 200, 8, 8, 4, 4, 4056e8394b8SKazutaka YOKOTA GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0 , 4066e8394b8SKazutaka YOKOTA V_INFO_MM_PLANAR }, 4076e8394b8SKazutaka YOKOTA { M_EGAMONOAPA, V_INFO_GRAPHICS, 640, 350, 8, 14, 4, 4, 4086e8394b8SKazutaka YOKOTA GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, 64*1024, 0, 0 , 4096e8394b8SKazutaka YOKOTA V_INFO_MM_PLANAR }, 4106e8394b8SKazutaka YOKOTA { M_ENHMONOAPA2,V_INFO_GRAPHICS, 640, 350, 8, 14, 4, 4, 4116e8394b8SKazutaka YOKOTA GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0 , 4126e8394b8SKazutaka YOKOTA V_INFO_MM_PLANAR }, 4136e8394b8SKazutaka YOKOTA { M_CG640x350, V_INFO_COLOR | V_INFO_GRAPHICS, 640, 350, 8, 14, 2, 2, 4146e8394b8SKazutaka YOKOTA GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0 , 4156e8394b8SKazutaka YOKOTA V_INFO_MM_PLANAR }, 4166e8394b8SKazutaka YOKOTA { M_ENH_CG640, V_INFO_COLOR | V_INFO_GRAPHICS, 640, 350, 8, 14, 4, 4, 4176e8394b8SKazutaka YOKOTA GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0 , 4186e8394b8SKazutaka YOKOTA V_INFO_MM_PLANAR }, 4196e8394b8SKazutaka YOKOTA /* VGA */ 4206e8394b8SKazutaka YOKOTA { M_BG640x480, V_INFO_COLOR | V_INFO_GRAPHICS, 640, 480, 8, 16, 4, 4, 4216e8394b8SKazutaka YOKOTA GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0 , 4226e8394b8SKazutaka YOKOTA V_INFO_MM_PLANAR }, 4236e8394b8SKazutaka YOKOTA { M_CG640x480, V_INFO_COLOR | V_INFO_GRAPHICS, 640, 480, 8, 16, 4, 4, 4246e8394b8SKazutaka YOKOTA GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0 , 4256e8394b8SKazutaka YOKOTA V_INFO_MM_PLANAR }, 4266e8394b8SKazutaka YOKOTA { M_VGA_CG320, V_INFO_COLOR | V_INFO_GRAPHICS, 320, 200, 8, 8, 8, 1, 4276e8394b8SKazutaka YOKOTA GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0, 4286e8394b8SKazutaka YOKOTA V_INFO_MM_PACKED, 1 }, 4292832e356SKazutaka YOKOTA { M_VGA_MODEX, V_INFO_COLOR | V_INFO_GRAPHICS, 320, 240, 8, 8, 8, 4, 4306e8394b8SKazutaka YOKOTA GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0, 4312832e356SKazutaka YOKOTA V_INFO_MM_VGAX, 1 }, 4326e8394b8SKazutaka YOKOTA #endif /* VGA_NO_MODE_CHANGE */ 4336e8394b8SKazutaka YOKOTA 4346e8394b8SKazutaka YOKOTA { EOT }, 4356e8394b8SKazutaka YOKOTA }; 4366e8394b8SKazutaka YOKOTA 4376e8394b8SKazutaka YOKOTA static int vga_init_done = FALSE; 4386e8394b8SKazutaka YOKOTA #if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE) 4396e8394b8SKazutaka YOKOTA static u_char *video_mode_ptr = NULL; /* EGA/VGA */ 4406e8394b8SKazutaka YOKOTA static u_char *video_mode_ptr2 = NULL; /* CGA/MDA */ 4416e8394b8SKazutaka YOKOTA #endif 4426e8394b8SKazutaka YOKOTA static u_char *mode_map[V_MODE_MAP_SIZE]; 4436e8394b8SKazutaka YOKOTA static adp_state_t adpstate; 4446e8394b8SKazutaka YOKOTA static adp_state_t adpstate2; 4456e8394b8SKazutaka YOKOTA static int rows_offset = 1; 4466e8394b8SKazutaka YOKOTA 4476e8394b8SKazutaka YOKOTA /* local macros and functions */ 4486e8394b8SKazutaka YOKOTA #define BIOS_SADDRTOLADDR(p) ((((p) & 0xffff0000) >> 12) + ((p) & 0x0000ffff)) 4496e8394b8SKazutaka YOKOTA 4506e8394b8SKazutaka YOKOTA #if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE) 4516e8394b8SKazutaka YOKOTA static void map_mode_table(u_char *map[], u_char *table, int max); 4526e8394b8SKazutaka YOKOTA #endif 4536e8394b8SKazutaka YOKOTA static void clear_mode_map(video_adapter_t *adp, u_char *map[], int max, 4546e8394b8SKazutaka YOKOTA int color); 4556e8394b8SKazutaka YOKOTA #if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE) 4566e8394b8SKazutaka YOKOTA static int map_mode_num(int mode); 4576e8394b8SKazutaka YOKOTA #endif 4586e8394b8SKazutaka YOKOTA static int map_gen_mode_num(int type, int color, int mode); 4596e8394b8SKazutaka YOKOTA static int map_bios_mode_num(int type, int color, int bios_mode); 4606e8394b8SKazutaka YOKOTA static u_char *get_mode_param(int mode); 4616e8394b8SKazutaka YOKOTA #ifndef VGA_NO_BIOS 4626e8394b8SKazutaka YOKOTA static void fill_adapter_param(int code, video_adapter_t *adp); 4636e8394b8SKazutaka YOKOTA #endif 4646e8394b8SKazutaka YOKOTA static int verify_adapter(video_adapter_t *adp); 4656e8394b8SKazutaka YOKOTA static void update_adapter_info(video_adapter_t *adp, video_info_t *info); 4666e8394b8SKazutaka YOKOTA #if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE) 4676e8394b8SKazutaka YOKOTA #define COMP_IDENTICAL 0 4686e8394b8SKazutaka YOKOTA #define COMP_SIMILAR 1 4696e8394b8SKazutaka YOKOTA #define COMP_DIFFERENT 2 4706e8394b8SKazutaka YOKOTA static int comp_adpregs(u_char *buf1, u_char *buf2); 4716e8394b8SKazutaka YOKOTA #endif 4726e8394b8SKazutaka YOKOTA static int probe_adapters(void); 4736e8394b8SKazutaka YOKOTA static int set_line_length(video_adapter_t *adp, int pixel); 4746e8394b8SKazutaka YOKOTA static int set_display_start(video_adapter_t *adp, int x, int y); 4756e8394b8SKazutaka YOKOTA 4766e8394b8SKazutaka YOKOTA #ifndef VGA_NO_MODE_CHANGE 4776e8394b8SKazutaka YOKOTA #ifdef VGA_WIDTH90 4786e8394b8SKazutaka YOKOTA static void set_width90(adp_state_t *params); 4796e8394b8SKazutaka YOKOTA #endif 4806e8394b8SKazutaka YOKOTA #endif /* !VGA_NO_MODE_CHANGE */ 4816e8394b8SKazutaka YOKOTA 4826e8394b8SKazutaka YOKOTA #ifndef VGA_NO_FONT_LOADING 4836e8394b8SKazutaka YOKOTA #define PARAM_BUFSIZE 6 4846e8394b8SKazutaka YOKOTA static void set_font_mode(video_adapter_t *adp, u_char *buf); 4856e8394b8SKazutaka YOKOTA static void set_normal_mode(video_adapter_t *adp, u_char *buf); 4866e8394b8SKazutaka YOKOTA #endif 4876e8394b8SKazutaka YOKOTA 4886e8394b8SKazutaka YOKOTA #ifndef VGA_NO_MODE_CHANGE 489b7b28d26SRuslan Ermilov static void filll_io(int val, vm_offset_t d, size_t size); 4906e8394b8SKazutaka YOKOTA static void planar_fill(video_adapter_t *adp, int val); 4916e8394b8SKazutaka YOKOTA static void packed_fill(video_adapter_t *adp, int val); 4926e8394b8SKazutaka YOKOTA static void direct_fill(video_adapter_t *adp, int val); 4936e8394b8SKazutaka YOKOTA #ifdef notyet 4946e8394b8SKazutaka YOKOTA static void planar_fill_rect(video_adapter_t *adp, int val, int x, int y, 4956e8394b8SKazutaka YOKOTA int cx, int cy); 4966e8394b8SKazutaka YOKOTA static void packed_fill_rect(video_adapter_t *adp, int val, int x, int y, 4976e8394b8SKazutaka YOKOTA int cx, int cy); 4986e8394b8SKazutaka YOKOTA static void direct_fill_rect16(video_adapter_t *adp, int val, int x, int y, 4996e8394b8SKazutaka YOKOTA int cx, int cy); 5006e8394b8SKazutaka YOKOTA static void direct_fill_rect24(video_adapter_t *adp, int val, int x, int y, 5016e8394b8SKazutaka YOKOTA int cx, int cy); 5026e8394b8SKazutaka YOKOTA static void direct_fill_rect32(video_adapter_t *adp, int val, int x, int y, 5036e8394b8SKazutaka YOKOTA int cx, int cy); 5046e8394b8SKazutaka YOKOTA #endif /* notyet */ 5056e8394b8SKazutaka YOKOTA #endif /* !VGA_NO_MODE_CHANGE */ 5066e8394b8SKazutaka YOKOTA 5076e8394b8SKazutaka YOKOTA static void dump_buffer(u_char *buf, size_t len); 5086e8394b8SKazutaka YOKOTA 5096e8394b8SKazutaka YOKOTA #define ISMAPPED(pa, width) \ 5106e8394b8SKazutaka YOKOTA (((pa) <= (u_long)0x1000 - (width)) \ 5116e8394b8SKazutaka YOKOTA || ((pa) >= ISA_HOLE_START && (pa) <= 0x100000 - (width))) 5126e8394b8SKazutaka YOKOTA 5136e8394b8SKazutaka YOKOTA #define prologue(adp, flag, err) \ 5146e8394b8SKazutaka YOKOTA if (!vga_init_done || !((adp)->va_flags & (flag))) \ 5156e8394b8SKazutaka YOKOTA return (err) 5166e8394b8SKazutaka YOKOTA 5176e8394b8SKazutaka YOKOTA /* a backdoor for the console driver */ 5186e8394b8SKazutaka YOKOTA static int 5196e8394b8SKazutaka YOKOTA vga_configure(int flags) 5206e8394b8SKazutaka YOKOTA { 5216e8394b8SKazutaka YOKOTA int i; 5226e8394b8SKazutaka YOKOTA 5236e8394b8SKazutaka YOKOTA probe_adapters(); 5246e8394b8SKazutaka YOKOTA for (i = 0; i < biosadapters; ++i) { 5256e8394b8SKazutaka YOKOTA if (!probe_done(&biosadapter[i])) 5266e8394b8SKazutaka YOKOTA continue; 5276e8394b8SKazutaka YOKOTA biosadapter[i].va_flags |= V_ADP_INITIALIZED; 5286e8394b8SKazutaka YOKOTA if (!config_done(&biosadapter[i])) { 5296e8394b8SKazutaka YOKOTA if (vid_register(&biosadapter[i]) < 0) 5306e8394b8SKazutaka YOKOTA continue; 5316e8394b8SKazutaka YOKOTA biosadapter[i].va_flags |= V_ADP_REGISTERED; 5326e8394b8SKazutaka YOKOTA } 5336e8394b8SKazutaka YOKOTA } 5346e8394b8SKazutaka YOKOTA if (vga_sub_configure != NULL) 5356e8394b8SKazutaka YOKOTA (*vga_sub_configure)(flags); 5366e8394b8SKazutaka YOKOTA 5376e8394b8SKazutaka YOKOTA return biosadapters; 5386e8394b8SKazutaka YOKOTA } 5396e8394b8SKazutaka YOKOTA 5406e8394b8SKazutaka YOKOTA /* local subroutines */ 5416e8394b8SKazutaka YOKOTA 5426e8394b8SKazutaka YOKOTA #if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE) 5436e8394b8SKazutaka YOKOTA /* construct the mode parameter map */ 5446e8394b8SKazutaka YOKOTA static void 5456e8394b8SKazutaka YOKOTA map_mode_table(u_char *map[], u_char *table, int max) 5466e8394b8SKazutaka YOKOTA { 5476e8394b8SKazutaka YOKOTA int i; 5486e8394b8SKazutaka YOKOTA 5496e8394b8SKazutaka YOKOTA for(i = 0; i < max; ++i) 5506e8394b8SKazutaka YOKOTA map[i] = table + i*V_MODE_PARAM_SIZE; 5516e8394b8SKazutaka YOKOTA for(; i < V_MODE_MAP_SIZE; ++i) 5526e8394b8SKazutaka YOKOTA map[i] = NULL; 5536e8394b8SKazutaka YOKOTA } 5546e8394b8SKazutaka YOKOTA #endif /* !VGA_NO_BIOS && !VGA_NO_MODE_CHANGE */ 5556e8394b8SKazutaka YOKOTA 5566e8394b8SKazutaka YOKOTA static void 5576e8394b8SKazutaka YOKOTA clear_mode_map(video_adapter_t *adp, u_char *map[], int max, int color) 5586e8394b8SKazutaka YOKOTA { 5596e8394b8SKazutaka YOKOTA video_info_t info; 5606e8394b8SKazutaka YOKOTA int i; 5616e8394b8SKazutaka YOKOTA 5626e8394b8SKazutaka YOKOTA /* 5636e8394b8SKazutaka YOKOTA * NOTE: we don't touch `bios_vmode[]' because it is shared 5646e8394b8SKazutaka YOKOTA * by all adapters. 5656e8394b8SKazutaka YOKOTA */ 5666e8394b8SKazutaka YOKOTA for(i = 0; i < max; ++i) { 5676e8394b8SKazutaka YOKOTA if (vga_get_info(adp, i, &info)) 5686e8394b8SKazutaka YOKOTA continue; 5696e8394b8SKazutaka YOKOTA if ((info.vi_flags & V_INFO_COLOR) != color) 5706e8394b8SKazutaka YOKOTA map[i] = NULL; 5716e8394b8SKazutaka YOKOTA } 5726e8394b8SKazutaka YOKOTA } 5736e8394b8SKazutaka YOKOTA 5746e8394b8SKazutaka YOKOTA #if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE) 5756e8394b8SKazutaka YOKOTA /* map the non-standard video mode to a known mode number */ 5766e8394b8SKazutaka YOKOTA static int 5776e8394b8SKazutaka YOKOTA map_mode_num(int mode) 5786e8394b8SKazutaka YOKOTA { 5796e8394b8SKazutaka YOKOTA static struct { 5806e8394b8SKazutaka YOKOTA int from; 5816e8394b8SKazutaka YOKOTA int to; 5826e8394b8SKazutaka YOKOTA } mode_map[] = { 5836e8394b8SKazutaka YOKOTA { M_ENH_B80x43, M_ENH_B80x25 }, 5846e8394b8SKazutaka YOKOTA { M_ENH_C80x43, M_ENH_C80x25 }, 5856e8394b8SKazutaka YOKOTA { M_VGA_M80x30, M_VGA_M80x25 }, 5866e8394b8SKazutaka YOKOTA { M_VGA_C80x30, M_VGA_C80x25 }, 5876e8394b8SKazutaka YOKOTA { M_VGA_M80x50, M_VGA_M80x25 }, 5886e8394b8SKazutaka YOKOTA { M_VGA_C80x50, M_VGA_C80x25 }, 5896e8394b8SKazutaka YOKOTA { M_VGA_M80x60, M_VGA_M80x25 }, 5906e8394b8SKazutaka YOKOTA { M_VGA_C80x60, M_VGA_C80x25 }, 5916e8394b8SKazutaka YOKOTA #ifdef VGA_WIDTH90 5926e8394b8SKazutaka YOKOTA { M_VGA_M90x25, M_VGA_M80x25 }, 5936e8394b8SKazutaka YOKOTA { M_VGA_C90x25, M_VGA_C80x25 }, 5946e8394b8SKazutaka YOKOTA { M_VGA_M90x30, M_VGA_M80x25 }, 5956e8394b8SKazutaka YOKOTA { M_VGA_C90x30, M_VGA_C80x25 }, 59689a1e6c3SBruce Evans { M_VGA_M90x43, M_VGA_M80x25 }, 5976e8394b8SKazutaka YOKOTA { M_VGA_C90x43, M_ENH_C80x25 }, 5986e8394b8SKazutaka YOKOTA { M_VGA_M90x50, M_VGA_M80x25 }, 5996e8394b8SKazutaka YOKOTA { M_VGA_C90x50, M_VGA_C80x25 }, 6006e8394b8SKazutaka YOKOTA { M_VGA_M90x60, M_VGA_M80x25 }, 6016e8394b8SKazutaka YOKOTA { M_VGA_C90x60, M_VGA_C80x25 }, 6026e8394b8SKazutaka YOKOTA #endif 6036e8394b8SKazutaka YOKOTA { M_VGA_MODEX, M_VGA_CG320 }, 6046e8394b8SKazutaka YOKOTA }; 6056e8394b8SKazutaka YOKOTA int i; 6066e8394b8SKazutaka YOKOTA 607323b076eSPedro F. Giffuni for (i = 0; i < nitems(mode_map); ++i) { 6086e8394b8SKazutaka YOKOTA if (mode_map[i].from == mode) 6096e8394b8SKazutaka YOKOTA return mode_map[i].to; 6106e8394b8SKazutaka YOKOTA } 6116e8394b8SKazutaka YOKOTA return mode; 6126e8394b8SKazutaka YOKOTA } 6136e8394b8SKazutaka YOKOTA #endif /* !VGA_NO_BIOS && !VGA_NO_MODE_CHANGE */ 6146e8394b8SKazutaka YOKOTA 6156e8394b8SKazutaka YOKOTA /* map a generic video mode to a known mode number */ 6166e8394b8SKazutaka YOKOTA static int 6176e8394b8SKazutaka YOKOTA map_gen_mode_num(int type, int color, int mode) 6186e8394b8SKazutaka YOKOTA { 6196e8394b8SKazutaka YOKOTA static struct { 6206e8394b8SKazutaka YOKOTA int from; 6216e8394b8SKazutaka YOKOTA int to_color; 6226e8394b8SKazutaka YOKOTA int to_mono; 6236e8394b8SKazutaka YOKOTA } mode_map[] = { 6246e8394b8SKazutaka YOKOTA { M_TEXT_80x30, M_VGA_C80x30, M_VGA_M80x30, }, 6256e8394b8SKazutaka YOKOTA { M_TEXT_80x43, M_ENH_C80x43, M_ENH_B80x43, }, 6266e8394b8SKazutaka YOKOTA { M_TEXT_80x50, M_VGA_C80x50, M_VGA_M80x50, }, 6276e8394b8SKazutaka YOKOTA { M_TEXT_80x60, M_VGA_C80x60, M_VGA_M80x60, }, 6286e8394b8SKazutaka YOKOTA }; 6296e8394b8SKazutaka YOKOTA int i; 6306e8394b8SKazutaka YOKOTA 6316e8394b8SKazutaka YOKOTA if (mode == M_TEXT_80x25) { 6326e8394b8SKazutaka YOKOTA switch (type) { 6336e8394b8SKazutaka YOKOTA 6346e8394b8SKazutaka YOKOTA case KD_VGA: 6356e8394b8SKazutaka YOKOTA if (color) 6366e8394b8SKazutaka YOKOTA return M_VGA_C80x25; 6376e8394b8SKazutaka YOKOTA else 6386e8394b8SKazutaka YOKOTA return M_VGA_M80x25; 6396e8394b8SKazutaka YOKOTA break; 6406e8394b8SKazutaka YOKOTA 6416e8394b8SKazutaka YOKOTA case KD_EGA: 6426e8394b8SKazutaka YOKOTA if (color) 6436e8394b8SKazutaka YOKOTA return M_ENH_C80x25; 6446e8394b8SKazutaka YOKOTA else 6456e8394b8SKazutaka YOKOTA return M_EGAMONO80x25; 6466e8394b8SKazutaka YOKOTA break; 6476e8394b8SKazutaka YOKOTA 6486e8394b8SKazutaka YOKOTA case KD_CGA: 6496e8394b8SKazutaka YOKOTA return M_C80x25; 6506e8394b8SKazutaka YOKOTA 6516e8394b8SKazutaka YOKOTA case KD_MONO: 6526e8394b8SKazutaka YOKOTA case KD_HERCULES: 6536e8394b8SKazutaka YOKOTA return M_EGAMONO80x25; /* XXX: this name is confusing */ 6546e8394b8SKazutaka YOKOTA 6556e8394b8SKazutaka YOKOTA default: 6566e8394b8SKazutaka YOKOTA return -1; 6576e8394b8SKazutaka YOKOTA } 6586e8394b8SKazutaka YOKOTA } 6596e8394b8SKazutaka YOKOTA 660323b076eSPedro F. Giffuni for (i = 0; i < nitems(mode_map); ++i) { 6616e8394b8SKazutaka YOKOTA if (mode_map[i].from == mode) 6626e8394b8SKazutaka YOKOTA return ((color) ? mode_map[i].to_color : mode_map[i].to_mono); 6636e8394b8SKazutaka YOKOTA } 6646e8394b8SKazutaka YOKOTA return mode; 6656e8394b8SKazutaka YOKOTA } 6666e8394b8SKazutaka YOKOTA 6676e8394b8SKazutaka YOKOTA /* turn the BIOS video number into our video mode number */ 6686e8394b8SKazutaka YOKOTA static int 6696e8394b8SKazutaka YOKOTA map_bios_mode_num(int type, int color, int bios_mode) 6706e8394b8SKazutaka YOKOTA { 6716e8394b8SKazutaka YOKOTA static int cga_modes[7] = { 6726e8394b8SKazutaka YOKOTA M_B40x25, M_C40x25, /* 0, 1 */ 6736e8394b8SKazutaka YOKOTA M_B80x25, M_C80x25, /* 2, 3 */ 6746e8394b8SKazutaka YOKOTA M_BG320, M_CG320, 6756e8394b8SKazutaka YOKOTA M_BG640, 6766e8394b8SKazutaka YOKOTA }; 6776e8394b8SKazutaka YOKOTA static int ega_modes[17] = { 6786e8394b8SKazutaka YOKOTA M_ENH_B40x25, M_ENH_C40x25, /* 0, 1 */ 6796e8394b8SKazutaka YOKOTA M_ENH_B80x25, M_ENH_C80x25, /* 2, 3 */ 6806e8394b8SKazutaka YOKOTA M_BG320, M_CG320, 6816e8394b8SKazutaka YOKOTA M_BG640, 6826e8394b8SKazutaka YOKOTA M_EGAMONO80x25, /* 7 */ 6836e8394b8SKazutaka YOKOTA 8, 9, 10, 11, 12, 6846e8394b8SKazutaka YOKOTA M_CG320_D, 6856e8394b8SKazutaka YOKOTA M_CG640_E, 6866e8394b8SKazutaka YOKOTA M_ENHMONOAPA2, /* XXX: video momery > 64K */ 6876e8394b8SKazutaka YOKOTA M_ENH_CG640, /* XXX: video momery > 64K */ 6886e8394b8SKazutaka YOKOTA }; 6896e8394b8SKazutaka YOKOTA static int vga_modes[20] = { 6906e8394b8SKazutaka YOKOTA M_VGA_C40x25, M_VGA_C40x25, /* 0, 1 */ 6916e8394b8SKazutaka YOKOTA M_VGA_C80x25, M_VGA_C80x25, /* 2, 3 */ 6926e8394b8SKazutaka YOKOTA M_BG320, M_CG320, 6936e8394b8SKazutaka YOKOTA M_BG640, 6946e8394b8SKazutaka YOKOTA M_VGA_M80x25, /* 7 */ 6956e8394b8SKazutaka YOKOTA 8, 9, 10, 11, 12, 6966e8394b8SKazutaka YOKOTA M_CG320_D, 6976e8394b8SKazutaka YOKOTA M_CG640_E, 6986e8394b8SKazutaka YOKOTA M_ENHMONOAPA2, 6996e8394b8SKazutaka YOKOTA M_ENH_CG640, 7006e8394b8SKazutaka YOKOTA M_BG640x480, M_CG640x480, 7016e8394b8SKazutaka YOKOTA M_VGA_CG320, 7026e8394b8SKazutaka YOKOTA }; 7036e8394b8SKazutaka YOKOTA 7046e8394b8SKazutaka YOKOTA switch (type) { 7056e8394b8SKazutaka YOKOTA 7066e8394b8SKazutaka YOKOTA case KD_VGA: 707323b076eSPedro F. Giffuni if (bios_mode < nitems(vga_modes)) 7086e8394b8SKazutaka YOKOTA return vga_modes[bios_mode]; 7096e8394b8SKazutaka YOKOTA else if (color) 7106e8394b8SKazutaka YOKOTA return M_VGA_C80x25; 7116e8394b8SKazutaka YOKOTA else 7126e8394b8SKazutaka YOKOTA return M_VGA_M80x25; 7136e8394b8SKazutaka YOKOTA break; 7146e8394b8SKazutaka YOKOTA 7156e8394b8SKazutaka YOKOTA case KD_EGA: 716323b076eSPedro F. Giffuni if (bios_mode < nitems(ega_modes)) 7176e8394b8SKazutaka YOKOTA return ega_modes[bios_mode]; 7186e8394b8SKazutaka YOKOTA else if (color) 7196e8394b8SKazutaka YOKOTA return M_ENH_C80x25; 7206e8394b8SKazutaka YOKOTA else 7216e8394b8SKazutaka YOKOTA return M_EGAMONO80x25; 7226e8394b8SKazutaka YOKOTA break; 7236e8394b8SKazutaka YOKOTA 7246e8394b8SKazutaka YOKOTA case KD_CGA: 725323b076eSPedro F. Giffuni if (bios_mode < nitems(cga_modes)) 7266e8394b8SKazutaka YOKOTA return cga_modes[bios_mode]; 7276e8394b8SKazutaka YOKOTA else 7286e8394b8SKazutaka YOKOTA return M_C80x25; 7296e8394b8SKazutaka YOKOTA break; 7306e8394b8SKazutaka YOKOTA 7316e8394b8SKazutaka YOKOTA case KD_MONO: 7326e8394b8SKazutaka YOKOTA case KD_HERCULES: 7336e8394b8SKazutaka YOKOTA return M_EGAMONO80x25; /* XXX: this name is confusing */ 7346e8394b8SKazutaka YOKOTA 7356e8394b8SKazutaka YOKOTA default: 7366e8394b8SKazutaka YOKOTA break; 7376e8394b8SKazutaka YOKOTA } 7386e8394b8SKazutaka YOKOTA return -1; 7396e8394b8SKazutaka YOKOTA } 7406e8394b8SKazutaka YOKOTA 7416e8394b8SKazutaka YOKOTA /* look up a parameter table entry */ 7426e8394b8SKazutaka YOKOTA static u_char 7436e8394b8SKazutaka YOKOTA *get_mode_param(int mode) 7446e8394b8SKazutaka YOKOTA { 7456e8394b8SKazutaka YOKOTA #if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE) 7466e8394b8SKazutaka YOKOTA if (mode >= V_MODE_MAP_SIZE) 7476e8394b8SKazutaka YOKOTA mode = map_mode_num(mode); 7486e8394b8SKazutaka YOKOTA #endif 7496e8394b8SKazutaka YOKOTA if ((mode >= 0) && (mode < V_MODE_MAP_SIZE)) 7506e8394b8SKazutaka YOKOTA return mode_map[mode]; 7516e8394b8SKazutaka YOKOTA else 7526e8394b8SKazutaka YOKOTA return NULL; 7536e8394b8SKazutaka YOKOTA } 7546e8394b8SKazutaka YOKOTA 7556e8394b8SKazutaka YOKOTA #ifndef VGA_NO_BIOS 7566e8394b8SKazutaka YOKOTA static void 7576e8394b8SKazutaka YOKOTA fill_adapter_param(int code, video_adapter_t *adp) 7586e8394b8SKazutaka YOKOTA { 7596e8394b8SKazutaka YOKOTA static struct { 7606e8394b8SKazutaka YOKOTA int primary; 7616e8394b8SKazutaka YOKOTA int secondary; 7626e8394b8SKazutaka YOKOTA } dcc[] = { 7636e8394b8SKazutaka YOKOTA { DCC_MONO, DCC_EGA40 /* CGA monitor */ }, 7646e8394b8SKazutaka YOKOTA { DCC_MONO, DCC_EGA80 /* CGA monitor */ }, 765e066609fSKazutaka YOKOTA { DCC_MONO, DCC_EGA80 }, 7666e8394b8SKazutaka YOKOTA { DCC_MONO, DCC_EGA80 }, 7676e8394b8SKazutaka YOKOTA { DCC_CGA40, DCC_EGAMONO }, 7686e8394b8SKazutaka YOKOTA { DCC_CGA80, DCC_EGAMONO }, 7696e8394b8SKazutaka YOKOTA { DCC_EGA40 /* CGA monitor */, DCC_MONO}, 7706e8394b8SKazutaka YOKOTA { DCC_EGA80 /* CGA monitor */, DCC_MONO}, 771e066609fSKazutaka YOKOTA { DCC_EGA80, DCC_MONO }, 7726e8394b8SKazutaka YOKOTA { DCC_EGA80, DCC_MONO }, 7736e8394b8SKazutaka YOKOTA { DCC_EGAMONO, DCC_CGA40 }, 774e066609fSKazutaka YOKOTA { DCC_EGAMONO, DCC_CGA80 }, 7756e8394b8SKazutaka YOKOTA }; 7766e8394b8SKazutaka YOKOTA 777323b076eSPedro F. Giffuni if ((code < 0) || (code >= nitems(dcc))) { 7786e8394b8SKazutaka YOKOTA adp[V_ADP_PRIMARY] = adapter_init_value[DCC_MONO]; 7796e8394b8SKazutaka YOKOTA adp[V_ADP_SECONDARY] = adapter_init_value[DCC_CGA80]; 7806e8394b8SKazutaka YOKOTA } else { 7816e8394b8SKazutaka YOKOTA adp[V_ADP_PRIMARY] = adapter_init_value[dcc[code].primary]; 7826e8394b8SKazutaka YOKOTA adp[V_ADP_SECONDARY] = adapter_init_value[dcc[code].secondary]; 7836e8394b8SKazutaka YOKOTA } 7846e8394b8SKazutaka YOKOTA } 7856e8394b8SKazutaka YOKOTA #endif /* VGA_NO_BIOS */ 7866e8394b8SKazutaka YOKOTA 7876e8394b8SKazutaka YOKOTA static int 7886e8394b8SKazutaka YOKOTA verify_adapter(video_adapter_t *adp) 7896e8394b8SKazutaka YOKOTA { 7906e8394b8SKazutaka YOKOTA vm_offset_t buf; 7916e8394b8SKazutaka YOKOTA u_int16_t v; 7926e8394b8SKazutaka YOKOTA #if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE) 7936e8394b8SKazutaka YOKOTA u_int32_t p; 7946e8394b8SKazutaka YOKOTA #endif 7956e8394b8SKazutaka YOKOTA 7966e8394b8SKazutaka YOKOTA buf = BIOS_PADDRTOVADDR(adp->va_window); 7976e8394b8SKazutaka YOKOTA v = readw(buf); 7986e8394b8SKazutaka YOKOTA writew(buf, 0xA55A); 7996e8394b8SKazutaka YOKOTA if (readw(buf) != 0xA55A) 8006e8394b8SKazutaka YOKOTA return ENXIO; 8016e8394b8SKazutaka YOKOTA writew(buf, v); 8026e8394b8SKazutaka YOKOTA 8036e8394b8SKazutaka YOKOTA switch (adp->va_type) { 8046e8394b8SKazutaka YOKOTA 8056e8394b8SKazutaka YOKOTA case KD_EGA: 8066e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr, 7); 8076e8394b8SKazutaka YOKOTA if (inb(adp->va_crtc_addr) == 7) { 8086e8394b8SKazutaka YOKOTA adp->va_type = KD_VGA; 8096e8394b8SKazutaka YOKOTA adp->va_name = "vga"; 8106e8394b8SKazutaka YOKOTA adp->va_flags |= V_ADP_STATESAVE | V_ADP_PALETTE; 8116e8394b8SKazutaka YOKOTA } 8126e8394b8SKazutaka YOKOTA adp->va_flags |= V_ADP_STATELOAD | V_ADP_BORDER; 8136e8394b8SKazutaka YOKOTA /* the color adapter may be in the 40x25 mode... XXX */ 8146e8394b8SKazutaka YOKOTA 8156e8394b8SKazutaka YOKOTA #if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE) 8166e8394b8SKazutaka YOKOTA /* get the BIOS video mode pointer */ 8176e8394b8SKazutaka YOKOTA p = *(u_int32_t *)BIOS_PADDRTOVADDR(0x4a8); 8186e8394b8SKazutaka YOKOTA p = BIOS_SADDRTOLADDR(p); 8196e8394b8SKazutaka YOKOTA if (ISMAPPED(p, sizeof(u_int32_t))) { 8206e8394b8SKazutaka YOKOTA p = *(u_int32_t *)BIOS_PADDRTOVADDR(p); 8216e8394b8SKazutaka YOKOTA p = BIOS_SADDRTOLADDR(p); 8226e8394b8SKazutaka YOKOTA if (ISMAPPED(p, V_MODE_PARAM_SIZE)) 8236e8394b8SKazutaka YOKOTA video_mode_ptr = (u_char *)BIOS_PADDRTOVADDR(p); 8246e8394b8SKazutaka YOKOTA } 8256e8394b8SKazutaka YOKOTA #endif 8266e8394b8SKazutaka YOKOTA break; 8276e8394b8SKazutaka YOKOTA 8286e8394b8SKazutaka YOKOTA case KD_CGA: 8296e8394b8SKazutaka YOKOTA adp->va_flags |= V_ADP_COLOR | V_ADP_BORDER; 8306e8394b8SKazutaka YOKOTA /* may be in the 40x25 mode... XXX */ 8316e8394b8SKazutaka YOKOTA #if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE) 8326e8394b8SKazutaka YOKOTA /* get the BIOS video mode pointer */ 8336e8394b8SKazutaka YOKOTA p = *(u_int32_t *)BIOS_PADDRTOVADDR(0x1d*4); 8346e8394b8SKazutaka YOKOTA p = BIOS_SADDRTOLADDR(p); 8356e8394b8SKazutaka YOKOTA video_mode_ptr2 = (u_char *)BIOS_PADDRTOVADDR(p); 8366e8394b8SKazutaka YOKOTA #endif 8376e8394b8SKazutaka YOKOTA break; 8386e8394b8SKazutaka YOKOTA 8396e8394b8SKazutaka YOKOTA case KD_MONO: 8406e8394b8SKazutaka YOKOTA #if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE) 8416e8394b8SKazutaka YOKOTA /* get the BIOS video mode pointer */ 8426e8394b8SKazutaka YOKOTA p = *(u_int32_t *)BIOS_PADDRTOVADDR(0x1d*4); 8436e8394b8SKazutaka YOKOTA p = BIOS_SADDRTOLADDR(p); 8446e8394b8SKazutaka YOKOTA video_mode_ptr2 = (u_char *)BIOS_PADDRTOVADDR(p); 8456e8394b8SKazutaka YOKOTA #endif 8466e8394b8SKazutaka YOKOTA break; 8476e8394b8SKazutaka YOKOTA } 8486e8394b8SKazutaka YOKOTA 8496e8394b8SKazutaka YOKOTA return 0; 8506e8394b8SKazutaka YOKOTA } 8516e8394b8SKazutaka YOKOTA 8526e8394b8SKazutaka YOKOTA static void 8536e8394b8SKazutaka YOKOTA update_adapter_info(video_adapter_t *adp, video_info_t *info) 8546e8394b8SKazutaka YOKOTA { 8556e8394b8SKazutaka YOKOTA adp->va_flags &= ~V_ADP_COLOR; 8566e8394b8SKazutaka YOKOTA adp->va_flags |= 8576e8394b8SKazutaka YOKOTA (info->vi_flags & V_INFO_COLOR) ? V_ADP_COLOR : 0; 8586e8394b8SKazutaka YOKOTA adp->va_crtc_addr = 8596e8394b8SKazutaka YOKOTA (adp->va_flags & V_ADP_COLOR) ? COLOR_CRTC : MONO_CRTC; 8606e8394b8SKazutaka YOKOTA adp->va_window = BIOS_PADDRTOVADDR(info->vi_window); 8616e8394b8SKazutaka YOKOTA adp->va_window_size = info->vi_window_size; 8626e8394b8SKazutaka YOKOTA adp->va_window_gran = info->vi_window_gran; 8636e8394b8SKazutaka YOKOTA adp->va_window_orig = 0; 8646e8394b8SKazutaka YOKOTA /* XXX */ 8656e8394b8SKazutaka YOKOTA adp->va_buffer = info->vi_buffer; 8666e8394b8SKazutaka YOKOTA adp->va_buffer_size = info->vi_buffer_size; 867ecb56aafSBruce Evans adp->va_flags &= ~V_ADP_CWIDTH9; 868ecb56aafSBruce Evans if (info->vi_flags & V_INFO_CWIDTH9) 869ecb56aafSBruce Evans adp->va_flags |= V_ADP_CWIDTH9; 8702832e356SKazutaka YOKOTA if (info->vi_mem_model == V_INFO_MM_VGAX) { 8712832e356SKazutaka YOKOTA adp->va_line_width = info->vi_width/2; 8722832e356SKazutaka YOKOTA } else if (info->vi_flags & V_INFO_GRAPHICS) { 8736e8394b8SKazutaka YOKOTA switch (info->vi_depth/info->vi_planes) { 8746e8394b8SKazutaka YOKOTA case 1: 8756e8394b8SKazutaka YOKOTA adp->va_line_width = info->vi_width/8; 8766e8394b8SKazutaka YOKOTA break; 8776e8394b8SKazutaka YOKOTA case 2: 8786e8394b8SKazutaka YOKOTA adp->va_line_width = info->vi_width/4; 8796e8394b8SKazutaka YOKOTA break; 8806e8394b8SKazutaka YOKOTA case 4: 8816e8394b8SKazutaka YOKOTA adp->va_line_width = info->vi_width/2; 8826e8394b8SKazutaka YOKOTA break; 8836e8394b8SKazutaka YOKOTA case 8: 8846e8394b8SKazutaka YOKOTA default: /* shouldn't happen */ 8856e8394b8SKazutaka YOKOTA adp->va_line_width = info->vi_width; 8866e8394b8SKazutaka YOKOTA break; 8876e8394b8SKazutaka YOKOTA } 8886e8394b8SKazutaka YOKOTA } else { 8896e8394b8SKazutaka YOKOTA adp->va_line_width = info->vi_width; 8906e8394b8SKazutaka YOKOTA } 8916e8394b8SKazutaka YOKOTA adp->va_disp_start.x = 0; 8926e8394b8SKazutaka YOKOTA adp->va_disp_start.y = 0; 8936e8394b8SKazutaka YOKOTA bcopy(info, &adp->va_info, sizeof(adp->va_info)); 8946e8394b8SKazutaka YOKOTA } 8956e8394b8SKazutaka YOKOTA 8966e8394b8SKazutaka YOKOTA #if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE) 8976e8394b8SKazutaka YOKOTA /* compare two parameter table entries */ 8986e8394b8SKazutaka YOKOTA static int 8996e8394b8SKazutaka YOKOTA comp_adpregs(u_char *buf1, u_char *buf2) 9006e8394b8SKazutaka YOKOTA { 9016e8394b8SKazutaka YOKOTA static struct { 9026e8394b8SKazutaka YOKOTA u_char mask; 9036e8394b8SKazutaka YOKOTA } params[V_MODE_PARAM_SIZE] = { 9046e8394b8SKazutaka YOKOTA {0xff}, {0x00}, {0xff}, /* COLS}, ROWS}, POINTS */ 9056e8394b8SKazutaka YOKOTA {0x00}, {0x00}, /* page length */ 9066e8394b8SKazutaka YOKOTA {0xfe}, {0xff}, {0xff}, {0xff}, /* sequencer registers */ 9076e8394b8SKazutaka YOKOTA {0xf3}, /* misc register */ 9086e8394b8SKazutaka YOKOTA {0xff}, {0xff}, {0xff}, {0x7f}, {0xff}, /* CRTC */ 9096e8394b8SKazutaka YOKOTA {0xff}, {0xff}, {0xff}, {0x7f}, {0xff}, 9106e8394b8SKazutaka YOKOTA {0x00}, {0x00}, {0x00}, {0x00}, {0x00}, 9116e8394b8SKazutaka YOKOTA {0x00}, {0xff}, {0x7f}, {0xff}, {0xff}, 9126e8394b8SKazutaka YOKOTA {0x7f}, {0xff}, {0xff}, {0xef}, {0xff}, 9136e8394b8SKazutaka YOKOTA {0xff}, {0xff}, {0xff}, {0xff}, {0xff}, /* attribute controller regs */ 9146e8394b8SKazutaka YOKOTA {0xff}, {0xff}, {0xff}, {0xff}, {0xff}, 9156e8394b8SKazutaka YOKOTA {0xff}, {0xff}, {0xff}, {0xff}, {0xff}, 9166e8394b8SKazutaka YOKOTA {0xff}, {0xff}, {0xff}, {0xff}, {0xf0}, 9176e8394b8SKazutaka YOKOTA {0xff}, {0xff}, {0xff}, {0xff}, {0xff}, /* GDC register */ 9186e8394b8SKazutaka YOKOTA {0xff}, {0xff}, {0xff}, {0xff}, 9196e8394b8SKazutaka YOKOTA }; 9206e8394b8SKazutaka YOKOTA int identical = TRUE; 9216e8394b8SKazutaka YOKOTA int i; 9226e8394b8SKazutaka YOKOTA 9236e8394b8SKazutaka YOKOTA if ((buf1 == NULL) || (buf2 == NULL)) 9246e8394b8SKazutaka YOKOTA return COMP_DIFFERENT; 9256e8394b8SKazutaka YOKOTA 926323b076eSPedro F. Giffuni for (i = 0; i < nitems(params); ++i) { 9276e8394b8SKazutaka YOKOTA if (params[i].mask == 0) /* don't care */ 9286e8394b8SKazutaka YOKOTA continue; 9296e8394b8SKazutaka YOKOTA if ((buf1[i] & params[i].mask) != (buf2[i] & params[i].mask)) 9306e8394b8SKazutaka YOKOTA return COMP_DIFFERENT; 9316e8394b8SKazutaka YOKOTA if (buf1[i] != buf2[i]) 9326e8394b8SKazutaka YOKOTA identical = FALSE; 9336e8394b8SKazutaka YOKOTA } 9346e8394b8SKazutaka YOKOTA return (identical) ? COMP_IDENTICAL : COMP_SIMILAR; 9356e8394b8SKazutaka YOKOTA } 9366e8394b8SKazutaka YOKOTA #endif /* !VGA_NO_BIOS && !VGA_NO_MODE_CHANGE */ 9376e8394b8SKazutaka YOKOTA 9386e8394b8SKazutaka YOKOTA /* probe video adapters and return the number of detected adapters */ 9396e8394b8SKazutaka YOKOTA static int 9406e8394b8SKazutaka YOKOTA probe_adapters(void) 9416e8394b8SKazutaka YOKOTA { 9426e8394b8SKazutaka YOKOTA video_adapter_t *adp; 9436e8394b8SKazutaka YOKOTA video_info_t info; 9446e8394b8SKazutaka YOKOTA #if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE) 9456e8394b8SKazutaka YOKOTA u_char *mp; 9466e8394b8SKazutaka YOKOTA #endif 9477b8306bcSBruce Evans int height, i, width; 9486e8394b8SKazutaka YOKOTA 9496e8394b8SKazutaka YOKOTA /* do this test only once */ 9506e8394b8SKazutaka YOKOTA if (vga_init_done) 9516e8394b8SKazutaka YOKOTA return biosadapters; 9526e8394b8SKazutaka YOKOTA vga_init_done = TRUE; 9536e8394b8SKazutaka YOKOTA 9546e8394b8SKazutaka YOKOTA /* 9556e8394b8SKazutaka YOKOTA * Locate display adapters. 9566e8394b8SKazutaka YOKOTA * The AT architecture supports up to two adapters. `syscons' allows 9576e8394b8SKazutaka YOKOTA * the following combinations of adapters: 9586e8394b8SKazutaka YOKOTA * 1) MDA + CGA 9596e8394b8SKazutaka YOKOTA * 2) MDA + EGA/VGA color 9606e8394b8SKazutaka YOKOTA * 3) CGA + EGA/VGA mono 9616e8394b8SKazutaka YOKOTA * Note that `syscons' doesn't bother with MCGA as it is only 9626e8394b8SKazutaka YOKOTA * avaiable for low end PS/2 models which has 80286 or earlier CPUs, 9636e8394b8SKazutaka YOKOTA * thus, they are not running FreeBSD! 9646e8394b8SKazutaka YOKOTA * When there are two adapaters in the system, one becomes `primary' 9656e8394b8SKazutaka YOKOTA * and the other `secondary'. The EGA adapter has a set of DIP 9666e8394b8SKazutaka YOKOTA * switches on board for this information and the EGA BIOS copies 9676e8394b8SKazutaka YOKOTA * it in the BIOS data area BIOSDATA_VIDEOSWITCH (40:88). 9686e8394b8SKazutaka YOKOTA * The VGA BIOS has more sophisticated mechanism and has this 9696e8394b8SKazutaka YOKOTA * information in BIOSDATA_DCCINDEX (40:8a), but it also maintains 9706e8394b8SKazutaka YOKOTA * compatibility with the EGA BIOS by updating BIOSDATA_VIDEOSWITCH. 9716e8394b8SKazutaka YOKOTA */ 9726e8394b8SKazutaka YOKOTA 9736e8394b8SKazutaka YOKOTA /* 9746e8394b8SKazutaka YOKOTA * Check rtc and BIOS data area. 9756e8394b8SKazutaka YOKOTA * XXX: we don't use BIOSDATA_EQUIPMENT, since it is not a dead 9766e8394b8SKazutaka YOKOTA * copy of RTC_EQUIPMENT. Bits 4 and 5 of ETC_EQUIPMENT are 9776e8394b8SKazutaka YOKOTA * zeros for EGA and VGA. However, the EGA/VGA BIOS sets 9786e8394b8SKazutaka YOKOTA * these bits in BIOSDATA_EQUIPMENT according to the monitor 9796e8394b8SKazutaka YOKOTA * type detected. 9806e8394b8SKazutaka YOKOTA */ 9816e8394b8SKazutaka YOKOTA #ifndef VGA_NO_BIOS 9824d00f042SKazutaka YOKOTA if (*(u_int32_t *)BIOS_PADDRTOVADDR(0x4a8)) { 9834d00f042SKazutaka YOKOTA /* EGA/VGA BIOS is present */ 9844d00f042SKazutaka YOKOTA fill_adapter_param(readb(BIOS_PADDRTOVADDR(0x488)) & 0x0f, 9854d00f042SKazutaka YOKOTA biosadapter); 9864d00f042SKazutaka YOKOTA } else { 9876e8394b8SKazutaka YOKOTA switch ((rtcin(RTC_EQUIPMENT) >> 4) & 3) { /* bit 4 and 5 */ 9886e8394b8SKazutaka YOKOTA case 0: 9894d00f042SKazutaka YOKOTA /* EGA/VGA: shouldn't be happening */ 9906e8394b8SKazutaka YOKOTA fill_adapter_param(readb(BIOS_PADDRTOVADDR(0x488)) & 0x0f, 9916e8394b8SKazutaka YOKOTA biosadapter); 9926e8394b8SKazutaka YOKOTA break; 9936e8394b8SKazutaka YOKOTA case 1: 9946e8394b8SKazutaka YOKOTA /* CGA 40x25 */ 9956e8394b8SKazutaka YOKOTA /* FIXME: switch to the 80x25 mode? XXX */ 9966e8394b8SKazutaka YOKOTA biosadapter[V_ADP_PRIMARY] = adapter_init_value[DCC_CGA40]; 9976e8394b8SKazutaka YOKOTA biosadapter[V_ADP_SECONDARY] = adapter_init_value[DCC_MONO]; 9986e8394b8SKazutaka YOKOTA break; 9996e8394b8SKazutaka YOKOTA case 2: 10006e8394b8SKazutaka YOKOTA /* CGA 80x25 */ 10016e8394b8SKazutaka YOKOTA biosadapter[V_ADP_PRIMARY] = adapter_init_value[DCC_CGA80]; 10026e8394b8SKazutaka YOKOTA biosadapter[V_ADP_SECONDARY] = adapter_init_value[DCC_MONO]; 10036e8394b8SKazutaka YOKOTA break; 10046e8394b8SKazutaka YOKOTA case 3: 10056e8394b8SKazutaka YOKOTA /* MDA */ 10066e8394b8SKazutaka YOKOTA biosadapter[V_ADP_PRIMARY] = adapter_init_value[DCC_MONO]; 10076e8394b8SKazutaka YOKOTA biosadapter[V_ADP_SECONDARY] = adapter_init_value[DCC_CGA80]; 10086e8394b8SKazutaka YOKOTA break; 10096e8394b8SKazutaka YOKOTA } 10104d00f042SKazutaka YOKOTA } 10116e8394b8SKazutaka YOKOTA #else 10126e8394b8SKazutaka YOKOTA /* assume EGA/VGA? XXX */ 10136e8394b8SKazutaka YOKOTA biosadapter[V_ADP_PRIMARY] = adapter_init_value[DCC_EGA80]; 10146e8394b8SKazutaka YOKOTA biosadapter[V_ADP_SECONDARY] = adapter_init_value[DCC_MONO]; 10156e8394b8SKazutaka YOKOTA #endif /* VGA_NO_BIOS */ 10166e8394b8SKazutaka YOKOTA 10176e8394b8SKazutaka YOKOTA biosadapters = 0; 10186e8394b8SKazutaka YOKOTA if (verify_adapter(&biosadapter[V_ADP_SECONDARY]) == 0) { 10196e8394b8SKazutaka YOKOTA ++biosadapters; 10206e8394b8SKazutaka YOKOTA biosadapter[V_ADP_SECONDARY].va_flags |= V_ADP_PROBED; 10216e8394b8SKazutaka YOKOTA biosadapter[V_ADP_SECONDARY].va_mode = 10226e8394b8SKazutaka YOKOTA biosadapter[V_ADP_SECONDARY].va_initial_mode = 10236e8394b8SKazutaka YOKOTA map_bios_mode_num(biosadapter[V_ADP_SECONDARY].va_type, 10246e8394b8SKazutaka YOKOTA biosadapter[V_ADP_SECONDARY].va_flags 10256e8394b8SKazutaka YOKOTA & V_ADP_COLOR, 10266e8394b8SKazutaka YOKOTA biosadapter[V_ADP_SECONDARY].va_initial_bios_mode); 10276e8394b8SKazutaka YOKOTA } else { 10286e8394b8SKazutaka YOKOTA biosadapter[V_ADP_SECONDARY].va_type = -1; 10296e8394b8SKazutaka YOKOTA } 10306e8394b8SKazutaka YOKOTA if (verify_adapter(&biosadapter[V_ADP_PRIMARY]) == 0) { 10316e8394b8SKazutaka YOKOTA ++biosadapters; 10326e8394b8SKazutaka YOKOTA biosadapter[V_ADP_PRIMARY].va_flags |= V_ADP_PROBED; 10336e8394b8SKazutaka YOKOTA #ifndef VGA_NO_BIOS 10346e8394b8SKazutaka YOKOTA biosadapter[V_ADP_PRIMARY].va_initial_bios_mode = 10356e8394b8SKazutaka YOKOTA readb(BIOS_PADDRTOVADDR(0x449)); 10366e8394b8SKazutaka YOKOTA #else 10376e8394b8SKazutaka YOKOTA biosadapter[V_ADP_PRIMARY].va_initial_bios_mode = 3; /* XXX */ 10386e8394b8SKazutaka YOKOTA #endif 10396e8394b8SKazutaka YOKOTA biosadapter[V_ADP_PRIMARY].va_mode = 10406e8394b8SKazutaka YOKOTA biosadapter[V_ADP_PRIMARY].va_initial_mode = 10416e8394b8SKazutaka YOKOTA map_bios_mode_num(biosadapter[V_ADP_PRIMARY].va_type, 10426e8394b8SKazutaka YOKOTA biosadapter[V_ADP_PRIMARY].va_flags & V_ADP_COLOR, 10436e8394b8SKazutaka YOKOTA biosadapter[V_ADP_PRIMARY].va_initial_bios_mode); 10446e8394b8SKazutaka YOKOTA } else { 10456e8394b8SKazutaka YOKOTA biosadapter[V_ADP_PRIMARY] = biosadapter[V_ADP_SECONDARY]; 10466e8394b8SKazutaka YOKOTA biosadapter[V_ADP_SECONDARY].va_type = -1; 10476e8394b8SKazutaka YOKOTA } 10486e8394b8SKazutaka YOKOTA if (biosadapters == 0) 10496e8394b8SKazutaka YOKOTA return biosadapters; 10506e8394b8SKazutaka YOKOTA biosadapter[V_ADP_PRIMARY].va_unit = V_ADP_PRIMARY; 10516e8394b8SKazutaka YOKOTA biosadapter[V_ADP_SECONDARY].va_unit = V_ADP_SECONDARY; 10526e8394b8SKazutaka YOKOTA 10536e8394b8SKazutaka YOKOTA #if 0 /* we don't need these... */ 10546e8394b8SKazutaka YOKOTA fb_init_struct(&biosadapter[V_ADP_PRIMARY], ...); 10556e8394b8SKazutaka YOKOTA fb_init_struct(&biosadapter[V_ADP_SECONDARY], ...); 10566e8394b8SKazutaka YOKOTA #endif 10576e8394b8SKazutaka YOKOTA 1058f4e98881SRuslan Ermilov #ifdef notyet 10596e8394b8SKazutaka YOKOTA /* 10606e8394b8SKazutaka YOKOTA * We cannot have two video adapter of the same type; there must be 10616e8394b8SKazutaka YOKOTA * only one of color or mono adapter, or one each of them. 10626e8394b8SKazutaka YOKOTA */ 10636e8394b8SKazutaka YOKOTA if (biosadapters > 1) { 10646e8394b8SKazutaka YOKOTA if (!((biosadapter[0].va_flags ^ biosadapter[1].va_flags) 10656e8394b8SKazutaka YOKOTA & V_ADP_COLOR)) 10666e8394b8SKazutaka YOKOTA /* we have two mono or color adapters!! */ 10676e8394b8SKazutaka YOKOTA return (biosadapters = 0); 10686e8394b8SKazutaka YOKOTA } 10696e8394b8SKazutaka YOKOTA #endif 10706e8394b8SKazutaka YOKOTA 10716e8394b8SKazutaka YOKOTA /* 10722ce7d7a0SPoul-Henning Kamp * Ensure a zero start address. The registers are w/o 10736e8394b8SKazutaka YOKOTA * for old hardware so it's too hard to relocate the active screen 10746e8394b8SKazutaka YOKOTA * memory. 10756e8394b8SKazutaka YOKOTA * This must be done before vga_save_state() for VGA. 10766e8394b8SKazutaka YOKOTA */ 10776e8394b8SKazutaka YOKOTA outb(biosadapter[V_ADP_PRIMARY].va_crtc_addr, 12); 10786e8394b8SKazutaka YOKOTA outb(biosadapter[V_ADP_PRIMARY].va_crtc_addr + 1, 0); 10796e8394b8SKazutaka YOKOTA outb(biosadapter[V_ADP_PRIMARY].va_crtc_addr, 13); 10806e8394b8SKazutaka YOKOTA outb(biosadapter[V_ADP_PRIMARY].va_crtc_addr + 1, 0); 10816e8394b8SKazutaka YOKOTA 10826e8394b8SKazutaka YOKOTA /* the video mode parameter table in EGA/VGA BIOS */ 10836e8394b8SKazutaka YOKOTA /* NOTE: there can be only one EGA/VGA, wheather color or mono, 10846e8394b8SKazutaka YOKOTA * recognized by the video BIOS. 10856e8394b8SKazutaka YOKOTA */ 10866e8394b8SKazutaka YOKOTA if ((biosadapter[V_ADP_PRIMARY].va_type == KD_EGA) || 10876e8394b8SKazutaka YOKOTA (biosadapter[V_ADP_PRIMARY].va_type == KD_VGA)) { 10886e8394b8SKazutaka YOKOTA adp = &biosadapter[V_ADP_PRIMARY]; 10896e8394b8SKazutaka YOKOTA } else if ((biosadapter[V_ADP_SECONDARY].va_type == KD_EGA) || 10906e8394b8SKazutaka YOKOTA (biosadapter[V_ADP_SECONDARY].va_type == KD_VGA)) { 10916e8394b8SKazutaka YOKOTA adp = &biosadapter[V_ADP_SECONDARY]; 10926e8394b8SKazutaka YOKOTA } else { 10936e8394b8SKazutaka YOKOTA adp = NULL; 10946e8394b8SKazutaka YOKOTA } 10956e8394b8SKazutaka YOKOTA bzero(mode_map, sizeof(mode_map)); 10966e8394b8SKazutaka YOKOTA if (adp != NULL) { 10976e8394b8SKazutaka YOKOTA if (adp->va_type == KD_VGA) { 10986e8394b8SKazutaka YOKOTA vga_save_state(adp, &adpstate, sizeof(adpstate)); 10996e8394b8SKazutaka YOKOTA #if defined(VGA_NO_BIOS) || defined(VGA_NO_MODE_CHANGE) 11006e8394b8SKazutaka YOKOTA mode_map[adp->va_initial_mode] = adpstate.regs; 11016e8394b8SKazutaka YOKOTA rows_offset = 1; 11026e8394b8SKazutaka YOKOTA #else /* VGA_NO_BIOS || VGA_NO_MODE_CHANGE */ 11036e8394b8SKazutaka YOKOTA if (video_mode_ptr == NULL) { 11046e8394b8SKazutaka YOKOTA mode_map[adp->va_initial_mode] = adpstate.regs; 11056e8394b8SKazutaka YOKOTA rows_offset = 1; 11066e8394b8SKazutaka YOKOTA } else { 11076e8394b8SKazutaka YOKOTA /* discard the table if we are not familiar with it... */ 11086e8394b8SKazutaka YOKOTA map_mode_table(mode_map, video_mode_ptr, M_VGA_CG320 + 1); 11096e8394b8SKazutaka YOKOTA mp = get_mode_param(adp->va_initial_mode); 11106e8394b8SKazutaka YOKOTA if (mp != NULL) 11116e8394b8SKazutaka YOKOTA bcopy(mp, adpstate2.regs, sizeof(adpstate2.regs)); 11126e8394b8SKazutaka YOKOTA switch (comp_adpregs(adpstate.regs, mp)) { 11136e8394b8SKazutaka YOKOTA case COMP_IDENTICAL: 11146e8394b8SKazutaka YOKOTA /* 11156e8394b8SKazutaka YOKOTA * OK, this parameter table looks reasonably familiar 11166e8394b8SKazutaka YOKOTA * to us... 11176e8394b8SKazutaka YOKOTA */ 11186e8394b8SKazutaka YOKOTA /* 11196e8394b8SKazutaka YOKOTA * This is a kludge for Toshiba DynaBook SS433 11206e8394b8SKazutaka YOKOTA * whose BIOS video mode table entry has the actual # 11216e8394b8SKazutaka YOKOTA * of rows at the offset 1; BIOSes from other 11226e8394b8SKazutaka YOKOTA * manufacturers store the # of rows - 1 there. XXX 11236e8394b8SKazutaka YOKOTA */ 11246e8394b8SKazutaka YOKOTA rows_offset = adpstate.regs[1] + 1 - mp[1]; 11256e8394b8SKazutaka YOKOTA break; 11266e8394b8SKazutaka YOKOTA 11276e8394b8SKazutaka YOKOTA case COMP_SIMILAR: 11286e8394b8SKazutaka YOKOTA /* 11296e8394b8SKazutaka YOKOTA * Not exactly the same, but similar enough to be 11306e8394b8SKazutaka YOKOTA * trusted. However, use the saved register values 11316e8394b8SKazutaka YOKOTA * for the initial mode and other modes which are 11326e8394b8SKazutaka YOKOTA * based on the initial mode. 11336e8394b8SKazutaka YOKOTA */ 11346e8394b8SKazutaka YOKOTA mode_map[adp->va_initial_mode] = adpstate.regs; 11356e8394b8SKazutaka YOKOTA rows_offset = adpstate.regs[1] + 1 - mp[1]; 11366e8394b8SKazutaka YOKOTA adpstate.regs[1] -= rows_offset - 1; 11376e8394b8SKazutaka YOKOTA break; 11386e8394b8SKazutaka YOKOTA 11396e8394b8SKazutaka YOKOTA case COMP_DIFFERENT: 11406e8394b8SKazutaka YOKOTA default: 11416e8394b8SKazutaka YOKOTA /* 11427b8306bcSBruce Evans * Don't use the parameter table in the BIOS, since 11437b8306bcSBruce Evans * even the BIOS doesn't use it for the initial mode. 11447b8306bcSBruce Evans * Restrict the tweaked modes to (in practice) 80x50 11457b8306bcSBruce Evans * from 80x25 with 400 scan lines, since the only safe 11467b8306bcSBruce Evans * tweak is changing the characters from 8x16 to 8x8. 11476e8394b8SKazutaka YOKOTA */ 11486e8394b8SKazutaka YOKOTA video_mode_ptr = NULL; 11496e8394b8SKazutaka YOKOTA bzero(mode_map, sizeof(mode_map)); 11506e8394b8SKazutaka YOKOTA mode_map[adp->va_initial_mode] = adpstate.regs; 11516e8394b8SKazutaka YOKOTA rows_offset = 1; 11527b8306bcSBruce Evans 11537b8306bcSBruce Evans width = height = -1; 11547b8306bcSBruce Evans for (i = 0; i < nitems(bios_vmode); ++i) { 11557b8306bcSBruce Evans if (bios_vmode[i].vi_mode == adp->va_initial_mode) { 11567b8306bcSBruce Evans width = bios_vmode[i].vi_width; 11577b8306bcSBruce Evans height = bios_vmode[i].vi_height; 11587b8306bcSBruce Evans break; 11597b8306bcSBruce Evans } 11607b8306bcSBruce Evans } 11617b8306bcSBruce Evans for (i = 0; i < nitems(bios_vmode); ++i) { 11627b8306bcSBruce Evans if (bios_vmode[i].vi_mode != adp->va_initial_mode && 11637b8306bcSBruce Evans map_mode_num(bios_vmode[i].vi_mode) == 11647b8306bcSBruce Evans adp->va_initial_mode && 11657b8306bcSBruce Evans (bios_vmode[i].vi_width != width || 11667b8306bcSBruce Evans bios_vmode[i].vi_height != 2 * height)) { 11677b8306bcSBruce Evans bios_vmode[i].vi_mode = NA; 11687b8306bcSBruce Evans } 11697b8306bcSBruce Evans } 11706e8394b8SKazutaka YOKOTA break; 11716e8394b8SKazutaka YOKOTA } 11726e8394b8SKazutaka YOKOTA } 11736e8394b8SKazutaka YOKOTA #endif /* VGA_NO_BIOS || VGA_NO_MODE_CHANGE */ 11746e8394b8SKazutaka YOKOTA 11756e8394b8SKazutaka YOKOTA #ifndef VGA_NO_MODE_CHANGE 11766e8394b8SKazutaka YOKOTA adp->va_flags |= V_ADP_MODECHANGE; 11776e8394b8SKazutaka YOKOTA #endif 11786e8394b8SKazutaka YOKOTA #ifndef VGA_NO_FONT_LOADING 11796e8394b8SKazutaka YOKOTA adp->va_flags |= V_ADP_FONT; 11806e8394b8SKazutaka YOKOTA #endif 11816e8394b8SKazutaka YOKOTA } else if (adp->va_type == KD_EGA) { 11826e8394b8SKazutaka YOKOTA #if defined(VGA_NO_BIOS) || defined(VGA_NO_MODE_CHANGE) 11836e8394b8SKazutaka YOKOTA rows_offset = 1; 11846e8394b8SKazutaka YOKOTA #else /* VGA_NO_BIOS || VGA_NO_MODE_CHANGE */ 11856e8394b8SKazutaka YOKOTA if (video_mode_ptr == NULL) { 11866e8394b8SKazutaka YOKOTA rows_offset = 1; 11876e8394b8SKazutaka YOKOTA } else { 11886e8394b8SKazutaka YOKOTA map_mode_table(mode_map, video_mode_ptr, M_ENH_C80x25 + 1); 11896e8394b8SKazutaka YOKOTA /* XXX how can one validate the EGA table... */ 11906e8394b8SKazutaka YOKOTA mp = get_mode_param(adp->va_initial_mode); 11916e8394b8SKazutaka YOKOTA if (mp != NULL) { 11926e8394b8SKazutaka YOKOTA adp->va_flags |= V_ADP_MODECHANGE; 11936e8394b8SKazutaka YOKOTA #ifndef VGA_NO_FONT_LOADING 11946e8394b8SKazutaka YOKOTA adp->va_flags |= V_ADP_FONT; 11956e8394b8SKazutaka YOKOTA #endif 11966e8394b8SKazutaka YOKOTA rows_offset = 1; 11976e8394b8SKazutaka YOKOTA } else { 11986e8394b8SKazutaka YOKOTA /* 11996e8394b8SKazutaka YOKOTA * This is serious. We will not be able to switch video 12006e8394b8SKazutaka YOKOTA * modes at all... 12016e8394b8SKazutaka YOKOTA */ 12026e8394b8SKazutaka YOKOTA video_mode_ptr = NULL; 12036e8394b8SKazutaka YOKOTA bzero(mode_map, sizeof(mode_map)); 12046e8394b8SKazutaka YOKOTA rows_offset = 1; 12056e8394b8SKazutaka YOKOTA } 12066e8394b8SKazutaka YOKOTA } 12076e8394b8SKazutaka YOKOTA #endif /* VGA_NO_BIOS || VGA_NO_MODE_CHANGE */ 12086e8394b8SKazutaka YOKOTA } 12096e8394b8SKazutaka YOKOTA } 12106e8394b8SKazutaka YOKOTA 12116e8394b8SKazutaka YOKOTA /* remove conflicting modes if we have more than one adapter */ 1212f0aac6a5SDoug Rabson if (biosadapters > 0) { 12136e8394b8SKazutaka YOKOTA for (i = 0; i < biosadapters; ++i) { 12146e8394b8SKazutaka YOKOTA if (!(biosadapter[i].va_flags & V_ADP_MODECHANGE)) 12156e8394b8SKazutaka YOKOTA continue; 12166e8394b8SKazutaka YOKOTA clear_mode_map(&biosadapter[i], mode_map, M_VGA_CG320 + 1, 12176e8394b8SKazutaka YOKOTA (biosadapter[i].va_flags & V_ADP_COLOR) ? 12186e8394b8SKazutaka YOKOTA V_INFO_COLOR : 0); 12196e8394b8SKazutaka YOKOTA if ((biosadapter[i].va_type == KD_VGA) 12206e8394b8SKazutaka YOKOTA || (biosadapter[i].va_type == KD_EGA)) { 12216e8394b8SKazutaka YOKOTA biosadapter[i].va_io_base = 12226e8394b8SKazutaka YOKOTA (biosadapter[i].va_flags & V_ADP_COLOR) ? 12236e8394b8SKazutaka YOKOTA IO_VGA : IO_MDA; 12246e8394b8SKazutaka YOKOTA biosadapter[i].va_io_size = 32; 12256e8394b8SKazutaka YOKOTA } 12266e8394b8SKazutaka YOKOTA } 12276e8394b8SKazutaka YOKOTA } 12286e8394b8SKazutaka YOKOTA 1229ecb56aafSBruce Evans #if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE) 1230ecb56aafSBruce Evans /* 1231ecb56aafSBruce Evans * Attempt to determine the real character width for each mode. 9 wide 1232ecb56aafSBruce Evans * is supposed to be standard for EGA mono mode and most VGA text modes, 1233ecb56aafSBruce Evans * but some hardware doesn't support it, so dynamic configuration is 1234ecb56aafSBruce Evans * needed. Bit 0 in sequencer register 1 is supposed control the width 1235ecb56aafSBruce Evans * (set = 8), but this is unreliable too. Trust that 0 in the sequencer 1236ecb56aafSBruce Evans * bit means 9 wide after verifying that 9 is consistent with some CRTC 1237ecb56aafSBruce Evans * timing. The ratio (Horizontal Total) / (Horizontal Displayed) is 1238ecb56aafSBruce Evans * about 1.2 in all standard 9-wide modes and should be about 9/8 larger 1239ecb56aafSBruce Evans * again in similar 8-wide modes; in practice it is usually about 1.4 1240ecb56aafSBruce Evans * times larger. 1241ecb56aafSBruce Evans */ 1242ecb56aafSBruce Evans for (i = 0; i < nitems(bios_vmode); ++i) { 1243ecb56aafSBruce Evans if (bios_vmode[i].vi_mem_model == V_INFO_MM_TEXT && 1244ecb56aafSBruce Evans bios_vmode[i].vi_width != 90) { 1245ecb56aafSBruce Evans mp = get_mode_param(map_mode_num(bios_vmode[i].vi_mode)); 1246ecb56aafSBruce Evans if (mp != NULL && !(mp[5] & 1) && mp[10] <= mp[11] * 125 / 100) 1247ecb56aafSBruce Evans bios_vmode[i].vi_flags |= V_INFO_CWIDTH9; 1248ecb56aafSBruce Evans } 1249ecb56aafSBruce Evans } 1250ecb56aafSBruce Evans #endif 1251ecb56aafSBruce Evans 12526e8394b8SKazutaka YOKOTA /* buffer address */ 12536e8394b8SKazutaka YOKOTA vga_get_info(&biosadapter[V_ADP_PRIMARY], 12546e8394b8SKazutaka YOKOTA biosadapter[V_ADP_PRIMARY].va_initial_mode, &info); 12556e8394b8SKazutaka YOKOTA info.vi_flags &= ~V_INFO_LINEAR; /* XXX */ 12566e8394b8SKazutaka YOKOTA update_adapter_info(&biosadapter[V_ADP_PRIMARY], &info); 12576e8394b8SKazutaka YOKOTA 12586e8394b8SKazutaka YOKOTA if (biosadapters > 1) { 12596e8394b8SKazutaka YOKOTA vga_get_info(&biosadapter[V_ADP_SECONDARY], 12606e8394b8SKazutaka YOKOTA biosadapter[V_ADP_SECONDARY].va_initial_mode, &info); 12616e8394b8SKazutaka YOKOTA info.vi_flags &= ~V_INFO_LINEAR; /* XXX */ 12626e8394b8SKazutaka YOKOTA update_adapter_info(&biosadapter[V_ADP_SECONDARY], &info); 12636e8394b8SKazutaka YOKOTA } 12646e8394b8SKazutaka YOKOTA 12656e8394b8SKazutaka YOKOTA /* 12666e8394b8SKazutaka YOKOTA * XXX: we should verify the following values for the primary adapter... 12676e8394b8SKazutaka YOKOTA * crtc I/O port address: *(u_int16_t *)BIOS_PADDRTOVADDR(0x463); 12686e8394b8SKazutaka YOKOTA * color/mono display: (*(u_int8_t *)BIOS_PADDRTOVADDR(0x487) & 0x02) 12696e8394b8SKazutaka YOKOTA * ? 0 : V_ADP_COLOR; 12706e8394b8SKazutaka YOKOTA * columns: *(u_int8_t *)BIOS_PADDRTOVADDR(0x44a); 12716e8394b8SKazutaka YOKOTA * rows: *(u_int8_t *)BIOS_PADDRTOVADDR(0x484); 12726e8394b8SKazutaka YOKOTA * font size: *(u_int8_t *)BIOS_PADDRTOVADDR(0x485); 12736e8394b8SKazutaka YOKOTA * buffer size: *(u_int16_t *)BIOS_PADDRTOVADDR(0x44c); 12746e8394b8SKazutaka YOKOTA */ 12756e8394b8SKazutaka YOKOTA 12766e8394b8SKazutaka YOKOTA return biosadapters; 12776e8394b8SKazutaka YOKOTA } 12786e8394b8SKazutaka YOKOTA 12796e8394b8SKazutaka YOKOTA /* set the scan line length in pixel */ 12806e8394b8SKazutaka YOKOTA static int 12816e8394b8SKazutaka YOKOTA set_line_length(video_adapter_t *adp, int pixel) 12826e8394b8SKazutaka YOKOTA { 12836e8394b8SKazutaka YOKOTA u_char *mp; 12846e8394b8SKazutaka YOKOTA int ppw; /* pixels per word */ 12856e8394b8SKazutaka YOKOTA int bpl; /* bytes per line */ 12866e8394b8SKazutaka YOKOTA int count; 12876e8394b8SKazutaka YOKOTA 12886e8394b8SKazutaka YOKOTA if ((adp->va_type != KD_VGA) && (adp->va_type != KD_EGA)) 12896e8394b8SKazutaka YOKOTA return ENODEV; 12906e8394b8SKazutaka YOKOTA mp = get_mode_param(adp->va_mode); 12916e8394b8SKazutaka YOKOTA if (mp == NULL) 12926e8394b8SKazutaka YOKOTA return EINVAL; 12936e8394b8SKazutaka YOKOTA 12946e8394b8SKazutaka YOKOTA switch (adp->va_info.vi_mem_model) { 12956e8394b8SKazutaka YOKOTA case V_INFO_MM_PLANAR: 12966e8394b8SKazutaka YOKOTA ppw = 16/(adp->va_info.vi_depth/adp->va_info.vi_planes); 1297057b4402SPedro F. Giffuni count = howmany(pixel, ppw)/2; 1298057b4402SPedro F. Giffuni bpl = (howmany(pixel, ppw)/2)*4; 12996e8394b8SKazutaka YOKOTA break; 13006e8394b8SKazutaka YOKOTA case V_INFO_MM_PACKED: 13016e8394b8SKazutaka YOKOTA count = (pixel + 7)/8; 13024ed3c0e7SPedro F. Giffuni bpl = rounddown(pixel + 7, 8); 13036e8394b8SKazutaka YOKOTA break; 13046e8394b8SKazutaka YOKOTA case V_INFO_MM_TEXT: 13056e8394b8SKazutaka YOKOTA count = (pixel + 7)/8; /* columns */ 13066e8394b8SKazutaka YOKOTA bpl = (pixel + 7)/8; /* columns */ 13076e8394b8SKazutaka YOKOTA break; 13086e8394b8SKazutaka YOKOTA default: 13096e8394b8SKazutaka YOKOTA return ENODEV; 13106e8394b8SKazutaka YOKOTA } 13116e8394b8SKazutaka YOKOTA 13126e8394b8SKazutaka YOKOTA if (mp[10 + 0x17] & 0x40) /* CRTC mode control reg */ 13136e8394b8SKazutaka YOKOTA count *= 2; /* byte mode */ 13146e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr, 0x13); 13156e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr + 1, count); 13166e8394b8SKazutaka YOKOTA adp->va_line_width = bpl; 13176e8394b8SKazutaka YOKOTA 13186e8394b8SKazutaka YOKOTA return 0; 13196e8394b8SKazutaka YOKOTA } 13206e8394b8SKazutaka YOKOTA 13216e8394b8SKazutaka YOKOTA static int 13226e8394b8SKazutaka YOKOTA set_display_start(video_adapter_t *adp, int x, int y) 13236e8394b8SKazutaka YOKOTA { 13246e8394b8SKazutaka YOKOTA int off; /* byte offset (graphics mode)/word offset (text mode) */ 13256e8394b8SKazutaka YOKOTA int poff; /* pixel offset */ 13266e8394b8SKazutaka YOKOTA int roff; /* row offset */ 13276e8394b8SKazutaka YOKOTA int ppb; /* pixels per byte */ 13286e8394b8SKazutaka YOKOTA 13296e8394b8SKazutaka YOKOTA if ((adp->va_type != KD_VGA) && (adp->va_type != KD_EGA)) 13306e8394b8SKazutaka YOKOTA x &= ~7; 13316e8394b8SKazutaka YOKOTA if (adp->va_info.vi_flags & V_INFO_GRAPHICS) { 13326e8394b8SKazutaka YOKOTA ppb = 8/(adp->va_info.vi_depth/adp->va_info.vi_planes); 13336e8394b8SKazutaka YOKOTA off = y*adp->va_line_width + x/ppb; 13346e8394b8SKazutaka YOKOTA roff = 0; 13356e8394b8SKazutaka YOKOTA poff = x%ppb; 13366e8394b8SKazutaka YOKOTA } else { 13376e8394b8SKazutaka YOKOTA if ((adp->va_type == KD_VGA) || (adp->va_type == KD_EGA)) { 13386e8394b8SKazutaka YOKOTA outb(TSIDX, 1); 13396e8394b8SKazutaka YOKOTA if (inb(TSREG) & 1) 13406e8394b8SKazutaka YOKOTA ppb = 9; 13416e8394b8SKazutaka YOKOTA else 13426e8394b8SKazutaka YOKOTA ppb = 8; 13436e8394b8SKazutaka YOKOTA } else { 13446e8394b8SKazutaka YOKOTA ppb = 8; 13456e8394b8SKazutaka YOKOTA } 13466e8394b8SKazutaka YOKOTA off = y/adp->va_info.vi_cheight*adp->va_line_width + x/ppb; 13476e8394b8SKazutaka YOKOTA roff = y%adp->va_info.vi_cheight; 13486e8394b8SKazutaka YOKOTA /* FIXME: is this correct? XXX */ 13496e8394b8SKazutaka YOKOTA if (ppb == 8) 13506e8394b8SKazutaka YOKOTA poff = x%ppb; 13516e8394b8SKazutaka YOKOTA else 13526e8394b8SKazutaka YOKOTA poff = (x + 8)%ppb; 13536e8394b8SKazutaka YOKOTA } 13546e8394b8SKazutaka YOKOTA 13556e8394b8SKazutaka YOKOTA /* start address */ 13566e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr, 0xc); /* high */ 13576e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr + 1, off >> 8); 13586e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr, 0xd); /* low */ 13596e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr + 1, off & 0xff); 13606e8394b8SKazutaka YOKOTA 13616e8394b8SKazutaka YOKOTA /* horizontal pel pan */ 13626e8394b8SKazutaka YOKOTA if ((adp->va_type == KD_VGA) || (adp->va_type == KD_EGA)) { 13636e8394b8SKazutaka YOKOTA inb(adp->va_crtc_addr + 6); 13646e8394b8SKazutaka YOKOTA outb(ATC, 0x13 | 0x20); 13656e8394b8SKazutaka YOKOTA outb(ATC, poff); 13666e8394b8SKazutaka YOKOTA inb(adp->va_crtc_addr + 6); 13676e8394b8SKazutaka YOKOTA outb(ATC, 0x20); 13686e8394b8SKazutaka YOKOTA } 13696e8394b8SKazutaka YOKOTA 13706e8394b8SKazutaka YOKOTA /* preset raw scan */ 13716e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr, 8); 13726e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr + 1, roff); 13736e8394b8SKazutaka YOKOTA 13746e8394b8SKazutaka YOKOTA adp->va_disp_start.x = x; 13756e8394b8SKazutaka YOKOTA adp->va_disp_start.y = y; 13766e8394b8SKazutaka YOKOTA return 0; 13776e8394b8SKazutaka YOKOTA } 13786e8394b8SKazutaka YOKOTA 1379b7b28d26SRuslan Ermilov #ifndef VGA_NO_MODE_CHANGE 13808c376570SPeter Wemm #if defined(__i386__) || defined(__amd64__) /* XXX */ 13816e8394b8SKazutaka YOKOTA static void 13826e8394b8SKazutaka YOKOTA fill(int val, void *d, size_t size) 13836e8394b8SKazutaka YOKOTA { 13846e8394b8SKazutaka YOKOTA u_char *p = d; 13856e8394b8SKazutaka YOKOTA 13866e8394b8SKazutaka YOKOTA while (size-- > 0) 13876e8394b8SKazutaka YOKOTA *p++ = val; 13886e8394b8SKazutaka YOKOTA } 13896e8394b8SKazutaka YOKOTA #endif /* __i386__ */ 13906e8394b8SKazutaka YOKOTA 13916e8394b8SKazutaka YOKOTA static void 13926e8394b8SKazutaka YOKOTA filll_io(int val, vm_offset_t d, size_t size) 13936e8394b8SKazutaka YOKOTA { 13946e8394b8SKazutaka YOKOTA while (size-- > 0) { 13956e8394b8SKazutaka YOKOTA writel(d, val); 13966e8394b8SKazutaka YOKOTA d += sizeof(u_int32_t); 13976e8394b8SKazutaka YOKOTA } 13986e8394b8SKazutaka YOKOTA } 1399b7b28d26SRuslan Ermilov #endif /* !VGA_NO_MODE_CHANGE */ 14006e8394b8SKazutaka YOKOTA 14016e8394b8SKazutaka YOKOTA /* entry points */ 14026e8394b8SKazutaka YOKOTA 14030fc85147SPeter Wemm #if 0 14046e8394b8SKazutaka YOKOTA static int 14056e8394b8SKazutaka YOKOTA vga_nop(void) 14066e8394b8SKazutaka YOKOTA { 14076e8394b8SKazutaka YOKOTA return 0; 14086e8394b8SKazutaka YOKOTA } 14090fc85147SPeter Wemm #endif 14106e8394b8SKazutaka YOKOTA 14116e8394b8SKazutaka YOKOTA static int 14126e8394b8SKazutaka YOKOTA vga_error(void) 14136e8394b8SKazutaka YOKOTA { 14146e8394b8SKazutaka YOKOTA return ENODEV; 14156e8394b8SKazutaka YOKOTA } 14166e8394b8SKazutaka YOKOTA 14176e8394b8SKazutaka YOKOTA static int 14186e8394b8SKazutaka YOKOTA vga_probe(int unit, video_adapter_t **adpp, void *arg, int flags) 14196e8394b8SKazutaka YOKOTA { 14206e8394b8SKazutaka YOKOTA probe_adapters(); 14216e8394b8SKazutaka YOKOTA if (unit >= biosadapters) 14226e8394b8SKazutaka YOKOTA return ENXIO; 14236e8394b8SKazutaka YOKOTA 14246e8394b8SKazutaka YOKOTA *adpp = &biosadapter[unit]; 14256e8394b8SKazutaka YOKOTA 14266e8394b8SKazutaka YOKOTA return 0; 14276e8394b8SKazutaka YOKOTA } 14286e8394b8SKazutaka YOKOTA 14296e8394b8SKazutaka YOKOTA static int 14306e8394b8SKazutaka YOKOTA vga_init(int unit, video_adapter_t *adp, int flags) 14316e8394b8SKazutaka YOKOTA { 14326e8394b8SKazutaka YOKOTA if ((unit >= biosadapters) || (adp == NULL) || !probe_done(adp)) 14336e8394b8SKazutaka YOKOTA return ENXIO; 14346e8394b8SKazutaka YOKOTA 14356e8394b8SKazutaka YOKOTA if (!init_done(adp)) { 14366e8394b8SKazutaka YOKOTA /* nothing to do really... */ 14376e8394b8SKazutaka YOKOTA adp->va_flags |= V_ADP_INITIALIZED; 14386e8394b8SKazutaka YOKOTA } 14396e8394b8SKazutaka YOKOTA 14406e8394b8SKazutaka YOKOTA if (!config_done(adp)) { 14416e8394b8SKazutaka YOKOTA if (vid_register(adp) < 0) 14426e8394b8SKazutaka YOKOTA return ENXIO; 14436e8394b8SKazutaka YOKOTA adp->va_flags |= V_ADP_REGISTERED; 14446e8394b8SKazutaka YOKOTA } 14456e8394b8SKazutaka YOKOTA if (vga_sub_configure != NULL) 14466e8394b8SKazutaka YOKOTA (*vga_sub_configure)(0); 14476e8394b8SKazutaka YOKOTA 14486e8394b8SKazutaka YOKOTA return 0; 14496e8394b8SKazutaka YOKOTA } 14506e8394b8SKazutaka YOKOTA 14516e8394b8SKazutaka YOKOTA /* 14526e8394b8SKazutaka YOKOTA * get_info(): 14536e8394b8SKazutaka YOKOTA * Return the video_info structure of the requested video mode. 14546e8394b8SKazutaka YOKOTA * 14556e8394b8SKazutaka YOKOTA * all adapters 14566e8394b8SKazutaka YOKOTA */ 14576e8394b8SKazutaka YOKOTA static int 14586e8394b8SKazutaka YOKOTA vga_get_info(video_adapter_t *adp, int mode, video_info_t *info) 14596e8394b8SKazutaka YOKOTA { 14606e8394b8SKazutaka YOKOTA int i; 14616e8394b8SKazutaka YOKOTA 14626e8394b8SKazutaka YOKOTA if (!vga_init_done) 14636e8394b8SKazutaka YOKOTA return ENXIO; 14646e8394b8SKazutaka YOKOTA 14656e8394b8SKazutaka YOKOTA mode = map_gen_mode_num(adp->va_type, adp->va_flags & V_ADP_COLOR, mode); 14666e8394b8SKazutaka YOKOTA #ifndef VGA_NO_MODE_CHANGE 14676e8394b8SKazutaka YOKOTA if (adp->va_flags & V_ADP_MODECHANGE) { 14686e8394b8SKazutaka YOKOTA /* 14696e8394b8SKazutaka YOKOTA * If the parameter table entry for this mode is not found, 14706e8394b8SKazutaka YOKOTA * the mode is not supported... 14716e8394b8SKazutaka YOKOTA */ 14726e8394b8SKazutaka YOKOTA if (get_mode_param(mode) == NULL) 14736e8394b8SKazutaka YOKOTA return EINVAL; 14746e8394b8SKazutaka YOKOTA } else 14756e8394b8SKazutaka YOKOTA #endif /* VGA_NO_MODE_CHANGE */ 14766e8394b8SKazutaka YOKOTA { 14776e8394b8SKazutaka YOKOTA /* 14786e8394b8SKazutaka YOKOTA * Even if we don't support video mode switching on this adapter, 14796e8394b8SKazutaka YOKOTA * the information on the initial (thus current) video mode 14806e8394b8SKazutaka YOKOTA * should be made available. 14816e8394b8SKazutaka YOKOTA */ 14826e8394b8SKazutaka YOKOTA if (mode != adp->va_initial_mode) 14836e8394b8SKazutaka YOKOTA return EINVAL; 14846e8394b8SKazutaka YOKOTA } 14856e8394b8SKazutaka YOKOTA 14866e8394b8SKazutaka YOKOTA for (i = 0; bios_vmode[i].vi_mode != EOT; ++i) { 14876e8394b8SKazutaka YOKOTA if (bios_vmode[i].vi_mode == NA) 14886e8394b8SKazutaka YOKOTA continue; 14896e8394b8SKazutaka YOKOTA if (mode == bios_vmode[i].vi_mode) { 14906e8394b8SKazutaka YOKOTA *info = bios_vmode[i]; 14916e8394b8SKazutaka YOKOTA /* XXX */ 14926e8394b8SKazutaka YOKOTA info->vi_buffer_size = info->vi_window_size*info->vi_planes; 14936e8394b8SKazutaka YOKOTA return 0; 14946e8394b8SKazutaka YOKOTA } 14956e8394b8SKazutaka YOKOTA } 14966e8394b8SKazutaka YOKOTA return EINVAL; 14976e8394b8SKazutaka YOKOTA } 14986e8394b8SKazutaka YOKOTA 14996e8394b8SKazutaka YOKOTA /* 15006e8394b8SKazutaka YOKOTA * query_mode(): 15016e8394b8SKazutaka YOKOTA * Find a video mode matching the requested parameters. 15026e8394b8SKazutaka YOKOTA * Fields filled with 0 are considered "don't care" fields and 15036e8394b8SKazutaka YOKOTA * match any modes. 15046e8394b8SKazutaka YOKOTA * 15056e8394b8SKazutaka YOKOTA * all adapters 15066e8394b8SKazutaka YOKOTA */ 15076e8394b8SKazutaka YOKOTA static int 15086e8394b8SKazutaka YOKOTA vga_query_mode(video_adapter_t *adp, video_info_t *info) 15096e8394b8SKazutaka YOKOTA { 15106e8394b8SKazutaka YOKOTA int i; 15116e8394b8SKazutaka YOKOTA 15126e8394b8SKazutaka YOKOTA if (!vga_init_done) 15130be01624SKazutaka YOKOTA return ENXIO; 15146e8394b8SKazutaka YOKOTA 15156e8394b8SKazutaka YOKOTA for (i = 0; bios_vmode[i].vi_mode != EOT; ++i) { 15166e8394b8SKazutaka YOKOTA if (bios_vmode[i].vi_mode == NA) 15176e8394b8SKazutaka YOKOTA continue; 15186e8394b8SKazutaka YOKOTA 15196e8394b8SKazutaka YOKOTA if ((info->vi_width != 0) 15206e8394b8SKazutaka YOKOTA && (info->vi_width != bios_vmode[i].vi_width)) 15216e8394b8SKazutaka YOKOTA continue; 15226e8394b8SKazutaka YOKOTA if ((info->vi_height != 0) 15236e8394b8SKazutaka YOKOTA && (info->vi_height != bios_vmode[i].vi_height)) 15246e8394b8SKazutaka YOKOTA continue; 15256e8394b8SKazutaka YOKOTA if ((info->vi_cwidth != 0) 15266e8394b8SKazutaka YOKOTA && (info->vi_cwidth != bios_vmode[i].vi_cwidth)) 15276e8394b8SKazutaka YOKOTA continue; 15286e8394b8SKazutaka YOKOTA if ((info->vi_cheight != 0) 15296e8394b8SKazutaka YOKOTA && (info->vi_cheight != bios_vmode[i].vi_cheight)) 15306e8394b8SKazutaka YOKOTA continue; 15316e8394b8SKazutaka YOKOTA if ((info->vi_depth != 0) 15326e8394b8SKazutaka YOKOTA && (info->vi_depth != bios_vmode[i].vi_depth)) 15336e8394b8SKazutaka YOKOTA continue; 15346e8394b8SKazutaka YOKOTA if ((info->vi_planes != 0) 15356e8394b8SKazutaka YOKOTA && (info->vi_planes != bios_vmode[i].vi_planes)) 15366e8394b8SKazutaka YOKOTA continue; 15376e8394b8SKazutaka YOKOTA /* XXX: should check pixel format, memory model */ 15386e8394b8SKazutaka YOKOTA if ((info->vi_flags != 0) 15396e8394b8SKazutaka YOKOTA && (info->vi_flags != bios_vmode[i].vi_flags)) 15406e8394b8SKazutaka YOKOTA continue; 15416e8394b8SKazutaka YOKOTA 15426e8394b8SKazutaka YOKOTA /* verify if this mode is supported on this adapter */ 15430be01624SKazutaka YOKOTA if (vga_get_info(adp, bios_vmode[i].vi_mode, info)) 15446e8394b8SKazutaka YOKOTA continue; 15450be01624SKazutaka YOKOTA return 0; 15466e8394b8SKazutaka YOKOTA } 15470be01624SKazutaka YOKOTA return ENODEV; 15486e8394b8SKazutaka YOKOTA } 15496e8394b8SKazutaka YOKOTA 15506e8394b8SKazutaka YOKOTA /* 15516e8394b8SKazutaka YOKOTA * set_mode(): 15526e8394b8SKazutaka YOKOTA * Change the video mode. 15536e8394b8SKazutaka YOKOTA * 15546e8394b8SKazutaka YOKOTA * EGA/VGA 15556e8394b8SKazutaka YOKOTA */ 15566e8394b8SKazutaka YOKOTA 15576e8394b8SKazutaka YOKOTA #ifndef VGA_NO_MODE_CHANGE 15586e8394b8SKazutaka YOKOTA #ifdef VGA_WIDTH90 15596e8394b8SKazutaka YOKOTA static void 15606e8394b8SKazutaka YOKOTA set_width90(adp_state_t *params) 15616e8394b8SKazutaka YOKOTA { 15626e8394b8SKazutaka YOKOTA /* 15636e8394b8SKazutaka YOKOTA * Based on code submitted by Kelly Yancey (kbyanc@freedomnet.com) 15646e8394b8SKazutaka YOKOTA * and alexv@sui.gda.itesm.mx. 15656e8394b8SKazutaka YOKOTA */ 15666e8394b8SKazutaka YOKOTA params->regs[5] |= 1; /* toggle 8 pixel wide fonts */ 15676e8394b8SKazutaka YOKOTA params->regs[10+0x0] = 0x6b; 15686e8394b8SKazutaka YOKOTA params->regs[10+0x1] = 0x59; 15696e8394b8SKazutaka YOKOTA params->regs[10+0x2] = 0x5a; 15706e8394b8SKazutaka YOKOTA params->regs[10+0x3] = 0x8e; 15716e8394b8SKazutaka YOKOTA params->regs[10+0x4] = 0x5e; 15726e8394b8SKazutaka YOKOTA params->regs[10+0x5] = 0x8a; 15736e8394b8SKazutaka YOKOTA params->regs[10+0x13] = 45; 15746e8394b8SKazutaka YOKOTA params->regs[35+0x13] = 0; 15756e8394b8SKazutaka YOKOTA } 15766e8394b8SKazutaka YOKOTA #endif /* VGA_WIDTH90 */ 15776e8394b8SKazutaka YOKOTA #endif /* !VGA_NO_MODE_CHANGE */ 15786e8394b8SKazutaka YOKOTA 15796e8394b8SKazutaka YOKOTA static int 15806e8394b8SKazutaka YOKOTA vga_set_mode(video_adapter_t *adp, int mode) 15816e8394b8SKazutaka YOKOTA { 15826e8394b8SKazutaka YOKOTA #ifndef VGA_NO_MODE_CHANGE 15836e8394b8SKazutaka YOKOTA video_info_t info; 15846e8394b8SKazutaka YOKOTA adp_state_t params; 15856e8394b8SKazutaka YOKOTA 15866e8394b8SKazutaka YOKOTA prologue(adp, V_ADP_MODECHANGE, ENODEV); 15876e8394b8SKazutaka YOKOTA 15886e8394b8SKazutaka YOKOTA mode = map_gen_mode_num(adp->va_type, 15896e8394b8SKazutaka YOKOTA adp->va_flags & V_ADP_COLOR, mode); 15906e8394b8SKazutaka YOKOTA if (vga_get_info(adp, mode, &info)) 15916e8394b8SKazutaka YOKOTA return EINVAL; 15926e8394b8SKazutaka YOKOTA 15936e8394b8SKazutaka YOKOTA #if VGA_DEBUG > 1 15946e8394b8SKazutaka YOKOTA printf("vga_set_mode(): setting mode %d\n", mode); 15956e8394b8SKazutaka YOKOTA #endif 15966e8394b8SKazutaka YOKOTA 15976e8394b8SKazutaka YOKOTA params.sig = V_STATE_SIG; 15986e8394b8SKazutaka YOKOTA bcopy(get_mode_param(mode), params.regs, sizeof(params.regs)); 15996e8394b8SKazutaka YOKOTA 16006e8394b8SKazutaka YOKOTA switch (mode) { 16016e8394b8SKazutaka YOKOTA #ifdef VGA_WIDTH90 16026e8394b8SKazutaka YOKOTA case M_VGA_C90x60: case M_VGA_M90x60: 16036e8394b8SKazutaka YOKOTA set_width90(¶ms); 16046e8394b8SKazutaka YOKOTA /* FALLTHROUGH */ 16056e8394b8SKazutaka YOKOTA #endif 16066e8394b8SKazutaka YOKOTA case M_VGA_C80x60: case M_VGA_M80x60: 16076e8394b8SKazutaka YOKOTA params.regs[2] = 0x08; 16086e8394b8SKazutaka YOKOTA params.regs[19] = 0x47; 16096e8394b8SKazutaka YOKOTA goto special_480l; 16106e8394b8SKazutaka YOKOTA 16116e8394b8SKazutaka YOKOTA #ifdef VGA_WIDTH90 16126e8394b8SKazutaka YOKOTA case M_VGA_C90x30: case M_VGA_M90x30: 16136e8394b8SKazutaka YOKOTA set_width90(¶ms); 16146e8394b8SKazutaka YOKOTA /* FALLTHROUGH */ 16156e8394b8SKazutaka YOKOTA #endif 16166e8394b8SKazutaka YOKOTA case M_VGA_C80x30: case M_VGA_M80x30: 16176e8394b8SKazutaka YOKOTA params.regs[19] = 0x4f; 16186e8394b8SKazutaka YOKOTA special_480l: 16196e8394b8SKazutaka YOKOTA params.regs[9] |= 0xc0; 16206e8394b8SKazutaka YOKOTA params.regs[16] = 0x08; 16216e8394b8SKazutaka YOKOTA params.regs[17] = 0x3e; 16226e8394b8SKazutaka YOKOTA params.regs[26] = 0xea; 16236e8394b8SKazutaka YOKOTA params.regs[28] = 0xdf; 16246e8394b8SKazutaka YOKOTA params.regs[31] = 0xe7; 16256e8394b8SKazutaka YOKOTA params.regs[32] = 0x04; 16266e8394b8SKazutaka YOKOTA goto setup_mode; 16276e8394b8SKazutaka YOKOTA 16286e8394b8SKazutaka YOKOTA #ifdef VGA_WIDTH90 16296e8394b8SKazutaka YOKOTA case M_VGA_C90x43: case M_VGA_M90x43: 16306e8394b8SKazutaka YOKOTA set_width90(¶ms); 16316e8394b8SKazutaka YOKOTA /* FALLTHROUGH */ 16326e8394b8SKazutaka YOKOTA #endif 16336e8394b8SKazutaka YOKOTA case M_ENH_C80x43: case M_ENH_B80x43: 16346e8394b8SKazutaka YOKOTA params.regs[28] = 87; 16356e8394b8SKazutaka YOKOTA goto special_80x50; 16366e8394b8SKazutaka YOKOTA 16376e8394b8SKazutaka YOKOTA #ifdef VGA_WIDTH90 16386e8394b8SKazutaka YOKOTA case M_VGA_C90x50: case M_VGA_M90x50: 16396e8394b8SKazutaka YOKOTA set_width90(¶ms); 16406e8394b8SKazutaka YOKOTA /* FALLTHROUGH */ 16416e8394b8SKazutaka YOKOTA #endif 16426e8394b8SKazutaka YOKOTA case M_VGA_C80x50: case M_VGA_M80x50: 16436e8394b8SKazutaka YOKOTA special_80x50: 16446e8394b8SKazutaka YOKOTA params.regs[2] = 8; 16456e8394b8SKazutaka YOKOTA params.regs[19] = 7; 16466e8394b8SKazutaka YOKOTA goto setup_mode; 16476e8394b8SKazutaka YOKOTA 16486e8394b8SKazutaka YOKOTA #ifdef VGA_WIDTH90 16496e8394b8SKazutaka YOKOTA case M_VGA_C90x25: case M_VGA_M90x25: 16506e8394b8SKazutaka YOKOTA set_width90(¶ms); 16516e8394b8SKazutaka YOKOTA /* FALLTHROUGH */ 16526e8394b8SKazutaka YOKOTA #endif 16536e8394b8SKazutaka YOKOTA case M_VGA_C40x25: case M_VGA_C80x25: 16546e8394b8SKazutaka YOKOTA case M_VGA_M80x25: 16556e8394b8SKazutaka YOKOTA case M_B40x25: case M_C40x25: 16566e8394b8SKazutaka YOKOTA case M_B80x25: case M_C80x25: 16576e8394b8SKazutaka YOKOTA case M_ENH_B40x25: case M_ENH_C40x25: 16586e8394b8SKazutaka YOKOTA case M_ENH_B80x25: case M_ENH_C80x25: 16596e8394b8SKazutaka YOKOTA case M_EGAMONO80x25: 16606e8394b8SKazutaka YOKOTA 16616e8394b8SKazutaka YOKOTA setup_mode: 16626e8394b8SKazutaka YOKOTA vga_load_state(adp, ¶ms); 16636e8394b8SKazutaka YOKOTA break; 16646e8394b8SKazutaka YOKOTA 16656e8394b8SKazutaka YOKOTA case M_VGA_MODEX: 16666e8394b8SKazutaka YOKOTA /* "unchain" the VGA mode */ 16676e8394b8SKazutaka YOKOTA params.regs[5-1+0x04] &= 0xf7; 16686e8394b8SKazutaka YOKOTA params.regs[5-1+0x04] |= 0x04; 16696e8394b8SKazutaka YOKOTA /* turn off doubleword mode */ 16706e8394b8SKazutaka YOKOTA params.regs[10+0x14] &= 0xbf; 167156bded8aSKris Kennaway /* turn off word addressing */ 16726e8394b8SKazutaka YOKOTA params.regs[10+0x17] |= 0x40; 16736e8394b8SKazutaka YOKOTA /* set logical screen width */ 16746e8394b8SKazutaka YOKOTA params.regs[10+0x13] = 80; 16756e8394b8SKazutaka YOKOTA /* set 240 lines */ 16766e8394b8SKazutaka YOKOTA params.regs[10+0x11] = 0x2c; 16776e8394b8SKazutaka YOKOTA params.regs[10+0x06] = 0x0d; 16786e8394b8SKazutaka YOKOTA params.regs[10+0x07] = 0x3e; 16796e8394b8SKazutaka YOKOTA params.regs[10+0x10] = 0xea; 16806e8394b8SKazutaka YOKOTA params.regs[10+0x11] = 0xac; 16816e8394b8SKazutaka YOKOTA params.regs[10+0x12] = 0xdf; 16826e8394b8SKazutaka YOKOTA params.regs[10+0x15] = 0xe7; 16836e8394b8SKazutaka YOKOTA params.regs[10+0x16] = 0x06; 16846e8394b8SKazutaka YOKOTA /* set vertical sync polarity to reflect aspect ratio */ 16856e8394b8SKazutaka YOKOTA params.regs[9] = 0xe3; 16866e8394b8SKazutaka YOKOTA goto setup_grmode; 16876e8394b8SKazutaka YOKOTA 16886e8394b8SKazutaka YOKOTA case M_BG320: case M_CG320: case M_BG640: 16896e8394b8SKazutaka YOKOTA case M_CG320_D: case M_CG640_E: 16906e8394b8SKazutaka YOKOTA case M_CG640x350: case M_ENH_CG640: 16916e8394b8SKazutaka YOKOTA case M_BG640x480: case M_CG640x480: case M_VGA_CG320: 16926e8394b8SKazutaka YOKOTA 16936e8394b8SKazutaka YOKOTA setup_grmode: 16946e8394b8SKazutaka YOKOTA vga_load_state(adp, ¶ms); 16956e8394b8SKazutaka YOKOTA break; 16966e8394b8SKazutaka YOKOTA 16976e8394b8SKazutaka YOKOTA default: 16986e8394b8SKazutaka YOKOTA return EINVAL; 16996e8394b8SKazutaka YOKOTA } 17006e8394b8SKazutaka YOKOTA 17016e8394b8SKazutaka YOKOTA adp->va_mode = mode; 17026e8394b8SKazutaka YOKOTA info.vi_flags &= ~V_INFO_LINEAR; /* XXX */ 17036e8394b8SKazutaka YOKOTA update_adapter_info(adp, &info); 17046e8394b8SKazutaka YOKOTA 17056e8394b8SKazutaka YOKOTA /* move hardware cursor out of the way */ 17069336e069SWojciech A. Koszek vidd_set_hw_cursor(adp, -1, -1); 17076e8394b8SKazutaka YOKOTA 17086e8394b8SKazutaka YOKOTA return 0; 17096e8394b8SKazutaka YOKOTA #else /* VGA_NO_MODE_CHANGE */ 17106e8394b8SKazutaka YOKOTA return ENODEV; 17116e8394b8SKazutaka YOKOTA #endif /* VGA_NO_MODE_CHANGE */ 17126e8394b8SKazutaka YOKOTA } 17136e8394b8SKazutaka YOKOTA 17146e8394b8SKazutaka YOKOTA #ifndef VGA_NO_FONT_LOADING 17156e8394b8SKazutaka YOKOTA 17166e8394b8SKazutaka YOKOTA static void 17176e8394b8SKazutaka YOKOTA set_font_mode(video_adapter_t *adp, u_char *buf) 17186e8394b8SKazutaka YOKOTA { 17196e8394b8SKazutaka YOKOTA u_char *mp; 17206e8394b8SKazutaka YOKOTA int s; 17216e8394b8SKazutaka YOKOTA 17226e8394b8SKazutaka YOKOTA s = splhigh(); 17236e8394b8SKazutaka YOKOTA 17246e8394b8SKazutaka YOKOTA /* save register values */ 17256e8394b8SKazutaka YOKOTA if (adp->va_type == KD_VGA) { 17266e8394b8SKazutaka YOKOTA outb(TSIDX, 0x02); buf[0] = inb(TSREG); 17276e8394b8SKazutaka YOKOTA outb(TSIDX, 0x04); buf[1] = inb(TSREG); 17286e8394b8SKazutaka YOKOTA outb(GDCIDX, 0x04); buf[2] = inb(GDCREG); 17296e8394b8SKazutaka YOKOTA outb(GDCIDX, 0x05); buf[3] = inb(GDCREG); 17306e8394b8SKazutaka YOKOTA outb(GDCIDX, 0x06); buf[4] = inb(GDCREG); 17316e8394b8SKazutaka YOKOTA inb(adp->va_crtc_addr + 6); 17326e8394b8SKazutaka YOKOTA outb(ATC, 0x10); buf[5] = inb(ATC + 1); 17336e8394b8SKazutaka YOKOTA } else /* if (adp->va_type == KD_EGA) */ { 17346e8394b8SKazutaka YOKOTA /* 17356e8394b8SKazutaka YOKOTA * EGA cannot be read; copy parameters from the mode parameter 17366e8394b8SKazutaka YOKOTA * table. 17376e8394b8SKazutaka YOKOTA */ 17386e8394b8SKazutaka YOKOTA mp = get_mode_param(adp->va_mode); 17396e8394b8SKazutaka YOKOTA buf[0] = mp[5 + 0x02 - 1]; 17406e8394b8SKazutaka YOKOTA buf[1] = mp[5 + 0x04 - 1]; 17416e8394b8SKazutaka YOKOTA buf[2] = mp[55 + 0x04]; 17426e8394b8SKazutaka YOKOTA buf[3] = mp[55 + 0x05]; 17436e8394b8SKazutaka YOKOTA buf[4] = mp[55 + 0x06]; 17446e8394b8SKazutaka YOKOTA buf[5] = mp[35 + 0x10]; 17456e8394b8SKazutaka YOKOTA } 17466e8394b8SKazutaka YOKOTA 17476e8394b8SKazutaka YOKOTA /* setup vga for loading fonts */ 17486e8394b8SKazutaka YOKOTA inb(adp->va_crtc_addr + 6); /* reset flip-flop */ 17496e8394b8SKazutaka YOKOTA outb(ATC, 0x10); outb(ATC, buf[5] & ~0x01); 17506e8394b8SKazutaka YOKOTA inb(adp->va_crtc_addr + 6); /* reset flip-flop */ 17516e8394b8SKazutaka YOKOTA outb(ATC, 0x20); /* enable palette */ 17526e8394b8SKazutaka YOKOTA 1753f4e98881SRuslan Ermilov #ifdef VGA_SLOW_IOACCESS 17546e8394b8SKazutaka YOKOTA #ifdef VGA_ALT_SEQACCESS 17556e8394b8SKazutaka YOKOTA outb(TSIDX, 0x00); outb(TSREG, 0x01); 17566e8394b8SKazutaka YOKOTA #endif 17576e8394b8SKazutaka YOKOTA outb(TSIDX, 0x02); outb(TSREG, 0x04); 17586e8394b8SKazutaka YOKOTA outb(TSIDX, 0x04); outb(TSREG, 0x07); 17596e8394b8SKazutaka YOKOTA #ifdef VGA_ALT_SEQACCESS 17606e8394b8SKazutaka YOKOTA outb(TSIDX, 0x00); outb(TSREG, 0x03); 17616e8394b8SKazutaka YOKOTA #endif 17626e8394b8SKazutaka YOKOTA outb(GDCIDX, 0x04); outb(GDCREG, 0x02); 17636e8394b8SKazutaka YOKOTA outb(GDCIDX, 0x05); outb(GDCREG, 0x00); 17646e8394b8SKazutaka YOKOTA outb(GDCIDX, 0x06); outb(GDCREG, 0x04); 17656e8394b8SKazutaka YOKOTA #else /* VGA_SLOW_IOACCESS */ 17666e8394b8SKazutaka YOKOTA #ifdef VGA_ALT_SEQACCESS 17676e8394b8SKazutaka YOKOTA outw(TSIDX, 0x0100); 17686e8394b8SKazutaka YOKOTA #endif 17696e8394b8SKazutaka YOKOTA outw(TSIDX, 0x0402); 17706e8394b8SKazutaka YOKOTA outw(TSIDX, 0x0704); 17716e8394b8SKazutaka YOKOTA #ifdef VGA_ALT_SEQACCESS 17726e8394b8SKazutaka YOKOTA outw(TSIDX, 0x0300); 17736e8394b8SKazutaka YOKOTA #endif 17746e8394b8SKazutaka YOKOTA outw(GDCIDX, 0x0204); 17756e8394b8SKazutaka YOKOTA outw(GDCIDX, 0x0005); 17766e8394b8SKazutaka YOKOTA outw(GDCIDX, 0x0406); /* addr = a0000, 64kb */ 17776e8394b8SKazutaka YOKOTA #endif /* VGA_SLOW_IOACCESS */ 17786e8394b8SKazutaka YOKOTA 17796e8394b8SKazutaka YOKOTA splx(s); 17806e8394b8SKazutaka YOKOTA } 17816e8394b8SKazutaka YOKOTA 17826e8394b8SKazutaka YOKOTA static void 17836e8394b8SKazutaka YOKOTA set_normal_mode(video_adapter_t *adp, u_char *buf) 17846e8394b8SKazutaka YOKOTA { 17856e8394b8SKazutaka YOKOTA int s; 17866e8394b8SKazutaka YOKOTA 17876e8394b8SKazutaka YOKOTA s = splhigh(); 17886e8394b8SKazutaka YOKOTA 17896e8394b8SKazutaka YOKOTA /* setup vga for normal operation mode again */ 17906e8394b8SKazutaka YOKOTA inb(adp->va_crtc_addr + 6); /* reset flip-flop */ 17916e8394b8SKazutaka YOKOTA outb(ATC, 0x10); outb(ATC, buf[5]); 17926e8394b8SKazutaka YOKOTA inb(adp->va_crtc_addr + 6); /* reset flip-flop */ 17936e8394b8SKazutaka YOKOTA outb(ATC, 0x20); /* enable palette */ 17946e8394b8SKazutaka YOKOTA 1795f4e98881SRuslan Ermilov #ifdef VGA_SLOW_IOACCESS 17966e8394b8SKazutaka YOKOTA #ifdef VGA_ALT_SEQACCESS 17976e8394b8SKazutaka YOKOTA outb(TSIDX, 0x00); outb(TSREG, 0x01); 17986e8394b8SKazutaka YOKOTA #endif 17996e8394b8SKazutaka YOKOTA outb(TSIDX, 0x02); outb(TSREG, buf[0]); 18006e8394b8SKazutaka YOKOTA outb(TSIDX, 0x04); outb(TSREG, buf[1]); 18016e8394b8SKazutaka YOKOTA #ifdef VGA_ALT_SEQACCESS 18026e8394b8SKazutaka YOKOTA outb(TSIDX, 0x00); outb(TSREG, 0x03); 18036e8394b8SKazutaka YOKOTA #endif 18046e8394b8SKazutaka YOKOTA outb(GDCIDX, 0x04); outb(GDCREG, buf[2]); 18056e8394b8SKazutaka YOKOTA outb(GDCIDX, 0x05); outb(GDCREG, buf[3]); 18066e8394b8SKazutaka YOKOTA if (adp->va_crtc_addr == MONO_CRTC) { 18076e8394b8SKazutaka YOKOTA outb(GDCIDX, 0x06); outb(GDCREG,(buf[4] & 0x03) | 0x08); 18086e8394b8SKazutaka YOKOTA } else { 18096e8394b8SKazutaka YOKOTA outb(GDCIDX, 0x06); outb(GDCREG,(buf[4] & 0x03) | 0x0c); 18106e8394b8SKazutaka YOKOTA } 18116e8394b8SKazutaka YOKOTA #else /* VGA_SLOW_IOACCESS */ 18126e8394b8SKazutaka YOKOTA #ifdef VGA_ALT_SEQACCESS 18136e8394b8SKazutaka YOKOTA outw(TSIDX, 0x0100); 18146e8394b8SKazutaka YOKOTA #endif 18156e8394b8SKazutaka YOKOTA outw(TSIDX, 0x0002 | (buf[0] << 8)); 18166e8394b8SKazutaka YOKOTA outw(TSIDX, 0x0004 | (buf[1] << 8)); 18176e8394b8SKazutaka YOKOTA #ifdef VGA_ALT_SEQACCESS 18186e8394b8SKazutaka YOKOTA outw(TSIDX, 0x0300); 18196e8394b8SKazutaka YOKOTA #endif 18206e8394b8SKazutaka YOKOTA outw(GDCIDX, 0x0004 | (buf[2] << 8)); 18216e8394b8SKazutaka YOKOTA outw(GDCIDX, 0x0005 | (buf[3] << 8)); 18226e8394b8SKazutaka YOKOTA if (adp->va_crtc_addr == MONO_CRTC) 18236e8394b8SKazutaka YOKOTA outw(GDCIDX, 0x0006 | (((buf[4] & 0x03) | 0x08)<<8)); 18246e8394b8SKazutaka YOKOTA else 18256e8394b8SKazutaka YOKOTA outw(GDCIDX, 0x0006 | (((buf[4] & 0x03) | 0x0c)<<8)); 18266e8394b8SKazutaka YOKOTA #endif /* VGA_SLOW_IOACCESS */ 18276e8394b8SKazutaka YOKOTA 18286e8394b8SKazutaka YOKOTA splx(s); 18296e8394b8SKazutaka YOKOTA } 18306e8394b8SKazutaka YOKOTA 18316e8394b8SKazutaka YOKOTA #endif /* VGA_NO_FONT_LOADING */ 18326e8394b8SKazutaka YOKOTA 18336e8394b8SKazutaka YOKOTA /* 18346e8394b8SKazutaka YOKOTA * save_font(): 18356e8394b8SKazutaka YOKOTA * Read the font data in the requested font page from the video adapter. 18366e8394b8SKazutaka YOKOTA * 18376e8394b8SKazutaka YOKOTA * EGA/VGA 18386e8394b8SKazutaka YOKOTA */ 18396e8394b8SKazutaka YOKOTA static int 1840b7c96c0dSMarius Strobl vga_save_font(video_adapter_t *adp, int page, int fontsize, int fontwidth, 1841b7c96c0dSMarius Strobl u_char *data, int ch, int count) 18426e8394b8SKazutaka YOKOTA { 18436e8394b8SKazutaka YOKOTA #ifndef VGA_NO_FONT_LOADING 18446e8394b8SKazutaka YOKOTA u_char buf[PARAM_BUFSIZE]; 1845637068b1SPeter Wemm vm_offset_t segment; 18466e8394b8SKazutaka YOKOTA int c; 18476e8394b8SKazutaka YOKOTA #ifdef VGA_ALT_SEQACCESS 18486e8394b8SKazutaka YOKOTA int s; 18496e8394b8SKazutaka YOKOTA u_char val = 0; 18506e8394b8SKazutaka YOKOTA #endif 18516e8394b8SKazutaka YOKOTA 18526e8394b8SKazutaka YOKOTA prologue(adp, V_ADP_FONT, ENODEV); 18536e8394b8SKazutaka YOKOTA 18546e8394b8SKazutaka YOKOTA if (fontsize < 14) { 18556e8394b8SKazutaka YOKOTA /* FONT_8 */ 18566e8394b8SKazutaka YOKOTA fontsize = 8; 18576e8394b8SKazutaka YOKOTA } else if (fontsize >= 32) { 18586e8394b8SKazutaka YOKOTA fontsize = 32; 18596e8394b8SKazutaka YOKOTA } else if (fontsize >= 16) { 18606e8394b8SKazutaka YOKOTA /* FONT_16 */ 18616e8394b8SKazutaka YOKOTA fontsize = 16; 18626e8394b8SKazutaka YOKOTA } else { 18636e8394b8SKazutaka YOKOTA /* FONT_14 */ 18646e8394b8SKazutaka YOKOTA fontsize = 14; 18656e8394b8SKazutaka YOKOTA } 18666e8394b8SKazutaka YOKOTA 1867b7c96c0dSMarius Strobl if (page < 0 || page >= 8 || fontwidth != 8) 18686e8394b8SKazutaka YOKOTA return EINVAL; 18696e8394b8SKazutaka YOKOTA segment = FONT_BUF + 0x4000*page; 18706e8394b8SKazutaka YOKOTA if (page > 3) 18716e8394b8SKazutaka YOKOTA segment -= 0xe000; 18726e8394b8SKazutaka YOKOTA 18736e8394b8SKazutaka YOKOTA #ifdef VGA_ALT_SEQACCESS 18746e8394b8SKazutaka YOKOTA if (adp->va_type == KD_VGA) { /* what about EGA? XXX */ 18756e8394b8SKazutaka YOKOTA s = splhigh(); 18766e8394b8SKazutaka YOKOTA outb(TSIDX, 0x00); outb(TSREG, 0x01); 18776e8394b8SKazutaka YOKOTA outb(TSIDX, 0x01); val = inb(TSREG); /* disable screen */ 18786e8394b8SKazutaka YOKOTA outb(TSIDX, 0x01); outb(TSREG, val | 0x20); 18796e8394b8SKazutaka YOKOTA outb(TSIDX, 0x00); outb(TSREG, 0x03); 18806e8394b8SKazutaka YOKOTA splx(s); 18816e8394b8SKazutaka YOKOTA } 18826e8394b8SKazutaka YOKOTA #endif 18836e8394b8SKazutaka YOKOTA 18846e8394b8SKazutaka YOKOTA set_font_mode(adp, buf); 18856e8394b8SKazutaka YOKOTA if (fontsize == 32) { 18868c376570SPeter Wemm bcopy_fromio((uintptr_t)segment + ch*32, data, fontsize*count); 18876e8394b8SKazutaka YOKOTA } else { 18886e8394b8SKazutaka YOKOTA for (c = ch; count > 0; ++c, --count) { 18898c376570SPeter Wemm bcopy_fromio((uintptr_t)segment + c*32, data, fontsize); 18906e8394b8SKazutaka YOKOTA data += fontsize; 18916e8394b8SKazutaka YOKOTA } 18926e8394b8SKazutaka YOKOTA } 18936e8394b8SKazutaka YOKOTA set_normal_mode(adp, buf); 18946e8394b8SKazutaka YOKOTA 18956e8394b8SKazutaka YOKOTA #ifdef VGA_ALT_SEQACCESS 18966e8394b8SKazutaka YOKOTA if (adp->va_type == KD_VGA) { 18976e8394b8SKazutaka YOKOTA s = splhigh(); 18986e8394b8SKazutaka YOKOTA outb(TSIDX, 0x00); outb(TSREG, 0x01); 18996e8394b8SKazutaka YOKOTA outb(TSIDX, 0x01); outb(TSREG, val & 0xdf); /* enable screen */ 19006e8394b8SKazutaka YOKOTA outb(TSIDX, 0x00); outb(TSREG, 0x03); 19016e8394b8SKazutaka YOKOTA splx(s); 19026e8394b8SKazutaka YOKOTA } 19036e8394b8SKazutaka YOKOTA #endif 19046e8394b8SKazutaka YOKOTA 19056e8394b8SKazutaka YOKOTA return 0; 19066e8394b8SKazutaka YOKOTA #else /* VGA_NO_FONT_LOADING */ 19076e8394b8SKazutaka YOKOTA return ENODEV; 19086e8394b8SKazutaka YOKOTA #endif /* VGA_NO_FONT_LOADING */ 19096e8394b8SKazutaka YOKOTA } 19106e8394b8SKazutaka YOKOTA 19116e8394b8SKazutaka YOKOTA /* 19126e8394b8SKazutaka YOKOTA * load_font(): 19136e8394b8SKazutaka YOKOTA * Set the font data in the requested font page. 19146e8394b8SKazutaka YOKOTA * NOTE: it appears that some recent video adapters do not support 19156e8394b8SKazutaka YOKOTA * the font page other than 0... XXX 19166e8394b8SKazutaka YOKOTA * 19176e8394b8SKazutaka YOKOTA * EGA/VGA 19186e8394b8SKazutaka YOKOTA */ 19196e8394b8SKazutaka YOKOTA static int 1920b7c96c0dSMarius Strobl vga_load_font(video_adapter_t *adp, int page, int fontsize, int fontwidth, 1921b7c96c0dSMarius Strobl u_char *data, int ch, int count) 19226e8394b8SKazutaka YOKOTA { 19236e8394b8SKazutaka YOKOTA #ifndef VGA_NO_FONT_LOADING 19246e8394b8SKazutaka YOKOTA u_char buf[PARAM_BUFSIZE]; 1925637068b1SPeter Wemm vm_offset_t segment; 19266e8394b8SKazutaka YOKOTA int c; 19276e8394b8SKazutaka YOKOTA #ifdef VGA_ALT_SEQACCESS 19286e8394b8SKazutaka YOKOTA int s; 19296e8394b8SKazutaka YOKOTA u_char val = 0; 19306e8394b8SKazutaka YOKOTA #endif 19316e8394b8SKazutaka YOKOTA 19326e8394b8SKazutaka YOKOTA prologue(adp, V_ADP_FONT, ENODEV); 19336e8394b8SKazutaka YOKOTA 19346e8394b8SKazutaka YOKOTA if (fontsize < 14) { 19356e8394b8SKazutaka YOKOTA /* FONT_8 */ 19366e8394b8SKazutaka YOKOTA fontsize = 8; 19376e8394b8SKazutaka YOKOTA } else if (fontsize >= 32) { 19386e8394b8SKazutaka YOKOTA fontsize = 32; 19396e8394b8SKazutaka YOKOTA } else if (fontsize >= 16) { 19406e8394b8SKazutaka YOKOTA /* FONT_16 */ 19416e8394b8SKazutaka YOKOTA fontsize = 16; 19426e8394b8SKazutaka YOKOTA } else { 19436e8394b8SKazutaka YOKOTA /* FONT_14 */ 19446e8394b8SKazutaka YOKOTA fontsize = 14; 19456e8394b8SKazutaka YOKOTA } 19466e8394b8SKazutaka YOKOTA 1947b7c96c0dSMarius Strobl if (page < 0 || page >= 8 || fontwidth != 8) 19486e8394b8SKazutaka YOKOTA return EINVAL; 19496e8394b8SKazutaka YOKOTA segment = FONT_BUF + 0x4000*page; 19506e8394b8SKazutaka YOKOTA if (page > 3) 19516e8394b8SKazutaka YOKOTA segment -= 0xe000; 19526e8394b8SKazutaka YOKOTA 19536e8394b8SKazutaka YOKOTA #ifdef VGA_ALT_SEQACCESS 19546e8394b8SKazutaka YOKOTA if (adp->va_type == KD_VGA) { /* what about EGA? XXX */ 19556e8394b8SKazutaka YOKOTA s = splhigh(); 19566e8394b8SKazutaka YOKOTA outb(TSIDX, 0x00); outb(TSREG, 0x01); 19576e8394b8SKazutaka YOKOTA outb(TSIDX, 0x01); val = inb(TSREG); /* disable screen */ 19586e8394b8SKazutaka YOKOTA outb(TSIDX, 0x01); outb(TSREG, val | 0x20); 19596e8394b8SKazutaka YOKOTA outb(TSIDX, 0x00); outb(TSREG, 0x03); 19606e8394b8SKazutaka YOKOTA splx(s); 19616e8394b8SKazutaka YOKOTA } 19626e8394b8SKazutaka YOKOTA #endif 19636e8394b8SKazutaka YOKOTA 19646e8394b8SKazutaka YOKOTA set_font_mode(adp, buf); 19656e8394b8SKazutaka YOKOTA if (fontsize == 32) { 19668c376570SPeter Wemm bcopy_toio(data, (uintptr_t)segment + ch*32, fontsize*count); 19676e8394b8SKazutaka YOKOTA } else { 19686e8394b8SKazutaka YOKOTA for (c = ch; count > 0; ++c, --count) { 19698c376570SPeter Wemm bcopy_toio(data, (uintptr_t)segment + c*32, fontsize); 19706e8394b8SKazutaka YOKOTA data += fontsize; 19716e8394b8SKazutaka YOKOTA } 19726e8394b8SKazutaka YOKOTA } 19736e8394b8SKazutaka YOKOTA set_normal_mode(adp, buf); 19746e8394b8SKazutaka YOKOTA 19756e8394b8SKazutaka YOKOTA #ifdef VGA_ALT_SEQACCESS 19766e8394b8SKazutaka YOKOTA if (adp->va_type == KD_VGA) { 19776e8394b8SKazutaka YOKOTA s = splhigh(); 19786e8394b8SKazutaka YOKOTA outb(TSIDX, 0x00); outb(TSREG, 0x01); 19796e8394b8SKazutaka YOKOTA outb(TSIDX, 0x01); outb(TSREG, val & 0xdf); /* enable screen */ 19806e8394b8SKazutaka YOKOTA outb(TSIDX, 0x00); outb(TSREG, 0x03); 19816e8394b8SKazutaka YOKOTA splx(s); 19826e8394b8SKazutaka YOKOTA } 19836e8394b8SKazutaka YOKOTA #endif 19846e8394b8SKazutaka YOKOTA 19856e8394b8SKazutaka YOKOTA return 0; 19866e8394b8SKazutaka YOKOTA #else /* VGA_NO_FONT_LOADING */ 19876e8394b8SKazutaka YOKOTA return ENODEV; 19886e8394b8SKazutaka YOKOTA #endif /* VGA_NO_FONT_LOADING */ 19896e8394b8SKazutaka YOKOTA } 19906e8394b8SKazutaka YOKOTA 19916e8394b8SKazutaka YOKOTA /* 19926e8394b8SKazutaka YOKOTA * show_font(): 19936e8394b8SKazutaka YOKOTA * Activate the requested font page. 19946e8394b8SKazutaka YOKOTA * NOTE: it appears that some recent video adapters do not support 19956e8394b8SKazutaka YOKOTA * the font page other than 0... XXX 19966e8394b8SKazutaka YOKOTA * 19976e8394b8SKazutaka YOKOTA * EGA/VGA 19986e8394b8SKazutaka YOKOTA */ 19996e8394b8SKazutaka YOKOTA static int 20006e8394b8SKazutaka YOKOTA vga_show_font(video_adapter_t *adp, int page) 20016e8394b8SKazutaka YOKOTA { 20026e8394b8SKazutaka YOKOTA #ifndef VGA_NO_FONT_LOADING 20036e8394b8SKazutaka YOKOTA static u_char cg[] = { 0x00, 0x05, 0x0a, 0x0f, 0x30, 0x35, 0x3a, 0x3f }; 20046e8394b8SKazutaka YOKOTA int s; 20056e8394b8SKazutaka YOKOTA 20066e8394b8SKazutaka YOKOTA prologue(adp, V_ADP_FONT, ENODEV); 20076e8394b8SKazutaka YOKOTA if (page < 0 || page >= 8) 20086e8394b8SKazutaka YOKOTA return EINVAL; 20096e8394b8SKazutaka YOKOTA 20106e8394b8SKazutaka YOKOTA s = splhigh(); 20116e8394b8SKazutaka YOKOTA outb(TSIDX, 0x03); outb(TSREG, cg[page]); 20126e8394b8SKazutaka YOKOTA splx(s); 20136e8394b8SKazutaka YOKOTA 20146e8394b8SKazutaka YOKOTA return 0; 20156e8394b8SKazutaka YOKOTA #else /* VGA_NO_FONT_LOADING */ 20166e8394b8SKazutaka YOKOTA return ENODEV; 20176e8394b8SKazutaka YOKOTA #endif /* VGA_NO_FONT_LOADING */ 20186e8394b8SKazutaka YOKOTA } 20196e8394b8SKazutaka YOKOTA 20206e8394b8SKazutaka YOKOTA /* 20216e8394b8SKazutaka YOKOTA * save_palette(): 20226e8394b8SKazutaka YOKOTA * Read DAC values. The values have expressed in 8 bits. 20236e8394b8SKazutaka YOKOTA * 20246e8394b8SKazutaka YOKOTA * VGA 20256e8394b8SKazutaka YOKOTA */ 20266e8394b8SKazutaka YOKOTA static int 20276e8394b8SKazutaka YOKOTA vga_save_palette(video_adapter_t *adp, u_char *palette) 20286e8394b8SKazutaka YOKOTA { 20291e161437SJung-uk Kim int bits; 20306e8394b8SKazutaka YOKOTA int i; 20316e8394b8SKazutaka YOKOTA 20326e8394b8SKazutaka YOKOTA prologue(adp, V_ADP_PALETTE, ENODEV); 20336e8394b8SKazutaka YOKOTA 20346e8394b8SKazutaka YOKOTA /* 20356e8394b8SKazutaka YOKOTA * We store 8 bit values in the palette buffer, while the standard 20366e8394b8SKazutaka YOKOTA * VGA has 6 bit DAC . 20376e8394b8SKazutaka YOKOTA */ 20386e8394b8SKazutaka YOKOTA outb(PALRADR, 0x00); 20391e161437SJung-uk Kim bits = (adp->va_flags & V_ADP_DAC8) != 0 ? 0 : 2; 20406e8394b8SKazutaka YOKOTA for (i = 0; i < 256*3; ++i) 20411e161437SJung-uk Kim palette[i] = inb(PALDATA) << bits; 20426e8394b8SKazutaka YOKOTA inb(adp->va_crtc_addr + 6); /* reset flip/flop */ 20436e8394b8SKazutaka YOKOTA return 0; 20446e8394b8SKazutaka YOKOTA } 20456e8394b8SKazutaka YOKOTA 20466e8394b8SKazutaka YOKOTA static int 20476e8394b8SKazutaka YOKOTA vga_save_palette2(video_adapter_t *adp, int base, int count, 20486e8394b8SKazutaka YOKOTA u_char *r, u_char *g, u_char *b) 20496e8394b8SKazutaka YOKOTA { 20501e161437SJung-uk Kim int bits; 20516e8394b8SKazutaka YOKOTA int i; 20526e8394b8SKazutaka YOKOTA 20536e8394b8SKazutaka YOKOTA prologue(adp, V_ADP_PALETTE, ENODEV); 20546e8394b8SKazutaka YOKOTA 20556e8394b8SKazutaka YOKOTA outb(PALRADR, base); 20561e161437SJung-uk Kim bits = (adp->va_flags & V_ADP_DAC8) != 0 ? 0 : 2; 20576e8394b8SKazutaka YOKOTA for (i = 0; i < count; ++i) { 20581e161437SJung-uk Kim r[i] = inb(PALDATA) << bits; 20591e161437SJung-uk Kim g[i] = inb(PALDATA) << bits; 20601e161437SJung-uk Kim b[i] = inb(PALDATA) << bits; 20616e8394b8SKazutaka YOKOTA } 20626e8394b8SKazutaka YOKOTA inb(adp->va_crtc_addr + 6); /* reset flip/flop */ 20636e8394b8SKazutaka YOKOTA return 0; 20646e8394b8SKazutaka YOKOTA } 20656e8394b8SKazutaka YOKOTA 20666e8394b8SKazutaka YOKOTA /* 20676e8394b8SKazutaka YOKOTA * load_palette(): 20686e8394b8SKazutaka YOKOTA * Set DAC values. 20696e8394b8SKazutaka YOKOTA * 20706e8394b8SKazutaka YOKOTA * VGA 20716e8394b8SKazutaka YOKOTA */ 20726e8394b8SKazutaka YOKOTA static int 20736e8394b8SKazutaka YOKOTA vga_load_palette(video_adapter_t *adp, u_char *palette) 20746e8394b8SKazutaka YOKOTA { 20751e161437SJung-uk Kim int bits; 20766e8394b8SKazutaka YOKOTA int i; 20776e8394b8SKazutaka YOKOTA 20786e8394b8SKazutaka YOKOTA prologue(adp, V_ADP_PALETTE, ENODEV); 20796e8394b8SKazutaka YOKOTA 20806e8394b8SKazutaka YOKOTA outb(PIXMASK, 0xff); /* no pixelmask */ 20816e8394b8SKazutaka YOKOTA outb(PALWADR, 0x00); 20821e161437SJung-uk Kim bits = (adp->va_flags & V_ADP_DAC8) != 0 ? 0 : 2; 20836e8394b8SKazutaka YOKOTA for (i = 0; i < 256*3; ++i) 20841e161437SJung-uk Kim outb(PALDATA, palette[i] >> bits); 20856e8394b8SKazutaka YOKOTA inb(adp->va_crtc_addr + 6); /* reset flip/flop */ 20866e8394b8SKazutaka YOKOTA outb(ATC, 0x20); /* enable palette */ 20876e8394b8SKazutaka YOKOTA return 0; 20886e8394b8SKazutaka YOKOTA } 20896e8394b8SKazutaka YOKOTA 20906e8394b8SKazutaka YOKOTA static int 20916e8394b8SKazutaka YOKOTA vga_load_palette2(video_adapter_t *adp, int base, int count, 20926e8394b8SKazutaka YOKOTA u_char *r, u_char *g, u_char *b) 20936e8394b8SKazutaka YOKOTA { 20941e161437SJung-uk Kim int bits; 20956e8394b8SKazutaka YOKOTA int i; 20966e8394b8SKazutaka YOKOTA 20976e8394b8SKazutaka YOKOTA prologue(adp, V_ADP_PALETTE, ENODEV); 20986e8394b8SKazutaka YOKOTA 20996e8394b8SKazutaka YOKOTA outb(PIXMASK, 0xff); /* no pixelmask */ 21006e8394b8SKazutaka YOKOTA outb(PALWADR, base); 21011e161437SJung-uk Kim bits = (adp->va_flags & V_ADP_DAC8) != 0 ? 0 : 2; 21026e8394b8SKazutaka YOKOTA for (i = 0; i < count; ++i) { 21031e161437SJung-uk Kim outb(PALDATA, r[i] >> bits); 21041e161437SJung-uk Kim outb(PALDATA, g[i] >> bits); 21051e161437SJung-uk Kim outb(PALDATA, b[i] >> bits); 21066e8394b8SKazutaka YOKOTA } 21076e8394b8SKazutaka YOKOTA inb(adp->va_crtc_addr + 6); /* reset flip/flop */ 21086e8394b8SKazutaka YOKOTA outb(ATC, 0x20); /* enable palette */ 21096e8394b8SKazutaka YOKOTA return 0; 21106e8394b8SKazutaka YOKOTA } 21116e8394b8SKazutaka YOKOTA 21126e8394b8SKazutaka YOKOTA /* 21136e8394b8SKazutaka YOKOTA * set_border(): 21146e8394b8SKazutaka YOKOTA * Change the border color. 21156e8394b8SKazutaka YOKOTA * 21166e8394b8SKazutaka YOKOTA * CGA/EGA/VGA 21176e8394b8SKazutaka YOKOTA */ 21186e8394b8SKazutaka YOKOTA static int 21196e8394b8SKazutaka YOKOTA vga_set_border(video_adapter_t *adp, int color) 21206e8394b8SKazutaka YOKOTA { 21216e8394b8SKazutaka YOKOTA prologue(adp, V_ADP_BORDER, ENODEV); 21226e8394b8SKazutaka YOKOTA 21236e8394b8SKazutaka YOKOTA switch (adp->va_type) { 21246e8394b8SKazutaka YOKOTA case KD_EGA: 21256e8394b8SKazutaka YOKOTA case KD_VGA: 21266e8394b8SKazutaka YOKOTA inb(adp->va_crtc_addr + 6); /* reset flip-flop */ 21276e8394b8SKazutaka YOKOTA outb(ATC, 0x31); outb(ATC, color & 0xff); 21286e8394b8SKazutaka YOKOTA break; 21296e8394b8SKazutaka YOKOTA case KD_CGA: 21306e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr + 5, color & 0x0f); /* color select register */ 21316e8394b8SKazutaka YOKOTA break; 21326e8394b8SKazutaka YOKOTA case KD_MONO: 21336e8394b8SKazutaka YOKOTA case KD_HERCULES: 21346e8394b8SKazutaka YOKOTA default: 21356e8394b8SKazutaka YOKOTA break; 21366e8394b8SKazutaka YOKOTA } 21376e8394b8SKazutaka YOKOTA return 0; 21386e8394b8SKazutaka YOKOTA } 21396e8394b8SKazutaka YOKOTA 21406e8394b8SKazutaka YOKOTA /* 21416e8394b8SKazutaka YOKOTA * save_state(): 21426e8394b8SKazutaka YOKOTA * Read video register values. 21436e8394b8SKazutaka YOKOTA * NOTE: this function only reads the standard EGA/VGA registers. 21446e8394b8SKazutaka YOKOTA * any extra/extended registers of SVGA adapters are not saved. 21456e8394b8SKazutaka YOKOTA * 21466e8394b8SKazutaka YOKOTA * VGA 21476e8394b8SKazutaka YOKOTA */ 21486e8394b8SKazutaka YOKOTA static int 21496e8394b8SKazutaka YOKOTA vga_save_state(video_adapter_t *adp, void *p, size_t size) 21506e8394b8SKazutaka YOKOTA { 21516e8394b8SKazutaka YOKOTA video_info_t info; 21526e8394b8SKazutaka YOKOTA u_char *buf; 21536e8394b8SKazutaka YOKOTA int crtc_addr; 21546e8394b8SKazutaka YOKOTA int i, j; 21556e8394b8SKazutaka YOKOTA int s; 21566e8394b8SKazutaka YOKOTA 21576e8394b8SKazutaka YOKOTA if (size == 0) { 21586e8394b8SKazutaka YOKOTA /* return the required buffer size */ 21596e8394b8SKazutaka YOKOTA prologue(adp, V_ADP_STATESAVE, 0); 21606e8394b8SKazutaka YOKOTA return sizeof(adp_state_t); 21616e8394b8SKazutaka YOKOTA } else { 21626e8394b8SKazutaka YOKOTA prologue(adp, V_ADP_STATESAVE, ENODEV); 21636e8394b8SKazutaka YOKOTA if (size < sizeof(adp_state_t)) 21646e8394b8SKazutaka YOKOTA return EINVAL; 21656e8394b8SKazutaka YOKOTA } 21666e8394b8SKazutaka YOKOTA 21676e8394b8SKazutaka YOKOTA ((adp_state_t *)p)->sig = V_STATE_SIG; 21686e8394b8SKazutaka YOKOTA buf = ((adp_state_t *)p)->regs; 21696e8394b8SKazutaka YOKOTA bzero(buf, V_MODE_PARAM_SIZE); 21706e8394b8SKazutaka YOKOTA crtc_addr = adp->va_crtc_addr; 21716e8394b8SKazutaka YOKOTA 21726e8394b8SKazutaka YOKOTA s = splhigh(); 21736e8394b8SKazutaka YOKOTA 21746e8394b8SKazutaka YOKOTA outb(TSIDX, 0x00); outb(TSREG, 0x01); /* stop sequencer */ 21756e8394b8SKazutaka YOKOTA for (i = 0, j = 5; i < 4; i++) { 21766e8394b8SKazutaka YOKOTA outb(TSIDX, i + 1); 21776e8394b8SKazutaka YOKOTA buf[j++] = inb(TSREG); 21786e8394b8SKazutaka YOKOTA } 21796e8394b8SKazutaka YOKOTA buf[9] = inb(MISC + 10); /* dot-clock */ 21806e8394b8SKazutaka YOKOTA outb(TSIDX, 0x00); outb(TSREG, 0x03); /* start sequencer */ 21816e8394b8SKazutaka YOKOTA 21826e8394b8SKazutaka YOKOTA for (i = 0, j = 10; i < 25; i++) { /* crtc */ 21836e8394b8SKazutaka YOKOTA outb(crtc_addr, i); 21846e8394b8SKazutaka YOKOTA buf[j++] = inb(crtc_addr + 1); 21856e8394b8SKazutaka YOKOTA } 21866e8394b8SKazutaka YOKOTA for (i = 0, j = 35; i < 20; i++) { /* attribute ctrl */ 21876e8394b8SKazutaka YOKOTA inb(crtc_addr + 6); /* reset flip-flop */ 21886e8394b8SKazutaka YOKOTA outb(ATC, i); 21896e8394b8SKazutaka YOKOTA buf[j++] = inb(ATC + 1); 21906e8394b8SKazutaka YOKOTA } 21916e8394b8SKazutaka YOKOTA for (i = 0, j = 55; i < 9; i++) { /* graph data ctrl */ 21926e8394b8SKazutaka YOKOTA outb(GDCIDX, i); 21936e8394b8SKazutaka YOKOTA buf[j++] = inb(GDCREG); 21946e8394b8SKazutaka YOKOTA } 21956e8394b8SKazutaka YOKOTA inb(crtc_addr + 6); /* reset flip-flop */ 21966e8394b8SKazutaka YOKOTA outb(ATC, 0x20); /* enable palette */ 21976e8394b8SKazutaka YOKOTA 21986e8394b8SKazutaka YOKOTA splx(s); 21996e8394b8SKazutaka YOKOTA 22006e8394b8SKazutaka YOKOTA #if 1 22016e8394b8SKazutaka YOKOTA if (vga_get_info(adp, adp->va_mode, &info) == 0) { 22026e8394b8SKazutaka YOKOTA if (info.vi_flags & V_INFO_GRAPHICS) { 22036e8394b8SKazutaka YOKOTA buf[0] = info.vi_width/info.vi_cwidth; /* COLS */ 22046e8394b8SKazutaka YOKOTA buf[1] = info.vi_height/info.vi_cheight - 1; /* ROWS */ 22056e8394b8SKazutaka YOKOTA } else { 22066e8394b8SKazutaka YOKOTA buf[0] = info.vi_width; /* COLS */ 22076e8394b8SKazutaka YOKOTA buf[1] = info.vi_height - 1; /* ROWS */ 22086e8394b8SKazutaka YOKOTA } 22096e8394b8SKazutaka YOKOTA buf[2] = info.vi_cheight; /* POINTS */ 22106e8394b8SKazutaka YOKOTA } 22116e8394b8SKazutaka YOKOTA #else 22126e8394b8SKazutaka YOKOTA buf[0] = readb(BIOS_PADDRTOVADDR(0x44a)); /* COLS */ 22136e8394b8SKazutaka YOKOTA buf[1] = readb(BIOS_PADDRTOVADDR(0x484)); /* ROWS */ 22146e8394b8SKazutaka YOKOTA buf[2] = readb(BIOS_PADDRTOVADDR(0x485)); /* POINTS */ 22156e8394b8SKazutaka YOKOTA buf[3] = readb(BIOS_PADDRTOVADDR(0x44c)); 22166e8394b8SKazutaka YOKOTA buf[4] = readb(BIOS_PADDRTOVADDR(0x44d)); 22176e8394b8SKazutaka YOKOTA #endif 22186e8394b8SKazutaka YOKOTA 22196e8394b8SKazutaka YOKOTA return 0; 22206e8394b8SKazutaka YOKOTA } 22216e8394b8SKazutaka YOKOTA 22226e8394b8SKazutaka YOKOTA /* 22236e8394b8SKazutaka YOKOTA * load_state(): 22246e8394b8SKazutaka YOKOTA * Set video registers at once. 22256e8394b8SKazutaka YOKOTA * NOTE: this function only updates the standard EGA/VGA registers. 22266e8394b8SKazutaka YOKOTA * any extra/extended registers of SVGA adapters are not changed. 22276e8394b8SKazutaka YOKOTA * 22286e8394b8SKazutaka YOKOTA * EGA/VGA 22296e8394b8SKazutaka YOKOTA */ 22306e8394b8SKazutaka YOKOTA static int 22316e8394b8SKazutaka YOKOTA vga_load_state(video_adapter_t *adp, void *p) 22326e8394b8SKazutaka YOKOTA { 22336e8394b8SKazutaka YOKOTA u_char *buf; 22346e8394b8SKazutaka YOKOTA int crtc_addr; 22356e8394b8SKazutaka YOKOTA int s; 22366e8394b8SKazutaka YOKOTA int i; 22376e8394b8SKazutaka YOKOTA 22386e8394b8SKazutaka YOKOTA prologue(adp, V_ADP_STATELOAD, ENODEV); 22396e8394b8SKazutaka YOKOTA if (((adp_state_t *)p)->sig != V_STATE_SIG) 22406e8394b8SKazutaka YOKOTA return EINVAL; 22416e8394b8SKazutaka YOKOTA 22426e8394b8SKazutaka YOKOTA buf = ((adp_state_t *)p)->regs; 22436e8394b8SKazutaka YOKOTA crtc_addr = adp->va_crtc_addr; 22446e8394b8SKazutaka YOKOTA 22456e8394b8SKazutaka YOKOTA #if VGA_DEBUG > 1 22466e8394b8SKazutaka YOKOTA dump_buffer(buf, V_MODE_PARAM_SIZE); 22476e8394b8SKazutaka YOKOTA #endif 22486e8394b8SKazutaka YOKOTA 22496e8394b8SKazutaka YOKOTA s = splhigh(); 22506e8394b8SKazutaka YOKOTA 22516e8394b8SKazutaka YOKOTA outb(TSIDX, 0x00); outb(TSREG, 0x01); /* stop sequencer */ 22526e8394b8SKazutaka YOKOTA for (i = 0; i < 4; ++i) { /* program sequencer */ 22536e8394b8SKazutaka YOKOTA outb(TSIDX, i + 1); 22546e8394b8SKazutaka YOKOTA outb(TSREG, buf[i + 5]); 22556e8394b8SKazutaka YOKOTA } 22566e8394b8SKazutaka YOKOTA outb(MISC, buf[9]); /* set dot-clock */ 22576e8394b8SKazutaka YOKOTA outb(TSIDX, 0x00); outb(TSREG, 0x03); /* start sequencer */ 22586e8394b8SKazutaka YOKOTA outb(crtc_addr, 0x11); 22596e8394b8SKazutaka YOKOTA outb(crtc_addr + 1, inb(crtc_addr + 1) & 0x7F); 22606e8394b8SKazutaka YOKOTA for (i = 0; i < 25; ++i) { /* program crtc */ 22616e8394b8SKazutaka YOKOTA outb(crtc_addr, i); 22626e8394b8SKazutaka YOKOTA outb(crtc_addr + 1, buf[i + 10]); 22636e8394b8SKazutaka YOKOTA } 22646e8394b8SKazutaka YOKOTA inb(crtc_addr+6); /* reset flip-flop */ 22656e8394b8SKazutaka YOKOTA for (i = 0; i < 20; ++i) { /* program attribute ctrl */ 22666e8394b8SKazutaka YOKOTA outb(ATC, i); 22676e8394b8SKazutaka YOKOTA outb(ATC, buf[i + 35]); 22686e8394b8SKazutaka YOKOTA } 22696e8394b8SKazutaka YOKOTA for (i = 0; i < 9; ++i) { /* program graph data ctrl */ 22706e8394b8SKazutaka YOKOTA outb(GDCIDX, i); 22716e8394b8SKazutaka YOKOTA outb(GDCREG, buf[i + 55]); 22726e8394b8SKazutaka YOKOTA } 22736e8394b8SKazutaka YOKOTA inb(crtc_addr + 6); /* reset flip-flop */ 22746e8394b8SKazutaka YOKOTA outb(ATC, 0x20); /* enable palette */ 22756e8394b8SKazutaka YOKOTA 2276f4e98881SRuslan Ermilov #ifdef notyet /* a temporary workaround for kernel panic, XXX */ 22776e8394b8SKazutaka YOKOTA #ifndef VGA_NO_BIOS 22786e8394b8SKazutaka YOKOTA if (adp->va_unit == V_ADP_PRIMARY) { 22796e8394b8SKazutaka YOKOTA writeb(BIOS_PADDRTOVADDR(0x44a), buf[0]); /* COLS */ 22806e8394b8SKazutaka YOKOTA writeb(BIOS_PADDRTOVADDR(0x484), buf[1] + rows_offset - 1); /* ROWS */ 22816e8394b8SKazutaka YOKOTA writeb(BIOS_PADDRTOVADDR(0x485), buf[2]); /* POINTS */ 22826e8394b8SKazutaka YOKOTA #if 0 22836e8394b8SKazutaka YOKOTA writeb(BIOS_PADDRTOVADDR(0x44c), buf[3]); 22846e8394b8SKazutaka YOKOTA writeb(BIOS_PADDRTOVADDR(0x44d), buf[4]); 22856e8394b8SKazutaka YOKOTA #endif 22866e8394b8SKazutaka YOKOTA } 22876e8394b8SKazutaka YOKOTA #endif /* VGA_NO_BIOS */ 22886e8394b8SKazutaka YOKOTA #endif /* notyet */ 22896e8394b8SKazutaka YOKOTA 22906e8394b8SKazutaka YOKOTA splx(s); 22916e8394b8SKazutaka YOKOTA return 0; 22926e8394b8SKazutaka YOKOTA } 22936e8394b8SKazutaka YOKOTA 22946e8394b8SKazutaka YOKOTA /* 22956e8394b8SKazutaka YOKOTA * set_origin(): 22966e8394b8SKazutaka YOKOTA * Change the origin (window mapping) of the banked frame buffer. 22976e8394b8SKazutaka YOKOTA */ 22986e8394b8SKazutaka YOKOTA static int 22996e8394b8SKazutaka YOKOTA vga_set_origin(video_adapter_t *adp, off_t offset) 23006e8394b8SKazutaka YOKOTA { 23016e8394b8SKazutaka YOKOTA /* 23026e8394b8SKazutaka YOKOTA * The standard video modes do not require window mapping; 23036e8394b8SKazutaka YOKOTA * always return error. 23046e8394b8SKazutaka YOKOTA */ 23056e8394b8SKazutaka YOKOTA return ENODEV; 23066e8394b8SKazutaka YOKOTA } 23076e8394b8SKazutaka YOKOTA 23086e8394b8SKazutaka YOKOTA /* 23096e8394b8SKazutaka YOKOTA * read_hw_cursor(): 23106e8394b8SKazutaka YOKOTA * Read the position of the hardware text cursor. 23116e8394b8SKazutaka YOKOTA * 23126e8394b8SKazutaka YOKOTA * all adapters 23136e8394b8SKazutaka YOKOTA */ 23146e8394b8SKazutaka YOKOTA static int 23156e8394b8SKazutaka YOKOTA vga_read_hw_cursor(video_adapter_t *adp, int *col, int *row) 23166e8394b8SKazutaka YOKOTA { 23176e8394b8SKazutaka YOKOTA u_int16_t off; 23186e8394b8SKazutaka YOKOTA int s; 23196e8394b8SKazutaka YOKOTA 23206e8394b8SKazutaka YOKOTA if (!vga_init_done) 23216e8394b8SKazutaka YOKOTA return ENXIO; 23226e8394b8SKazutaka YOKOTA 23236e8394b8SKazutaka YOKOTA if (adp->va_info.vi_flags & V_INFO_GRAPHICS) 23246e8394b8SKazutaka YOKOTA return ENODEV; 23256e8394b8SKazutaka YOKOTA 23266e8394b8SKazutaka YOKOTA s = spltty(); 23276e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr, 14); 23286e8394b8SKazutaka YOKOTA off = inb(adp->va_crtc_addr + 1); 23296e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr, 15); 23306e8394b8SKazutaka YOKOTA off = (off << 8) | inb(adp->va_crtc_addr + 1); 23316e8394b8SKazutaka YOKOTA splx(s); 23326e8394b8SKazutaka YOKOTA 23336e8394b8SKazutaka YOKOTA *row = off / adp->va_info.vi_width; 23346e8394b8SKazutaka YOKOTA *col = off % adp->va_info.vi_width; 23356e8394b8SKazutaka YOKOTA 23366e8394b8SKazutaka YOKOTA return 0; 23376e8394b8SKazutaka YOKOTA } 23386e8394b8SKazutaka YOKOTA 23396e8394b8SKazutaka YOKOTA /* 23406e8394b8SKazutaka YOKOTA * set_hw_cursor(): 23416e8394b8SKazutaka YOKOTA * Move the hardware text cursor. If col and row are both -1, 23426e8394b8SKazutaka YOKOTA * the cursor won't be shown. 23436e8394b8SKazutaka YOKOTA * 23446e8394b8SKazutaka YOKOTA * all adapters 23456e8394b8SKazutaka YOKOTA */ 23466e8394b8SKazutaka YOKOTA static int 23476e8394b8SKazutaka YOKOTA vga_set_hw_cursor(video_adapter_t *adp, int col, int row) 23486e8394b8SKazutaka YOKOTA { 23496e8394b8SKazutaka YOKOTA u_int16_t off; 23506e8394b8SKazutaka YOKOTA int s; 23516e8394b8SKazutaka YOKOTA 23526e8394b8SKazutaka YOKOTA if (!vga_init_done) 23536e8394b8SKazutaka YOKOTA return ENXIO; 23546e8394b8SKazutaka YOKOTA 23556e8394b8SKazutaka YOKOTA if ((col == -1) && (row == -1)) { 23566e8394b8SKazutaka YOKOTA off = -1; 23576e8394b8SKazutaka YOKOTA } else { 23586e8394b8SKazutaka YOKOTA if (adp->va_info.vi_flags & V_INFO_GRAPHICS) 23596e8394b8SKazutaka YOKOTA return ENODEV; 23606e8394b8SKazutaka YOKOTA off = row*adp->va_info.vi_width + col; 23616e8394b8SKazutaka YOKOTA } 23626e8394b8SKazutaka YOKOTA 23636e8394b8SKazutaka YOKOTA s = spltty(); 23646e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr, 14); 23656e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr + 1, off >> 8); 23666e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr, 15); 23676e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr + 1, off & 0x00ff); 23686e8394b8SKazutaka YOKOTA splx(s); 23696e8394b8SKazutaka YOKOTA 23706e8394b8SKazutaka YOKOTA return 0; 23716e8394b8SKazutaka YOKOTA } 23726e8394b8SKazutaka YOKOTA 23736e8394b8SKazutaka YOKOTA /* 23746e8394b8SKazutaka YOKOTA * set_hw_cursor_shape(): 23756e8394b8SKazutaka YOKOTA * Change the shape of the hardware text cursor. If the height is 23766e8394b8SKazutaka YOKOTA * zero or negative, the cursor won't be shown. 23776e8394b8SKazutaka YOKOTA * 23786e8394b8SKazutaka YOKOTA * all adapters 23796e8394b8SKazutaka YOKOTA */ 23806e8394b8SKazutaka YOKOTA static int 23816e8394b8SKazutaka YOKOTA vga_set_hw_cursor_shape(video_adapter_t *adp, int base, int height, 23826e8394b8SKazutaka YOKOTA int celsize, int blink) 23836e8394b8SKazutaka YOKOTA { 23846e8394b8SKazutaka YOKOTA int s; 23856e8394b8SKazutaka YOKOTA 23866e8394b8SKazutaka YOKOTA if (!vga_init_done) 23876e8394b8SKazutaka YOKOTA return ENXIO; 23886e8394b8SKazutaka YOKOTA 23896e8394b8SKazutaka YOKOTA s = spltty(); 23906e8394b8SKazutaka YOKOTA switch (adp->va_type) { 23916e8394b8SKazutaka YOKOTA case KD_VGA: 23926e8394b8SKazutaka YOKOTA case KD_CGA: 23936e8394b8SKazutaka YOKOTA case KD_MONO: 23946e8394b8SKazutaka YOKOTA case KD_HERCULES: 23956e8394b8SKazutaka YOKOTA default: 23966e8394b8SKazutaka YOKOTA if (height <= 0) { 23976e8394b8SKazutaka YOKOTA /* make the cursor invisible */ 23986e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr, 10); 23996e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr + 1, 32); 24006e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr, 11); 24016e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr + 1, 0); 24026e8394b8SKazutaka YOKOTA } else { 24036e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr, 10); 24046e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr + 1, celsize - base - height); 24056e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr, 11); 24066e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr + 1, celsize - base - 1); 24076e8394b8SKazutaka YOKOTA } 24086e8394b8SKazutaka YOKOTA break; 24096e8394b8SKazutaka YOKOTA case KD_EGA: 24106e8394b8SKazutaka YOKOTA if (height <= 0) { 24116e8394b8SKazutaka YOKOTA /* make the cursor invisible */ 24126e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr, 10); 24136e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr + 1, celsize); 24146e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr, 11); 24156e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr + 1, 0); 24166e8394b8SKazutaka YOKOTA } else { 24176e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr, 10); 24186e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr + 1, celsize - base - height); 24196e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr, 11); 24206e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr + 1, celsize - base); 24216e8394b8SKazutaka YOKOTA } 24226e8394b8SKazutaka YOKOTA break; 24236e8394b8SKazutaka YOKOTA } 24246e8394b8SKazutaka YOKOTA splx(s); 24256e8394b8SKazutaka YOKOTA 24266e8394b8SKazutaka YOKOTA return 0; 24276e8394b8SKazutaka YOKOTA } 24286e8394b8SKazutaka YOKOTA 24296e8394b8SKazutaka YOKOTA /* 24306e8394b8SKazutaka YOKOTA * blank_display() 24316e8394b8SKazutaka YOKOTA * Put the display in power save/power off mode. 24326e8394b8SKazutaka YOKOTA * 24336e8394b8SKazutaka YOKOTA * all adapters 24346e8394b8SKazutaka YOKOTA */ 24356e8394b8SKazutaka YOKOTA static int 24366e8394b8SKazutaka YOKOTA vga_blank_display(video_adapter_t *adp, int mode) 24376e8394b8SKazutaka YOKOTA { 24386e8394b8SKazutaka YOKOTA u_char val; 24396e8394b8SKazutaka YOKOTA int s; 24406e8394b8SKazutaka YOKOTA 24416e8394b8SKazutaka YOKOTA s = splhigh(); 24426e8394b8SKazutaka YOKOTA switch (adp->va_type) { 24436e8394b8SKazutaka YOKOTA case KD_VGA: 24446e8394b8SKazutaka YOKOTA switch (mode) { 24456e8394b8SKazutaka YOKOTA case V_DISPLAY_SUSPEND: 24466e8394b8SKazutaka YOKOTA case V_DISPLAY_STAND_BY: 24476e8394b8SKazutaka YOKOTA outb(TSIDX, 0x01); 24486e8394b8SKazutaka YOKOTA val = inb(TSREG); 24496e8394b8SKazutaka YOKOTA outb(TSIDX, 0x01); 24506e8394b8SKazutaka YOKOTA outb(TSREG, val | 0x20); 24516e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr, 0x17); 24526e8394b8SKazutaka YOKOTA val = inb(adp->va_crtc_addr + 1); 24536e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr + 1, val & ~0x80); 24546e8394b8SKazutaka YOKOTA break; 24556e8394b8SKazutaka YOKOTA case V_DISPLAY_BLANK: 24566e8394b8SKazutaka YOKOTA outb(TSIDX, 0x01); 24576e8394b8SKazutaka YOKOTA val = inb(TSREG); 24586e8394b8SKazutaka YOKOTA outb(TSIDX, 0x01); 24596e8394b8SKazutaka YOKOTA outb(TSREG, val | 0x20); 24606e8394b8SKazutaka YOKOTA break; 24616e8394b8SKazutaka YOKOTA case V_DISPLAY_ON: 24626e8394b8SKazutaka YOKOTA outb(TSIDX, 0x01); 24636e8394b8SKazutaka YOKOTA val = inb(TSREG); 24646e8394b8SKazutaka YOKOTA outb(TSIDX, 0x01); 24656e8394b8SKazutaka YOKOTA outb(TSREG, val & 0xDF); 24666e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr, 0x17); 24676e8394b8SKazutaka YOKOTA val = inb(adp->va_crtc_addr + 1); 24686e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr + 1, val | 0x80); 24696e8394b8SKazutaka YOKOTA break; 24706e8394b8SKazutaka YOKOTA } 24716e8394b8SKazutaka YOKOTA break; 24726e8394b8SKazutaka YOKOTA 24736e8394b8SKazutaka YOKOTA case KD_EGA: 24746e8394b8SKazutaka YOKOTA /* no support yet */ 24753863b6dbSKazutaka YOKOTA splx(s); 24766e8394b8SKazutaka YOKOTA return ENODEV; 24776e8394b8SKazutaka YOKOTA 24786e8394b8SKazutaka YOKOTA case KD_CGA: 24796e8394b8SKazutaka YOKOTA switch (mode) { 24806e8394b8SKazutaka YOKOTA case V_DISPLAY_SUSPEND: 24816e8394b8SKazutaka YOKOTA case V_DISPLAY_STAND_BY: 24826e8394b8SKazutaka YOKOTA case V_DISPLAY_BLANK: 24836e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr + 4, 0x25); 24846e8394b8SKazutaka YOKOTA break; 24856e8394b8SKazutaka YOKOTA case V_DISPLAY_ON: 24866e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr + 4, 0x2d); 24876e8394b8SKazutaka YOKOTA break; 24886e8394b8SKazutaka YOKOTA } 24896e8394b8SKazutaka YOKOTA break; 24906e8394b8SKazutaka YOKOTA 24916e8394b8SKazutaka YOKOTA case KD_MONO: 24926e8394b8SKazutaka YOKOTA case KD_HERCULES: 24936e8394b8SKazutaka YOKOTA switch (mode) { 24946e8394b8SKazutaka YOKOTA case V_DISPLAY_SUSPEND: 24956e8394b8SKazutaka YOKOTA case V_DISPLAY_STAND_BY: 24966e8394b8SKazutaka YOKOTA case V_DISPLAY_BLANK: 24976e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr + 4, 0x21); 24986e8394b8SKazutaka YOKOTA break; 24996e8394b8SKazutaka YOKOTA case V_DISPLAY_ON: 25006e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr + 4, 0x29); 25016e8394b8SKazutaka YOKOTA break; 25026e8394b8SKazutaka YOKOTA } 25036e8394b8SKazutaka YOKOTA break; 25046e8394b8SKazutaka YOKOTA default: 25056e8394b8SKazutaka YOKOTA break; 25066e8394b8SKazutaka YOKOTA } 25076e8394b8SKazutaka YOKOTA splx(s); 25086e8394b8SKazutaka YOKOTA 25096e8394b8SKazutaka YOKOTA return 0; 25106e8394b8SKazutaka YOKOTA } 25116e8394b8SKazutaka YOKOTA 25126e8394b8SKazutaka YOKOTA /* 25136e8394b8SKazutaka YOKOTA * mmap(): 25146e8394b8SKazutaka YOKOTA * Mmap frame buffer. 25156e8394b8SKazutaka YOKOTA * 25166e8394b8SKazutaka YOKOTA * all adapters 25176e8394b8SKazutaka YOKOTA */ 25186e8394b8SKazutaka YOKOTA static int 2519cfd7baceSRobert Noland vga_mmap_buf(video_adapter_t *adp, vm_ooffset_t offset, vm_paddr_t *paddr, 2520cfd7baceSRobert Noland int prot, vm_memattr_t *memattr) 25216e8394b8SKazutaka YOKOTA { 25226e8394b8SKazutaka YOKOTA if (adp->va_info.vi_flags & V_INFO_LINEAR) 25236e8394b8SKazutaka YOKOTA return -1; 25246e8394b8SKazutaka YOKOTA 25256e8394b8SKazutaka YOKOTA #if VGA_DEBUG > 0 25263f57c87eSJohn Baldwin printf("vga_mmap_buf(): window:0x%jx, offset:0x%jx\n", 25273f57c87eSJohn Baldwin (uintmax_t)adp->va_info.vi_window, (uintmax_t)offset); 25286e8394b8SKazutaka YOKOTA #endif 25296e8394b8SKazutaka YOKOTA 25306e8394b8SKazutaka YOKOTA /* XXX: is this correct? */ 25316e8394b8SKazutaka YOKOTA if (offset > adp->va_window_size - PAGE_SIZE) 25326e8394b8SKazutaka YOKOTA return -1; 25336e8394b8SKazutaka YOKOTA 253407159f9cSMaxime Henrion *paddr = adp->va_info.vi_window + offset; 253507159f9cSMaxime Henrion return 0; 25366e8394b8SKazutaka YOKOTA } 25376e8394b8SKazutaka YOKOTA 25386e8394b8SKazutaka YOKOTA #ifndef VGA_NO_MODE_CHANGE 25396e8394b8SKazutaka YOKOTA 25406e8394b8SKazutaka YOKOTA static void 25416e8394b8SKazutaka YOKOTA planar_fill(video_adapter_t *adp, int val) 25426e8394b8SKazutaka YOKOTA { 25436e8394b8SKazutaka YOKOTA int length; 25446e8394b8SKazutaka YOKOTA int at; /* position in the frame buffer */ 25456e8394b8SKazutaka YOKOTA int l; 25466e8394b8SKazutaka YOKOTA 25476e8394b8SKazutaka YOKOTA outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */ 25486e8394b8SKazutaka YOKOTA outw(GDCIDX, 0x0003); /* data rotate/function select */ 25496e8394b8SKazutaka YOKOTA outw(GDCIDX, 0x0f01); /* set/reset enable */ 25506e8394b8SKazutaka YOKOTA outw(GDCIDX, 0xff08); /* bit mask */ 25516e8394b8SKazutaka YOKOTA outw(GDCIDX, (val << 8) | 0x00); /* set/reset */ 25526e8394b8SKazutaka YOKOTA at = 0; 25536e8394b8SKazutaka YOKOTA length = adp->va_line_width*adp->va_info.vi_height; 25546e8394b8SKazutaka YOKOTA while (length > 0) { 25556e8394b8SKazutaka YOKOTA l = imin(length, adp->va_window_size); 25569336e069SWojciech A. Koszek vidd_set_win_org(adp, at); 25576e8394b8SKazutaka YOKOTA bzero_io(adp->va_window, l); 25586e8394b8SKazutaka YOKOTA length -= l; 25596e8394b8SKazutaka YOKOTA at += l; 25606e8394b8SKazutaka YOKOTA } 25616e8394b8SKazutaka YOKOTA outw(GDCIDX, 0x0000); /* set/reset */ 25626e8394b8SKazutaka YOKOTA outw(GDCIDX, 0x0001); /* set/reset enable */ 25636e8394b8SKazutaka YOKOTA } 25646e8394b8SKazutaka YOKOTA 25656e8394b8SKazutaka YOKOTA static void 25666e8394b8SKazutaka YOKOTA packed_fill(video_adapter_t *adp, int val) 25676e8394b8SKazutaka YOKOTA { 25686e8394b8SKazutaka YOKOTA int length; 25696e8394b8SKazutaka YOKOTA int at; /* position in the frame buffer */ 25706e8394b8SKazutaka YOKOTA int l; 25716e8394b8SKazutaka YOKOTA 25726e8394b8SKazutaka YOKOTA at = 0; 25736e8394b8SKazutaka YOKOTA length = adp->va_line_width*adp->va_info.vi_height; 25746e8394b8SKazutaka YOKOTA while (length > 0) { 25756e8394b8SKazutaka YOKOTA l = imin(length, adp->va_window_size); 25769336e069SWojciech A. Koszek vidd_set_win_org(adp, at); 25776e8394b8SKazutaka YOKOTA fill_io(val, adp->va_window, l); 25786e8394b8SKazutaka YOKOTA length -= l; 25796e8394b8SKazutaka YOKOTA at += l; 25806e8394b8SKazutaka YOKOTA } 25816e8394b8SKazutaka YOKOTA } 25826e8394b8SKazutaka YOKOTA 25836e8394b8SKazutaka YOKOTA static void 25846e8394b8SKazutaka YOKOTA direct_fill(video_adapter_t *adp, int val) 25856e8394b8SKazutaka YOKOTA { 25866e8394b8SKazutaka YOKOTA int length; 25876e8394b8SKazutaka YOKOTA int at; /* position in the frame buffer */ 25886e8394b8SKazutaka YOKOTA int l; 25896e8394b8SKazutaka YOKOTA 25906e8394b8SKazutaka YOKOTA at = 0; 25916e8394b8SKazutaka YOKOTA length = adp->va_line_width*adp->va_info.vi_height; 25926e8394b8SKazutaka YOKOTA while (length > 0) { 25936e8394b8SKazutaka YOKOTA l = imin(length, adp->va_window_size); 25949336e069SWojciech A. Koszek vidd_set_win_org(adp, at); 25956e8394b8SKazutaka YOKOTA switch (adp->va_info.vi_pixel_size) { 25966e8394b8SKazutaka YOKOTA case sizeof(u_int16_t): 25976e8394b8SKazutaka YOKOTA fillw_io(val, adp->va_window, l/sizeof(u_int16_t)); 25986e8394b8SKazutaka YOKOTA break; 25996e8394b8SKazutaka YOKOTA case 3: 26006e8394b8SKazutaka YOKOTA /* FIXME */ 26016e8394b8SKazutaka YOKOTA break; 26026e8394b8SKazutaka YOKOTA case sizeof(u_int32_t): 26036e8394b8SKazutaka YOKOTA filll_io(val, adp->va_window, l/sizeof(u_int32_t)); 26046e8394b8SKazutaka YOKOTA break; 26056e8394b8SKazutaka YOKOTA } 26066e8394b8SKazutaka YOKOTA length -= l; 26076e8394b8SKazutaka YOKOTA at += l; 26086e8394b8SKazutaka YOKOTA } 26096e8394b8SKazutaka YOKOTA } 26106e8394b8SKazutaka YOKOTA 26116e8394b8SKazutaka YOKOTA static int 26126e8394b8SKazutaka YOKOTA vga_clear(video_adapter_t *adp) 26136e8394b8SKazutaka YOKOTA { 26146e8394b8SKazutaka YOKOTA switch (adp->va_info.vi_mem_model) { 26156e8394b8SKazutaka YOKOTA case V_INFO_MM_TEXT: 26166e8394b8SKazutaka YOKOTA /* do nothing? XXX */ 26176e8394b8SKazutaka YOKOTA break; 26186e8394b8SKazutaka YOKOTA case V_INFO_MM_PLANAR: 26196e8394b8SKazutaka YOKOTA planar_fill(adp, 0); 26206e8394b8SKazutaka YOKOTA break; 26216e8394b8SKazutaka YOKOTA case V_INFO_MM_PACKED: 26226e8394b8SKazutaka YOKOTA packed_fill(adp, 0); 26236e8394b8SKazutaka YOKOTA break; 26246e8394b8SKazutaka YOKOTA case V_INFO_MM_DIRECT: 26256e8394b8SKazutaka YOKOTA direct_fill(adp, 0); 26266e8394b8SKazutaka YOKOTA break; 26276e8394b8SKazutaka YOKOTA } 26286e8394b8SKazutaka YOKOTA return 0; 26296e8394b8SKazutaka YOKOTA } 26306e8394b8SKazutaka YOKOTA 26316e8394b8SKazutaka YOKOTA #ifdef notyet 26326e8394b8SKazutaka YOKOTA static void 26336e8394b8SKazutaka YOKOTA planar_fill_rect(video_adapter_t *adp, int val, int x, int y, int cx, int cy) 26346e8394b8SKazutaka YOKOTA { 26356e8394b8SKazutaka YOKOTA int banksize; 26366e8394b8SKazutaka YOKOTA int bank; 26376e8394b8SKazutaka YOKOTA int pos; 26386e8394b8SKazutaka YOKOTA int offset; /* offset within window */ 26396e8394b8SKazutaka YOKOTA int bx; 26406e8394b8SKazutaka YOKOTA int l; 26416e8394b8SKazutaka YOKOTA 26426e8394b8SKazutaka YOKOTA outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */ 26436e8394b8SKazutaka YOKOTA outw(GDCIDX, 0x0003); /* data rotate/function select */ 26446e8394b8SKazutaka YOKOTA outw(GDCIDX, 0x0f01); /* set/reset enable */ 26456e8394b8SKazutaka YOKOTA outw(GDCIDX, 0xff08); /* bit mask */ 26466e8394b8SKazutaka YOKOTA outw(GDCIDX, (val << 8) | 0x00); /* set/reset */ 26476e8394b8SKazutaka YOKOTA 26486e8394b8SKazutaka YOKOTA banksize = adp->va_window_size; 26496e8394b8SKazutaka YOKOTA bank = -1; 26506e8394b8SKazutaka YOKOTA while (cy > 0) { 26516e8394b8SKazutaka YOKOTA pos = adp->va_line_width*y + x/8; 26526e8394b8SKazutaka YOKOTA if (bank != pos/banksize) { 26539336e069SWojciech A. Koszek vidd_set_win_org(adp, pos); 26546e8394b8SKazutaka YOKOTA bank = pos/banksize; 26556e8394b8SKazutaka YOKOTA } 26566e8394b8SKazutaka YOKOTA offset = pos%banksize; 26576e8394b8SKazutaka YOKOTA bx = (x + cx)/8 - x/8; 26586e8394b8SKazutaka YOKOTA if (x % 8) { 26596e8394b8SKazutaka YOKOTA outw(GDCIDX, ((0xff00 >> (x % 8)) & 0xff00) | 0x08); 26606e8394b8SKazutaka YOKOTA writeb(adp->va_window + offset, 0); 26616e8394b8SKazutaka YOKOTA ++offset; 26626e8394b8SKazutaka YOKOTA --bx; 26636e8394b8SKazutaka YOKOTA if (offset >= banksize) { 26646e8394b8SKazutaka YOKOTA offset = 0; 26656e8394b8SKazutaka YOKOTA ++bank; /* next bank */ 26669336e069SWojciech A. Koszek vidd_set_win_org(adp, bank*banksize); 26676e8394b8SKazutaka YOKOTA } 26686e8394b8SKazutaka YOKOTA outw(GDCIDX, 0xff08); /* bit mask */ 26696e8394b8SKazutaka YOKOTA } 26706e8394b8SKazutaka YOKOTA while (bx > 0) { 26716e8394b8SKazutaka YOKOTA l = imin(bx, banksize); 26726e8394b8SKazutaka YOKOTA bzero_io(adp->va_window + offset, l); 26736e8394b8SKazutaka YOKOTA offset += l; 26746e8394b8SKazutaka YOKOTA bx -= l; 26756e8394b8SKazutaka YOKOTA if (offset >= banksize) { 26766e8394b8SKazutaka YOKOTA offset = 0; 26776e8394b8SKazutaka YOKOTA ++bank; /* next bank */ 26789336e069SWojciech A. Koszek vidd_set_win_org(adp, bank*banksize); 26796e8394b8SKazutaka YOKOTA } 26806e8394b8SKazutaka YOKOTA } 26816e8394b8SKazutaka YOKOTA if ((x + cx) % 8) { 26826e8394b8SKazutaka YOKOTA outw(GDCIDX, (~(0xff00 >> ((x + cx) % 8)) & 0xff00) | 0x08); 26836e8394b8SKazutaka YOKOTA writeb(adp->va_window + offset, 0); 26846e8394b8SKazutaka YOKOTA ++offset; 26856e8394b8SKazutaka YOKOTA if (offset >= banksize) { 26866e8394b8SKazutaka YOKOTA offset = 0; 26876e8394b8SKazutaka YOKOTA ++bank; /* next bank */ 26889336e069SWojciech A. Koszek vidd_set_win_org(adp, bank*banksize); 26896e8394b8SKazutaka YOKOTA } 26906e8394b8SKazutaka YOKOTA outw(GDCIDX, 0xff08); /* bit mask */ 26916e8394b8SKazutaka YOKOTA } 26926e8394b8SKazutaka YOKOTA ++y; 26936e8394b8SKazutaka YOKOTA --cy; 26946e8394b8SKazutaka YOKOTA } 26956e8394b8SKazutaka YOKOTA 26966e8394b8SKazutaka YOKOTA outw(GDCIDX, 0xff08); /* bit mask */ 26976e8394b8SKazutaka YOKOTA outw(GDCIDX, 0x0000); /* set/reset */ 26986e8394b8SKazutaka YOKOTA outw(GDCIDX, 0x0001); /* set/reset enable */ 26996e8394b8SKazutaka YOKOTA } 27006e8394b8SKazutaka YOKOTA 27016e8394b8SKazutaka YOKOTA static void 27026e8394b8SKazutaka YOKOTA packed_fill_rect(video_adapter_t *adp, int val, int x, int y, int cx, int cy) 27036e8394b8SKazutaka YOKOTA { 27046e8394b8SKazutaka YOKOTA int banksize; 27056e8394b8SKazutaka YOKOTA int bank; 27066e8394b8SKazutaka YOKOTA int pos; 27076e8394b8SKazutaka YOKOTA int offset; /* offset within window */ 27086e8394b8SKazutaka YOKOTA int end; 27096e8394b8SKazutaka YOKOTA 27106e8394b8SKazutaka YOKOTA banksize = adp->va_window_size; 27116e8394b8SKazutaka YOKOTA bank = -1; 27126e8394b8SKazutaka YOKOTA cx *= adp->va_info.vi_pixel_size; 27136e8394b8SKazutaka YOKOTA while (cy > 0) { 27146e8394b8SKazutaka YOKOTA pos = adp->va_line_width*y + x*adp->va_info.vi_pixel_size; 27156e8394b8SKazutaka YOKOTA if (bank != pos/banksize) { 27169336e069SWojciech A. Koszek vidd_set_win_org(adp, pos); 27176e8394b8SKazutaka YOKOTA bank = pos/banksize; 27186e8394b8SKazutaka YOKOTA } 27196e8394b8SKazutaka YOKOTA offset = pos%banksize; 27206e8394b8SKazutaka YOKOTA end = imin(offset + cx, banksize); 27216e8394b8SKazutaka YOKOTA fill_io(val, adp->va_window + offset, 27226e8394b8SKazutaka YOKOTA (end - offset)/adp->va_info.vi_pixel_size); 27236e8394b8SKazutaka YOKOTA /* the line may cross the window boundary */ 27246e8394b8SKazutaka YOKOTA if (offset + cx > banksize) { 27256e8394b8SKazutaka YOKOTA ++bank; /* next bank */ 27269336e069SWojciech A. Koszek vidd_set_win_org(adp, bank*banksize); 27276e8394b8SKazutaka YOKOTA end = offset + cx - banksize; 27286e8394b8SKazutaka YOKOTA fill_io(val, adp->va_window, end/adp->va_info.vi_pixel_size); 27296e8394b8SKazutaka YOKOTA } 27306e8394b8SKazutaka YOKOTA ++y; 27316e8394b8SKazutaka YOKOTA --cy; 27326e8394b8SKazutaka YOKOTA } 27336e8394b8SKazutaka YOKOTA } 27346e8394b8SKazutaka YOKOTA 27356e8394b8SKazutaka YOKOTA static void 27366e8394b8SKazutaka YOKOTA direct_fill_rect16(video_adapter_t *adp, int val, int x, int y, int cx, int cy) 27376e8394b8SKazutaka YOKOTA { 27386e8394b8SKazutaka YOKOTA int banksize; 27396e8394b8SKazutaka YOKOTA int bank; 27406e8394b8SKazutaka YOKOTA int pos; 27416e8394b8SKazutaka YOKOTA int offset; /* offset within window */ 27426e8394b8SKazutaka YOKOTA int end; 27436e8394b8SKazutaka YOKOTA 27446e8394b8SKazutaka YOKOTA /* 27456e8394b8SKazutaka YOKOTA * XXX: the function assumes that banksize is a muliple of 27466e8394b8SKazutaka YOKOTA * sizeof(u_int16_t). 27476e8394b8SKazutaka YOKOTA */ 27486e8394b8SKazutaka YOKOTA banksize = adp->va_window_size; 27496e8394b8SKazutaka YOKOTA bank = -1; 27506e8394b8SKazutaka YOKOTA cx *= sizeof(u_int16_t); 27516e8394b8SKazutaka YOKOTA while (cy > 0) { 27526e8394b8SKazutaka YOKOTA pos = adp->va_line_width*y + x*sizeof(u_int16_t); 27536e8394b8SKazutaka YOKOTA if (bank != pos/banksize) { 27549336e069SWojciech A. Koszek vidd_set_win_org(adp, pos); 27556e8394b8SKazutaka YOKOTA bank = pos/banksize; 27566e8394b8SKazutaka YOKOTA } 27576e8394b8SKazutaka YOKOTA offset = pos%banksize; 27586e8394b8SKazutaka YOKOTA end = imin(offset + cx, banksize); 27596e8394b8SKazutaka YOKOTA fillw_io(val, adp->va_window + offset, 27606e8394b8SKazutaka YOKOTA (end - offset)/sizeof(u_int16_t)); 27616e8394b8SKazutaka YOKOTA /* the line may cross the window boundary */ 27626e8394b8SKazutaka YOKOTA if (offset + cx > banksize) { 27636e8394b8SKazutaka YOKOTA ++bank; /* next bank */ 27649336e069SWojciech A. Koszek vidd_set_win_org(adp, bank*banksize); 27656e8394b8SKazutaka YOKOTA end = offset + cx - banksize; 27666e8394b8SKazutaka YOKOTA fillw_io(val, adp->va_window, end/sizeof(u_int16_t)); 27676e8394b8SKazutaka YOKOTA } 27686e8394b8SKazutaka YOKOTA ++y; 27696e8394b8SKazutaka YOKOTA --cy; 27706e8394b8SKazutaka YOKOTA } 27716e8394b8SKazutaka YOKOTA } 27726e8394b8SKazutaka YOKOTA 27736e8394b8SKazutaka YOKOTA static void 27746e8394b8SKazutaka YOKOTA direct_fill_rect24(video_adapter_t *adp, int val, int x, int y, int cx, int cy) 27756e8394b8SKazutaka YOKOTA { 27766e8394b8SKazutaka YOKOTA int banksize; 27776e8394b8SKazutaka YOKOTA int bank; 27786e8394b8SKazutaka YOKOTA int pos; 27796e8394b8SKazutaka YOKOTA int offset; /* offset within window */ 27806e8394b8SKazutaka YOKOTA int end; 27816e8394b8SKazutaka YOKOTA int i; 27826e8394b8SKazutaka YOKOTA int j; 27836e8394b8SKazutaka YOKOTA u_int8_t b[3]; 27846e8394b8SKazutaka YOKOTA 27856e8394b8SKazutaka YOKOTA b[0] = val & 0x0000ff; 27866e8394b8SKazutaka YOKOTA b[1] = (val >> 8) & 0x0000ff; 27876e8394b8SKazutaka YOKOTA b[2] = (val >> 16) & 0x0000ff; 27886e8394b8SKazutaka YOKOTA banksize = adp->va_window_size; 27896e8394b8SKazutaka YOKOTA bank = -1; 27906e8394b8SKazutaka YOKOTA cx *= 3; 27916e8394b8SKazutaka YOKOTA while (cy > 0) { 27926e8394b8SKazutaka YOKOTA pos = adp->va_line_width*y + x*3; 27936e8394b8SKazutaka YOKOTA if (bank != pos/banksize) { 27949336e069SWojciech A. Koszek vidd_set_win_org(adp, pos); 27956e8394b8SKazutaka YOKOTA bank = pos/banksize; 27966e8394b8SKazutaka YOKOTA } 27976e8394b8SKazutaka YOKOTA offset = pos%banksize; 27986e8394b8SKazutaka YOKOTA end = imin(offset + cx, banksize); 27996e8394b8SKazutaka YOKOTA for (i = 0, j = offset; j < end; i = (++i)%3, ++j) { 28006e8394b8SKazutaka YOKOTA writeb(adp->va_window + j, b[i]); 28016e8394b8SKazutaka YOKOTA } 28026e8394b8SKazutaka YOKOTA /* the line may cross the window boundary */ 28036e8394b8SKazutaka YOKOTA if (offset + cx >= banksize) { 28046e8394b8SKazutaka YOKOTA ++bank; /* next bank */ 28059336e069SWojciech A. Koszek vidd_set_win_org(adp, bank*banksize); 28066e8394b8SKazutaka YOKOTA j = 0; 28076e8394b8SKazutaka YOKOTA end = offset + cx - banksize; 28086e8394b8SKazutaka YOKOTA for (; j < end; i = (++i)%3, ++j) { 28096e8394b8SKazutaka YOKOTA writeb(adp->va_window + j, b[i]); 28106e8394b8SKazutaka YOKOTA } 28116e8394b8SKazutaka YOKOTA } 28126e8394b8SKazutaka YOKOTA ++y; 28136e8394b8SKazutaka YOKOTA --cy; 28146e8394b8SKazutaka YOKOTA } 28156e8394b8SKazutaka YOKOTA } 28166e8394b8SKazutaka YOKOTA 28176e8394b8SKazutaka YOKOTA static void 28186e8394b8SKazutaka YOKOTA direct_fill_rect32(video_adapter_t *adp, int val, int x, int y, int cx, int cy) 28196e8394b8SKazutaka YOKOTA { 28206e8394b8SKazutaka YOKOTA int banksize; 28216e8394b8SKazutaka YOKOTA int bank; 28226e8394b8SKazutaka YOKOTA int pos; 28236e8394b8SKazutaka YOKOTA int offset; /* offset within window */ 28246e8394b8SKazutaka YOKOTA int end; 28256e8394b8SKazutaka YOKOTA 28266e8394b8SKazutaka YOKOTA /* 28276e8394b8SKazutaka YOKOTA * XXX: the function assumes that banksize is a muliple of 28286e8394b8SKazutaka YOKOTA * sizeof(u_int32_t). 28296e8394b8SKazutaka YOKOTA */ 28306e8394b8SKazutaka YOKOTA banksize = adp->va_window_size; 28316e8394b8SKazutaka YOKOTA bank = -1; 28326e8394b8SKazutaka YOKOTA cx *= sizeof(u_int32_t); 28336e8394b8SKazutaka YOKOTA while (cy > 0) { 28346e8394b8SKazutaka YOKOTA pos = adp->va_line_width*y + x*sizeof(u_int32_t); 28356e8394b8SKazutaka YOKOTA if (bank != pos/banksize) { 28369336e069SWojciech A. Koszek vidd_set_win_org(adp, pos); 28376e8394b8SKazutaka YOKOTA bank = pos/banksize; 28386e8394b8SKazutaka YOKOTA } 28396e8394b8SKazutaka YOKOTA offset = pos%banksize; 28406e8394b8SKazutaka YOKOTA end = imin(offset + cx, banksize); 28416e8394b8SKazutaka YOKOTA filll_io(val, adp->va_window + offset, 28426e8394b8SKazutaka YOKOTA (end - offset)/sizeof(u_int32_t)); 28436e8394b8SKazutaka YOKOTA /* the line may cross the window boundary */ 28446e8394b8SKazutaka YOKOTA if (offset + cx > banksize) { 28456e8394b8SKazutaka YOKOTA ++bank; /* next bank */ 28469336e069SWojciech A. Koszek vidd_set_win_org(adp, bank*banksize); 28476e8394b8SKazutaka YOKOTA end = offset + cx - banksize; 28486e8394b8SKazutaka YOKOTA filll_io(val, adp->va_window, end/sizeof(u_int32_t)); 28496e8394b8SKazutaka YOKOTA } 28506e8394b8SKazutaka YOKOTA ++y; 28516e8394b8SKazutaka YOKOTA --cy; 28526e8394b8SKazutaka YOKOTA } 28536e8394b8SKazutaka YOKOTA } 28546e8394b8SKazutaka YOKOTA 28556e8394b8SKazutaka YOKOTA static int 28566e8394b8SKazutaka YOKOTA vga_fill_rect(video_adapter_t *adp, int val, int x, int y, int cx, int cy) 28576e8394b8SKazutaka YOKOTA { 28586e8394b8SKazutaka YOKOTA switch (adp->va_info.vi_mem_model) { 28596e8394b8SKazutaka YOKOTA case V_INFO_MM_TEXT: 28606e8394b8SKazutaka YOKOTA /* do nothing? XXX */ 28616e8394b8SKazutaka YOKOTA break; 28626e8394b8SKazutaka YOKOTA case V_INFO_MM_PLANAR: 28636e8394b8SKazutaka YOKOTA planar_fill_rect(adp, val, x, y, cx, cy); 28646e8394b8SKazutaka YOKOTA break; 28656e8394b8SKazutaka YOKOTA case V_INFO_MM_PACKED: 28666e8394b8SKazutaka YOKOTA packed_fill_rect(adp, val, x, y, cx, cy); 28676e8394b8SKazutaka YOKOTA break; 28686e8394b8SKazutaka YOKOTA case V_INFO_MM_DIRECT: 28696e8394b8SKazutaka YOKOTA switch (adp->va_info.vi_pixel_size) { 28706e8394b8SKazutaka YOKOTA case sizeof(u_int16_t): 28716e8394b8SKazutaka YOKOTA direct_fill_rect16(adp, val, x, y, cx, cy); 28726e8394b8SKazutaka YOKOTA break; 28736e8394b8SKazutaka YOKOTA case 3: 28746e8394b8SKazutaka YOKOTA direct_fill_rect24(adp, val, x, y, cx, cy); 28756e8394b8SKazutaka YOKOTA break; 28766e8394b8SKazutaka YOKOTA case sizeof(u_int32_t): 28776e8394b8SKazutaka YOKOTA direct_fill_rect32(adp, val, x, y, cx, cy); 28786e8394b8SKazutaka YOKOTA break; 28796e8394b8SKazutaka YOKOTA } 28806e8394b8SKazutaka YOKOTA break; 28816e8394b8SKazutaka YOKOTA } 28826e8394b8SKazutaka YOKOTA return 0; 28836e8394b8SKazutaka YOKOTA } 28846e8394b8SKazutaka YOKOTA #else /* !notyet */ 28856e8394b8SKazutaka YOKOTA static int 28866e8394b8SKazutaka YOKOTA vga_fill_rect(video_adapter_t *adp, int val, int x, int y, int cx, int cy) 28876e8394b8SKazutaka YOKOTA { 28886e8394b8SKazutaka YOKOTA return ENODEV; 28896e8394b8SKazutaka YOKOTA } 28906e8394b8SKazutaka YOKOTA #endif /* notyet */ 28916e8394b8SKazutaka YOKOTA 28926e8394b8SKazutaka YOKOTA static int 28936e8394b8SKazutaka YOKOTA vga_bitblt(video_adapter_t *adp,...) 28946e8394b8SKazutaka YOKOTA { 28956e8394b8SKazutaka YOKOTA /* FIXME */ 28966e8394b8SKazutaka YOKOTA return ENODEV; 28976e8394b8SKazutaka YOKOTA } 28986e8394b8SKazutaka YOKOTA 28996e8394b8SKazutaka YOKOTA #endif /* !VGA_NO_MODE_CHANGE */ 29006e8394b8SKazutaka YOKOTA 29016e8394b8SKazutaka YOKOTA static int 29026e8394b8SKazutaka YOKOTA get_palette(video_adapter_t *adp, int base, int count, 29036e8394b8SKazutaka YOKOTA u_char *red, u_char *green, u_char *blue, u_char *trans) 29046e8394b8SKazutaka YOKOTA { 29056e8394b8SKazutaka YOKOTA u_char *r; 29066e8394b8SKazutaka YOKOTA u_char *g; 29076e8394b8SKazutaka YOKOTA u_char *b; 29086e8394b8SKazutaka YOKOTA 29094f2eff8cSJacques Vidrine if (count < 0 || base < 0 || count > 256 || base > 256 || 29104f2eff8cSJacques Vidrine base + count > 256) 29116e8394b8SKazutaka YOKOTA return EINVAL; 29126e8394b8SKazutaka YOKOTA 2913a163d034SWarner Losh r = malloc(count*3, M_DEVBUF, M_WAITOK); 29146e8394b8SKazutaka YOKOTA g = r + count; 29156e8394b8SKazutaka YOKOTA b = g + count; 29168311f05aSPoul-Henning Kamp if (vga_save_palette2(adp, base, count, r, g, b)) { 29178311f05aSPoul-Henning Kamp free(r, M_DEVBUF); 29186e8394b8SKazutaka YOKOTA return ENODEV; 29198311f05aSPoul-Henning Kamp } 29206e8394b8SKazutaka YOKOTA copyout(r, red, count); 29216e8394b8SKazutaka YOKOTA copyout(g, green, count); 29226e8394b8SKazutaka YOKOTA copyout(b, blue, count); 29236e8394b8SKazutaka YOKOTA if (trans != NULL) { 29246e8394b8SKazutaka YOKOTA bzero(r, count); 29256e8394b8SKazutaka YOKOTA copyout(r, trans, count); 29266e8394b8SKazutaka YOKOTA } 29276e8394b8SKazutaka YOKOTA free(r, M_DEVBUF); 29286e8394b8SKazutaka YOKOTA 29296e8394b8SKazutaka YOKOTA return 0; 29306e8394b8SKazutaka YOKOTA } 29316e8394b8SKazutaka YOKOTA 29326e8394b8SKazutaka YOKOTA static int 29336e8394b8SKazutaka YOKOTA set_palette(video_adapter_t *adp, int base, int count, 29346e8394b8SKazutaka YOKOTA u_char *red, u_char *green, u_char *blue, u_char *trans) 29356e8394b8SKazutaka YOKOTA { 29366e8394b8SKazutaka YOKOTA u_char *r; 29376e8394b8SKazutaka YOKOTA u_char *g; 29386e8394b8SKazutaka YOKOTA u_char *b; 29396e8394b8SKazutaka YOKOTA int err; 29406e8394b8SKazutaka YOKOTA 29414f2eff8cSJacques Vidrine if (count < 0 || base < 0 || count > 256 || base > 256 || 29424f2eff8cSJacques Vidrine base + count > 256) 29436e8394b8SKazutaka YOKOTA return EINVAL; 29446e8394b8SKazutaka YOKOTA 2945a163d034SWarner Losh r = malloc(count*3, M_DEVBUF, M_WAITOK); 29466e8394b8SKazutaka YOKOTA g = r + count; 29476e8394b8SKazutaka YOKOTA b = g + count; 2948ca640ca9SSam Leffler err = copyin(red, r, count); 2949ca640ca9SSam Leffler if (!err) 2950ca640ca9SSam Leffler err = copyin(green, g, count); 2951ca640ca9SSam Leffler if (!err) 2952ca640ca9SSam Leffler err = copyin(blue, b, count); 2953ca640ca9SSam Leffler if (!err) 29546e8394b8SKazutaka YOKOTA err = vga_load_palette2(adp, base, count, r, g, b); 29556e8394b8SKazutaka YOKOTA free(r, M_DEVBUF); 29566e8394b8SKazutaka YOKOTA 29576e8394b8SKazutaka YOKOTA return (err ? ENODEV : 0); 29586e8394b8SKazutaka YOKOTA } 29596e8394b8SKazutaka YOKOTA 29606e8394b8SKazutaka YOKOTA static int 29616e8394b8SKazutaka YOKOTA vga_dev_ioctl(video_adapter_t *adp, u_long cmd, caddr_t arg) 29626e8394b8SKazutaka YOKOTA { 29636e8394b8SKazutaka YOKOTA switch (cmd) { 29646e8394b8SKazutaka YOKOTA case FBIO_GETWINORG: /* get frame buffer window origin */ 29656e8394b8SKazutaka YOKOTA *(u_int *)arg = 0; 29666e8394b8SKazutaka YOKOTA return 0; 29676e8394b8SKazutaka YOKOTA 29686e8394b8SKazutaka YOKOTA case FBIO_SETWINORG: /* set frame buffer window origin */ 29696e8394b8SKazutaka YOKOTA return ENODEV; 29706e8394b8SKazutaka YOKOTA 29716e8394b8SKazutaka YOKOTA case FBIO_SETDISPSTART: /* set display start address */ 29726e8394b8SKazutaka YOKOTA return (set_display_start(adp, 29736e8394b8SKazutaka YOKOTA ((video_display_start_t *)arg)->x, 29746e8394b8SKazutaka YOKOTA ((video_display_start_t *)arg)->y) 29756e8394b8SKazutaka YOKOTA ? ENODEV : 0); 29766e8394b8SKazutaka YOKOTA 29776e8394b8SKazutaka YOKOTA case FBIO_SETLINEWIDTH: /* set scan line length in pixel */ 29786e8394b8SKazutaka YOKOTA return (set_line_length(adp, *(u_int *)arg) ? ENODEV : 0); 29796e8394b8SKazutaka YOKOTA 29806e8394b8SKazutaka YOKOTA case FBIO_GETPALETTE: /* get color palette */ 29816e8394b8SKazutaka YOKOTA return get_palette(adp, ((video_color_palette_t *)arg)->index, 29826e8394b8SKazutaka YOKOTA ((video_color_palette_t *)arg)->count, 29836e8394b8SKazutaka YOKOTA ((video_color_palette_t *)arg)->red, 29846e8394b8SKazutaka YOKOTA ((video_color_palette_t *)arg)->green, 29856e8394b8SKazutaka YOKOTA ((video_color_palette_t *)arg)->blue, 29866e8394b8SKazutaka YOKOTA ((video_color_palette_t *)arg)->transparent); 29876e8394b8SKazutaka YOKOTA 29886e8394b8SKazutaka YOKOTA case FBIO_SETPALETTE: /* set color palette */ 29896e8394b8SKazutaka YOKOTA return set_palette(adp, ((video_color_palette_t *)arg)->index, 29906e8394b8SKazutaka YOKOTA ((video_color_palette_t *)arg)->count, 29916e8394b8SKazutaka YOKOTA ((video_color_palette_t *)arg)->red, 29926e8394b8SKazutaka YOKOTA ((video_color_palette_t *)arg)->green, 29936e8394b8SKazutaka YOKOTA ((video_color_palette_t *)arg)->blue, 29946e8394b8SKazutaka YOKOTA ((video_color_palette_t *)arg)->transparent); 29956e8394b8SKazutaka YOKOTA 29966e8394b8SKazutaka YOKOTA case FBIOGTYPE: /* get frame buffer type info. */ 29976e8394b8SKazutaka YOKOTA ((struct fbtype *)arg)->fb_type = fb_type(adp->va_type); 29986e8394b8SKazutaka YOKOTA ((struct fbtype *)arg)->fb_height = adp->va_info.vi_height; 29996e8394b8SKazutaka YOKOTA ((struct fbtype *)arg)->fb_width = adp->va_info.vi_width; 30006e8394b8SKazutaka YOKOTA ((struct fbtype *)arg)->fb_depth = adp->va_info.vi_depth; 30016e8394b8SKazutaka YOKOTA if ((adp->va_info.vi_depth <= 1) || (adp->va_info.vi_depth > 8)) 30026e8394b8SKazutaka YOKOTA ((struct fbtype *)arg)->fb_cmsize = 0; 30036e8394b8SKazutaka YOKOTA else 30046e8394b8SKazutaka YOKOTA ((struct fbtype *)arg)->fb_cmsize = 1 << adp->va_info.vi_depth; 30056e8394b8SKazutaka YOKOTA ((struct fbtype *)arg)->fb_size = adp->va_buffer_size; 30066e8394b8SKazutaka YOKOTA return 0; 30076e8394b8SKazutaka YOKOTA 30086e8394b8SKazutaka YOKOTA case FBIOGETCMAP: /* get color palette */ 30096e8394b8SKazutaka YOKOTA return get_palette(adp, ((struct fbcmap *)arg)->index, 30106e8394b8SKazutaka YOKOTA ((struct fbcmap *)arg)->count, 30116e8394b8SKazutaka YOKOTA ((struct fbcmap *)arg)->red, 30126e8394b8SKazutaka YOKOTA ((struct fbcmap *)arg)->green, 30136e8394b8SKazutaka YOKOTA ((struct fbcmap *)arg)->blue, NULL); 30146e8394b8SKazutaka YOKOTA 30156e8394b8SKazutaka YOKOTA case FBIOPUTCMAP: /* set color palette */ 30166e8394b8SKazutaka YOKOTA return set_palette(adp, ((struct fbcmap *)arg)->index, 30176e8394b8SKazutaka YOKOTA ((struct fbcmap *)arg)->count, 30186e8394b8SKazutaka YOKOTA ((struct fbcmap *)arg)->red, 30196e8394b8SKazutaka YOKOTA ((struct fbcmap *)arg)->green, 30206e8394b8SKazutaka YOKOTA ((struct fbcmap *)arg)->blue, NULL); 30216e8394b8SKazutaka YOKOTA 30226e8394b8SKazutaka YOKOTA default: 30236e8394b8SKazutaka YOKOTA return fb_commonioctl(adp, cmd, arg); 30246e8394b8SKazutaka YOKOTA } 30256e8394b8SKazutaka YOKOTA } 30266e8394b8SKazutaka YOKOTA 30276e8394b8SKazutaka YOKOTA static void 30286e8394b8SKazutaka YOKOTA dump_buffer(u_char *buf, size_t len) 30296e8394b8SKazutaka YOKOTA { 30306e8394b8SKazutaka YOKOTA int i; 30316e8394b8SKazutaka YOKOTA 30326e8394b8SKazutaka YOKOTA for(i = 0; i < len;) { 30336e8394b8SKazutaka YOKOTA printf("%02x ", buf[i]); 30346e8394b8SKazutaka YOKOTA if ((++i % 16) == 0) 30356e8394b8SKazutaka YOKOTA printf("\n"); 30366e8394b8SKazutaka YOKOTA } 30376e8394b8SKazutaka YOKOTA } 30386e8394b8SKazutaka YOKOTA 30396e8394b8SKazutaka YOKOTA /* 30406e8394b8SKazutaka YOKOTA * diag(): 30416e8394b8SKazutaka YOKOTA * Print some information about the video adapter and video modes, 30426e8394b8SKazutaka YOKOTA * with requested level of details. 30436e8394b8SKazutaka YOKOTA * 30446e8394b8SKazutaka YOKOTA * all adapters 30456e8394b8SKazutaka YOKOTA */ 30466e8394b8SKazutaka YOKOTA static int 30476e8394b8SKazutaka YOKOTA vga_diag(video_adapter_t *adp, int level) 30486e8394b8SKazutaka YOKOTA { 30496e8394b8SKazutaka YOKOTA u_char *mp; 30506e8394b8SKazutaka YOKOTA #if FB_DEBUG > 1 30516e8394b8SKazutaka YOKOTA video_info_t info; 30526e8394b8SKazutaka YOKOTA int i; 30536e8394b8SKazutaka YOKOTA #endif 30546e8394b8SKazutaka YOKOTA 30556e8394b8SKazutaka YOKOTA if (!vga_init_done) 30566e8394b8SKazutaka YOKOTA return ENXIO; 30576e8394b8SKazutaka YOKOTA 30586e8394b8SKazutaka YOKOTA #if FB_DEBUG > 1 30596e8394b8SKazutaka YOKOTA #ifndef VGA_NO_BIOS 30606e8394b8SKazutaka YOKOTA printf("vga: RTC equip. code:0x%02x, DCC code:0x%02x\n", 30616e8394b8SKazutaka YOKOTA rtcin(RTC_EQUIPMENT), readb(BIOS_PADDRTOVADDR(0x488))); 30626e8394b8SKazutaka YOKOTA printf("vga: CRTC:0x%x, video option:0x%02x, ", 30636e8394b8SKazutaka YOKOTA readw(BIOS_PADDRTOVADDR(0x463)), 30646e8394b8SKazutaka YOKOTA readb(BIOS_PADDRTOVADDR(0x487))); 30656e8394b8SKazutaka YOKOTA printf("rows:%d, cols:%d, font height:%d\n", 30666e8394b8SKazutaka YOKOTA readb(BIOS_PADDRTOVADDR(0x44a)), 30676e8394b8SKazutaka YOKOTA readb(BIOS_PADDRTOVADDR(0x484)) + 1, 30686e8394b8SKazutaka YOKOTA readb(BIOS_PADDRTOVADDR(0x485))); 30696e8394b8SKazutaka YOKOTA #endif /* VGA_NO_BIOS */ 30706e8394b8SKazutaka YOKOTA #if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE) 30716e8394b8SKazutaka YOKOTA printf("vga: param table EGA/VGA:%p", video_mode_ptr); 30726e8394b8SKazutaka YOKOTA printf(", CGA/MDA:%p\n", video_mode_ptr2); 30736e8394b8SKazutaka YOKOTA printf("vga: rows_offset:%d\n", rows_offset); 30746e8394b8SKazutaka YOKOTA #endif 30756e8394b8SKazutaka YOKOTA #endif /* FB_DEBUG > 1 */ 30766e8394b8SKazutaka YOKOTA 30776e8394b8SKazutaka YOKOTA fb_dump_adp_info(VGA_DRIVER_NAME, adp, level); 30786e8394b8SKazutaka YOKOTA 30796e8394b8SKazutaka YOKOTA #if FB_DEBUG > 1 30806e8394b8SKazutaka YOKOTA if (adp->va_flags & V_ADP_MODECHANGE) { 30816e8394b8SKazutaka YOKOTA for (i = 0; bios_vmode[i].vi_mode != EOT; ++i) { 30826e8394b8SKazutaka YOKOTA if (bios_vmode[i].vi_mode == NA) 30836e8394b8SKazutaka YOKOTA continue; 30846e8394b8SKazutaka YOKOTA if (get_mode_param(bios_vmode[i].vi_mode) == NULL) 30856e8394b8SKazutaka YOKOTA continue; 30866e8394b8SKazutaka YOKOTA fb_dump_mode_info(VGA_DRIVER_NAME, adp, &bios_vmode[i], level); 30876e8394b8SKazutaka YOKOTA } 30886e8394b8SKazutaka YOKOTA } else { 30896e8394b8SKazutaka YOKOTA vga_get_info(adp, adp->va_initial_mode, &info); /* shouldn't fail */ 30906e8394b8SKazutaka YOKOTA fb_dump_mode_info(VGA_DRIVER_NAME, adp, &info, level); 30916e8394b8SKazutaka YOKOTA } 30926e8394b8SKazutaka YOKOTA #endif /* FB_DEBUG > 1 */ 30936e8394b8SKazutaka YOKOTA 30946e8394b8SKazutaka YOKOTA if ((adp->va_type != KD_EGA) && (adp->va_type != KD_VGA)) 30956e8394b8SKazutaka YOKOTA return 0; 30966e8394b8SKazutaka YOKOTA #if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE) 30976e8394b8SKazutaka YOKOTA if (video_mode_ptr == NULL) 30986e8394b8SKazutaka YOKOTA printf("vga%d: %s: WARNING: video mode switching is not " 30996e8394b8SKazutaka YOKOTA "fully supported on this adapter\n", 31006e8394b8SKazutaka YOKOTA adp->va_unit, adp->va_name); 31016e8394b8SKazutaka YOKOTA #endif 31026e8394b8SKazutaka YOKOTA if (level <= 0) 31036e8394b8SKazutaka YOKOTA return 0; 31046e8394b8SKazutaka YOKOTA 31056e8394b8SKazutaka YOKOTA if (adp->va_type == KD_VGA) { 31066e8394b8SKazutaka YOKOTA printf("VGA parameters upon power-up\n"); 31076e8394b8SKazutaka YOKOTA dump_buffer(adpstate.regs, sizeof(adpstate.regs)); 31086e8394b8SKazutaka YOKOTA printf("VGA parameters in BIOS for mode %d\n", adp->va_initial_mode); 31096e8394b8SKazutaka YOKOTA dump_buffer(adpstate2.regs, sizeof(adpstate2.regs)); 31106e8394b8SKazutaka YOKOTA } 31116e8394b8SKazutaka YOKOTA 31126e8394b8SKazutaka YOKOTA mp = get_mode_param(adp->va_initial_mode); 31136e8394b8SKazutaka YOKOTA if (mp == NULL) /* this shouldn't be happening */ 31146e8394b8SKazutaka YOKOTA return 0; 31156e8394b8SKazutaka YOKOTA printf("EGA/VGA parameters to be used for mode %d\n", adp->va_initial_mode); 31166e8394b8SKazutaka YOKOTA dump_buffer(mp, V_MODE_PARAM_SIZE); 31176e8394b8SKazutaka YOKOTA 31186e8394b8SKazutaka YOKOTA return 0; 31196e8394b8SKazutaka YOKOTA } 3120