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