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