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 * 296e8394b8SKazutaka YOKOTA * $Id: $ 306e8394b8SKazutaka YOKOTA */ 316e8394b8SKazutaka YOKOTA 326e8394b8SKazutaka YOKOTA #include "vga.h" 336e8394b8SKazutaka YOKOTA #include "opt_vga.h" 346e8394b8SKazutaka YOKOTA #include "opt_fb.h" 356e8394b8SKazutaka YOKOTA #include "opt_syscons.h" /* should be removed in the future, XXX */ 366e8394b8SKazutaka YOKOTA 376e8394b8SKazutaka YOKOTA #if NVGA > 0 386e8394b8SKazutaka YOKOTA 396e8394b8SKazutaka YOKOTA #include <sys/param.h> 406e8394b8SKazutaka YOKOTA #include <sys/systm.h> 416e8394b8SKazutaka YOKOTA #include <sys/kernel.h> 426e8394b8SKazutaka YOKOTA #include <sys/conf.h> 436e8394b8SKazutaka YOKOTA #include <sys/proc.h> 446e8394b8SKazutaka YOKOTA #include <sys/fcntl.h> 456e8394b8SKazutaka YOKOTA #include <sys/malloc.h> 466e8394b8SKazutaka YOKOTA #include <sys/fbio.h> 476e8394b8SKazutaka YOKOTA 486e8394b8SKazutaka YOKOTA #include <vm/vm.h> 496e8394b8SKazutaka YOKOTA #include <vm/vm_param.h> 506e8394b8SKazutaka YOKOTA #include <vm/pmap.h> 516e8394b8SKazutaka YOKOTA 526e8394b8SKazutaka YOKOTA #include <machine/md_var.h> 536e8394b8SKazutaka YOKOTA #include <machine/pc/bios.h> 546e8394b8SKazutaka YOKOTA 556e8394b8SKazutaka YOKOTA #include <dev/fb/fbreg.h> 566e8394b8SKazutaka YOKOTA #include <dev/fb/vgareg.h> 576e8394b8SKazutaka YOKOTA 586e8394b8SKazutaka YOKOTA #include <isa/isareg.h> 596e8394b8SKazutaka YOKOTA 606e8394b8SKazutaka YOKOTA #ifndef VGA_DEBUG 616e8394b8SKazutaka YOKOTA #define VGA_DEBUG 0 626e8394b8SKazutaka YOKOTA #endif 636e8394b8SKazutaka YOKOTA 646e8394b8SKazutaka YOKOTA int 656e8394b8SKazutaka YOKOTA vga_probe_unit(int unit, video_adapter_t *buf, int flags) 666e8394b8SKazutaka YOKOTA { 676e8394b8SKazutaka YOKOTA video_adapter_t *adp; 686e8394b8SKazutaka YOKOTA video_switch_t *sw; 696e8394b8SKazutaka YOKOTA int error; 706e8394b8SKazutaka YOKOTA 716e8394b8SKazutaka YOKOTA sw = vid_get_switch(VGA_DRIVER_NAME); 726e8394b8SKazutaka YOKOTA if (sw == NULL) 736e8394b8SKazutaka YOKOTA return 0; 746e8394b8SKazutaka YOKOTA error = (*sw->probe)(unit, &adp, NULL, flags); 756e8394b8SKazutaka YOKOTA if (error) 766e8394b8SKazutaka YOKOTA return error; 776e8394b8SKazutaka YOKOTA bcopy(adp, buf, sizeof(*buf)); 786e8394b8SKazutaka YOKOTA return 0; 796e8394b8SKazutaka YOKOTA } 806e8394b8SKazutaka YOKOTA 816e8394b8SKazutaka YOKOTA int 826e8394b8SKazutaka YOKOTA vga_attach_unit(int unit, vga_softc_t *sc, int flags) 836e8394b8SKazutaka YOKOTA { 846e8394b8SKazutaka YOKOTA video_switch_t *sw; 856e8394b8SKazutaka YOKOTA int error; 866e8394b8SKazutaka YOKOTA 876e8394b8SKazutaka YOKOTA sw = vid_get_switch(VGA_DRIVER_NAME); 886e8394b8SKazutaka YOKOTA if (sw == NULL) 896e8394b8SKazutaka YOKOTA return ENXIO; 906e8394b8SKazutaka YOKOTA 916e8394b8SKazutaka YOKOTA error = (*sw->probe)(unit, &sc->adp, NULL, flags); 926e8394b8SKazutaka YOKOTA if (error) 936e8394b8SKazutaka YOKOTA return error; 946e8394b8SKazutaka YOKOTA return (*sw->init)(unit, sc->adp, flags); 956e8394b8SKazutaka YOKOTA } 966e8394b8SKazutaka YOKOTA 976e8394b8SKazutaka YOKOTA /* cdev driver functions */ 986e8394b8SKazutaka YOKOTA 996e8394b8SKazutaka YOKOTA #ifdef FB_INSTALL_CDEV 1006e8394b8SKazutaka YOKOTA 1016e8394b8SKazutaka YOKOTA int 1026e8394b8SKazutaka YOKOTA vga_open(dev_t dev, vga_softc_t *sc, int flag, int mode, struct proc *p) 1036e8394b8SKazutaka YOKOTA { 1046e8394b8SKazutaka YOKOTA if (sc == NULL) 1056e8394b8SKazutaka YOKOTA return ENXIO; 1066e8394b8SKazutaka YOKOTA if (mode & (O_CREAT | O_APPEND | O_TRUNC)) 1076e8394b8SKazutaka YOKOTA return ENODEV; 1086e8394b8SKazutaka YOKOTA 1096e8394b8SKazutaka YOKOTA return genfbopen(&sc->gensc, sc->adp, flag, mode, p); 1106e8394b8SKazutaka YOKOTA } 1116e8394b8SKazutaka YOKOTA 1126e8394b8SKazutaka YOKOTA int 1136e8394b8SKazutaka YOKOTA vga_close(dev_t dev, vga_softc_t *sc, int flag, int mode, struct proc *p) 1146e8394b8SKazutaka YOKOTA { 1156e8394b8SKazutaka YOKOTA return genfbclose(&sc->gensc, sc->adp, flag, mode, p); 1166e8394b8SKazutaka YOKOTA } 1176e8394b8SKazutaka YOKOTA 1186e8394b8SKazutaka YOKOTA int 1196e8394b8SKazutaka YOKOTA vga_read(dev_t dev, vga_softc_t *sc, struct uio *uio, int flag) 1206e8394b8SKazutaka YOKOTA { 1216e8394b8SKazutaka YOKOTA return genfbread(&sc->gensc, sc->adp, uio, flag); 1226e8394b8SKazutaka YOKOTA } 1236e8394b8SKazutaka YOKOTA 1246e8394b8SKazutaka YOKOTA int 1256e8394b8SKazutaka YOKOTA vga_write(dev_t dev, vga_softc_t *sc, struct uio *uio, int flag) 1266e8394b8SKazutaka YOKOTA { 1276e8394b8SKazutaka YOKOTA return genfbread(&sc->gensc, sc->adp, uio, flag); 1286e8394b8SKazutaka YOKOTA } 1296e8394b8SKazutaka YOKOTA 1306e8394b8SKazutaka YOKOTA int 1316e8394b8SKazutaka YOKOTA vga_ioctl(dev_t dev, vga_softc_t *sc, u_long cmd, caddr_t arg, int flag, 1326e8394b8SKazutaka YOKOTA struct proc *p) 1336e8394b8SKazutaka YOKOTA { 1346e8394b8SKazutaka YOKOTA return genfbioctl(&sc->gensc, sc->adp, cmd, arg, flag, p); 1356e8394b8SKazutaka YOKOTA } 1366e8394b8SKazutaka YOKOTA 1376e8394b8SKazutaka YOKOTA int 1386e8394b8SKazutaka YOKOTA vga_mmap(dev_t dev, vga_softc_t *sc, vm_offset_t offset, int prot) 1396e8394b8SKazutaka YOKOTA { 1406e8394b8SKazutaka YOKOTA return genfbmmap(&sc->gensc, sc->adp, offset, prot); 1416e8394b8SKazutaka YOKOTA } 1426e8394b8SKazutaka YOKOTA 1436e8394b8SKazutaka YOKOTA #endif /* FB_INSTALL_CDEV */ 1446e8394b8SKazutaka YOKOTA 1456e8394b8SKazutaka YOKOTA /* LOW-LEVEL */ 1466e8394b8SKazutaka YOKOTA 1476e8394b8SKazutaka YOKOTA #include <machine/clock.h> 1486e8394b8SKazutaka YOKOTA #include <machine/pc/vesa.h> 1496e8394b8SKazutaka YOKOTA 1506e8394b8SKazutaka YOKOTA #define probe_done(adp) ((adp)->va_flags & V_ADP_PROBED) 1516e8394b8SKazutaka YOKOTA #define init_done(adp) ((adp)->va_flags & V_ADP_INITIALIZED) 1526e8394b8SKazutaka YOKOTA #define config_done(adp) ((adp)->va_flags & V_ADP_REGISTERED) 1536e8394b8SKazutaka YOKOTA 1546e8394b8SKazutaka YOKOTA /* for compatibility with old kernel options */ 1556e8394b8SKazutaka YOKOTA #ifdef SC_ALT_SEQACCESS 1566e8394b8SKazutaka YOKOTA #undef SC_ALT_SEQACCESS 1576e8394b8SKazutaka YOKOTA #undef VGA_ALT_SEQACCESS 1586e8394b8SKazutaka YOKOTA #define VGA_ALT_SEQACCESS 1 1596e8394b8SKazutaka YOKOTA #endif 1606e8394b8SKazutaka YOKOTA 1616e8394b8SKazutaka YOKOTA #ifdef SLOW_VGA 1626e8394b8SKazutaka YOKOTA #undef SLOW_VGA 1636e8394b8SKazutaka YOKOTA #undef VGA_SLOW_IOACCESS 1646e8394b8SKazutaka YOKOTA #define VGA_SLOW_IOACCESS 1 1656e8394b8SKazutaka YOKOTA #endif 1666e8394b8SKazutaka YOKOTA 1676e8394b8SKazutaka YOKOTA /* architecture dependent option */ 1686e8394b8SKazutaka YOKOTA #ifdef __alpha__ 1696e8394b8SKazutaka YOKOTA #define VGA_NO_BIOS 1 1706e8394b8SKazutaka YOKOTA #endif 1716e8394b8SKazutaka YOKOTA 1726e8394b8SKazutaka YOKOTA /* this should really be in `rtc.h' */ 1736e8394b8SKazutaka YOKOTA #define RTC_EQUIPMENT 0x14 1746e8394b8SKazutaka YOKOTA 1756e8394b8SKazutaka YOKOTA /* various sizes */ 1766e8394b8SKazutaka YOKOTA #define V_MODE_MAP_SIZE (M_VGA_CG320 + 1) 1776e8394b8SKazutaka YOKOTA #define V_MODE_PARAM_SIZE 64 1786e8394b8SKazutaka YOKOTA 1796e8394b8SKazutaka YOKOTA /* video adapter state buffer */ 1806e8394b8SKazutaka YOKOTA struct adp_state { 1816e8394b8SKazutaka YOKOTA int sig; 1826e8394b8SKazutaka YOKOTA #define V_STATE_SIG 0x736f6962 1836e8394b8SKazutaka YOKOTA u_char regs[V_MODE_PARAM_SIZE]; 1846e8394b8SKazutaka YOKOTA }; 1856e8394b8SKazutaka YOKOTA typedef struct adp_state adp_state_t; 1866e8394b8SKazutaka YOKOTA 1876e8394b8SKazutaka YOKOTA /* video adapter information */ 1886e8394b8SKazutaka YOKOTA #define DCC_MONO 0 1896e8394b8SKazutaka YOKOTA #define DCC_CGA40 1 1906e8394b8SKazutaka YOKOTA #define DCC_CGA80 2 1916e8394b8SKazutaka YOKOTA #define DCC_EGAMONO 3 1926e8394b8SKazutaka YOKOTA #define DCC_EGA40 4 1936e8394b8SKazutaka YOKOTA #define DCC_EGA80 5 1946e8394b8SKazutaka YOKOTA 1956e8394b8SKazutaka YOKOTA /* 1966e8394b8SKazutaka YOKOTA * NOTE: `va_window' should have a virtual address, but is initialized 1976e8394b8SKazutaka YOKOTA * with a physical address in the following table, as verify_adapter() 1986e8394b8SKazutaka YOKOTA * will perform address conversion at run-time. 1996e8394b8SKazutaka YOKOTA */ 2006e8394b8SKazutaka YOKOTA static video_adapter_t adapter_init_value[] = { 2016e8394b8SKazutaka YOKOTA /* DCC_MONO */ 2026e8394b8SKazutaka YOKOTA { 0, KD_MONO, "mda", 0, 0, 0, IO_MDA, IO_MDASIZE, MONO_CRTC, 2036e8394b8SKazutaka YOKOTA MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE, 2046e8394b8SKazutaka YOKOTA 0, 0, 0, 0, 7, 0, }, 2056e8394b8SKazutaka YOKOTA /* DCC_CGA40 */ 2066e8394b8SKazutaka YOKOTA { 0, KD_CGA, "cga", 0, 0, V_ADP_COLOR, IO_CGA, IO_CGASIZE, COLOR_CRTC, 2076e8394b8SKazutaka YOKOTA CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 2086e8394b8SKazutaka YOKOTA 0, 0, 0, 0, 3, 0, }, 2096e8394b8SKazutaka YOKOTA /* DCC_CGA80 */ 2106e8394b8SKazutaka YOKOTA { 0, KD_CGA, "cga", 0, 0, V_ADP_COLOR, IO_CGA, IO_CGASIZE, COLOR_CRTC, 2116e8394b8SKazutaka YOKOTA CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 2126e8394b8SKazutaka YOKOTA 0, 0, 0, 0, 3, 0, }, 2136e8394b8SKazutaka YOKOTA /* DCC_EGAMONO */ 2146e8394b8SKazutaka YOKOTA { 0, KD_EGA, "ega", 0, 0, 0, IO_MDA, 48, MONO_CRTC, 2156e8394b8SKazutaka YOKOTA EGA_BUF_BASE, EGA_BUF_SIZE, MDA_BUF_BASE, MDA_BUF_SIZE, MDA_BUF_SIZE, 2166e8394b8SKazutaka YOKOTA 0, 0, 0, 0, 7, 0, }, 2176e8394b8SKazutaka YOKOTA /* DCC_EGA40 */ 2186e8394b8SKazutaka YOKOTA { 0, KD_EGA, "ega", 0, 0, V_ADP_COLOR, IO_MDA, 48, COLOR_CRTC, 2196e8394b8SKazutaka YOKOTA EGA_BUF_BASE, EGA_BUF_SIZE, CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 2206e8394b8SKazutaka YOKOTA 0, 0, 0, 0, 3, 0, }, 2216e8394b8SKazutaka YOKOTA /* DCC_EGA80 */ 2226e8394b8SKazutaka YOKOTA { 0, KD_EGA, "ega", 0, 0, V_ADP_COLOR, IO_MDA, 48, COLOR_CRTC, 2236e8394b8SKazutaka YOKOTA EGA_BUF_BASE, EGA_BUF_SIZE, CGA_BUF_BASE, CGA_BUF_SIZE, CGA_BUF_SIZE, 2246e8394b8SKazutaka YOKOTA 0, 0, 0, 0, 3, 0, }, 2256e8394b8SKazutaka YOKOTA }; 2266e8394b8SKazutaka YOKOTA 2276e8394b8SKazutaka YOKOTA static video_adapter_t biosadapter[2]; 2286e8394b8SKazutaka YOKOTA static int biosadapters = 0; 2296e8394b8SKazutaka YOKOTA 2306e8394b8SKazutaka YOKOTA /* video driver declarations */ 2316e8394b8SKazutaka YOKOTA static int vga_configure(int flags); 2326e8394b8SKazutaka YOKOTA int (*vga_sub_configure)(int flags); 2336e8394b8SKazutaka YOKOTA static int vga_nop(void); 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 }, 4136e8394b8SKazutaka YOKOTA { M_VGA_MODEX, V_INFO_COLOR | V_INFO_GRAPHICS, 320, 240, 8, 8, 8, 1, 4146e8394b8SKazutaka YOKOTA GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0, 4156e8394b8SKazutaka YOKOTA V_INFO_MM_PACKED, 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 */ }, 7496e8394b8SKazutaka YOKOTA { DCC_MONO, DCC_EGA80 /* CGA emulation */ }, 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}, 7556e8394b8SKazutaka YOKOTA { DCC_EGA80 /* CGA emulation */,DCC_MONO }, 7566e8394b8SKazutaka YOKOTA { DCC_EGA80, DCC_MONO }, 7576e8394b8SKazutaka YOKOTA { DCC_EGAMONO, DCC_CGA40 }, 7586e8394b8SKazutaka YOKOTA { DCC_EGAMONO, DCC_CGA40 }, 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; 8516e8394b8SKazutaka YOKOTA if (info->vi_flags & V_INFO_GRAPHICS) { 8526e8394b8SKazutaka YOKOTA switch (info->vi_depth/info->vi_planes) { 8536e8394b8SKazutaka YOKOTA case 1: 8546e8394b8SKazutaka YOKOTA adp->va_line_width = info->vi_width/8; 8556e8394b8SKazutaka YOKOTA break; 8566e8394b8SKazutaka YOKOTA case 2: 8576e8394b8SKazutaka YOKOTA adp->va_line_width = info->vi_width/4; 8586e8394b8SKazutaka YOKOTA break; 8596e8394b8SKazutaka YOKOTA case 4: 8606e8394b8SKazutaka YOKOTA adp->va_line_width = info->vi_width/2; 8616e8394b8SKazutaka YOKOTA break; 8626e8394b8SKazutaka YOKOTA case 8: 8636e8394b8SKazutaka YOKOTA default: /* shouldn't happen */ 8646e8394b8SKazutaka YOKOTA adp->va_line_width = info->vi_width; 8656e8394b8SKazutaka YOKOTA break; 8666e8394b8SKazutaka YOKOTA } 8676e8394b8SKazutaka YOKOTA } else { 8686e8394b8SKazutaka YOKOTA adp->va_line_width = info->vi_width; 8696e8394b8SKazutaka YOKOTA } 8706e8394b8SKazutaka YOKOTA adp->va_disp_start.x = 0; 8716e8394b8SKazutaka YOKOTA adp->va_disp_start.y = 0; 8726e8394b8SKazutaka YOKOTA bcopy(info, &adp->va_info, sizeof(adp->va_info)); 8736e8394b8SKazutaka YOKOTA } 8746e8394b8SKazutaka YOKOTA 8756e8394b8SKazutaka YOKOTA #if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE) 8766e8394b8SKazutaka YOKOTA /* compare two parameter table entries */ 8776e8394b8SKazutaka YOKOTA static int 8786e8394b8SKazutaka YOKOTA comp_adpregs(u_char *buf1, u_char *buf2) 8796e8394b8SKazutaka YOKOTA { 8806e8394b8SKazutaka YOKOTA static struct { 8816e8394b8SKazutaka YOKOTA u_char mask; 8826e8394b8SKazutaka YOKOTA } params[V_MODE_PARAM_SIZE] = { 8836e8394b8SKazutaka YOKOTA {0xff}, {0x00}, {0xff}, /* COLS}, ROWS}, POINTS */ 8846e8394b8SKazutaka YOKOTA {0x00}, {0x00}, /* page length */ 8856e8394b8SKazutaka YOKOTA {0xfe}, {0xff}, {0xff}, {0xff}, /* sequencer registers */ 8866e8394b8SKazutaka YOKOTA {0xf3}, /* misc register */ 8876e8394b8SKazutaka YOKOTA {0xff}, {0xff}, {0xff}, {0x7f}, {0xff}, /* CRTC */ 8886e8394b8SKazutaka YOKOTA {0xff}, {0xff}, {0xff}, {0x7f}, {0xff}, 8896e8394b8SKazutaka YOKOTA {0x00}, {0x00}, {0x00}, {0x00}, {0x00}, 8906e8394b8SKazutaka YOKOTA {0x00}, {0xff}, {0x7f}, {0xff}, {0xff}, 8916e8394b8SKazutaka YOKOTA {0x7f}, {0xff}, {0xff}, {0xef}, {0xff}, 8926e8394b8SKazutaka YOKOTA {0xff}, {0xff}, {0xff}, {0xff}, {0xff}, /* attribute controller regs */ 8936e8394b8SKazutaka YOKOTA {0xff}, {0xff}, {0xff}, {0xff}, {0xff}, 8946e8394b8SKazutaka YOKOTA {0xff}, {0xff}, {0xff}, {0xff}, {0xff}, 8956e8394b8SKazutaka YOKOTA {0xff}, {0xff}, {0xff}, {0xff}, {0xf0}, 8966e8394b8SKazutaka YOKOTA {0xff}, {0xff}, {0xff}, {0xff}, {0xff}, /* GDC register */ 8976e8394b8SKazutaka YOKOTA {0xff}, {0xff}, {0xff}, {0xff}, 8986e8394b8SKazutaka YOKOTA }; 8996e8394b8SKazutaka YOKOTA int identical = TRUE; 9006e8394b8SKazutaka YOKOTA int i; 9016e8394b8SKazutaka YOKOTA 9026e8394b8SKazutaka YOKOTA if ((buf1 == NULL) || (buf2 == NULL)) 9036e8394b8SKazutaka YOKOTA return COMP_DIFFERENT; 9046e8394b8SKazutaka YOKOTA 9056e8394b8SKazutaka YOKOTA for (i = 0; i < sizeof(params)/sizeof(params[0]); ++i) { 9066e8394b8SKazutaka YOKOTA if (params[i].mask == 0) /* don't care */ 9076e8394b8SKazutaka YOKOTA continue; 9086e8394b8SKazutaka YOKOTA if ((buf1[i] & params[i].mask) != (buf2[i] & params[i].mask)) 9096e8394b8SKazutaka YOKOTA return COMP_DIFFERENT; 9106e8394b8SKazutaka YOKOTA if (buf1[i] != buf2[i]) 9116e8394b8SKazutaka YOKOTA identical = FALSE; 9126e8394b8SKazutaka YOKOTA } 9136e8394b8SKazutaka YOKOTA return (identical) ? COMP_IDENTICAL : COMP_SIMILAR; 9146e8394b8SKazutaka YOKOTA } 9156e8394b8SKazutaka YOKOTA #endif /* !VGA_NO_BIOS && !VGA_NO_MODE_CHANGE */ 9166e8394b8SKazutaka YOKOTA 9176e8394b8SKazutaka YOKOTA /* probe video adapters and return the number of detected adapters */ 9186e8394b8SKazutaka YOKOTA static int 9196e8394b8SKazutaka YOKOTA probe_adapters(void) 9206e8394b8SKazutaka YOKOTA { 9216e8394b8SKazutaka YOKOTA video_adapter_t *adp; 9226e8394b8SKazutaka YOKOTA video_info_t info; 9236e8394b8SKazutaka YOKOTA #if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE) 9246e8394b8SKazutaka YOKOTA u_char *mp; 9256e8394b8SKazutaka YOKOTA #endif 9266e8394b8SKazutaka YOKOTA int i; 9276e8394b8SKazutaka YOKOTA 9286e8394b8SKazutaka YOKOTA /* do this test only once */ 9296e8394b8SKazutaka YOKOTA if (vga_init_done) 9306e8394b8SKazutaka YOKOTA return biosadapters; 9316e8394b8SKazutaka YOKOTA vga_init_done = TRUE; 9326e8394b8SKazutaka YOKOTA 9336e8394b8SKazutaka YOKOTA /* 9346e8394b8SKazutaka YOKOTA * Locate display adapters. 9356e8394b8SKazutaka YOKOTA * The AT architecture supports upto two adapters. `syscons' allows 9366e8394b8SKazutaka YOKOTA * the following combinations of adapters: 9376e8394b8SKazutaka YOKOTA * 1) MDA + CGA 9386e8394b8SKazutaka YOKOTA * 2) MDA + EGA/VGA color 9396e8394b8SKazutaka YOKOTA * 3) CGA + EGA/VGA mono 9406e8394b8SKazutaka YOKOTA * Note that `syscons' doesn't bother with MCGA as it is only 9416e8394b8SKazutaka YOKOTA * avaiable for low end PS/2 models which has 80286 or earlier CPUs, 9426e8394b8SKazutaka YOKOTA * thus, they are not running FreeBSD! 9436e8394b8SKazutaka YOKOTA * When there are two adapaters in the system, one becomes `primary' 9446e8394b8SKazutaka YOKOTA * and the other `secondary'. The EGA adapter has a set of DIP 9456e8394b8SKazutaka YOKOTA * switches on board for this information and the EGA BIOS copies 9466e8394b8SKazutaka YOKOTA * it in the BIOS data area BIOSDATA_VIDEOSWITCH (40:88). 9476e8394b8SKazutaka YOKOTA * The VGA BIOS has more sophisticated mechanism and has this 9486e8394b8SKazutaka YOKOTA * information in BIOSDATA_DCCINDEX (40:8a), but it also maintains 9496e8394b8SKazutaka YOKOTA * compatibility with the EGA BIOS by updating BIOSDATA_VIDEOSWITCH. 9506e8394b8SKazutaka YOKOTA */ 9516e8394b8SKazutaka YOKOTA 9526e8394b8SKazutaka YOKOTA /* 9536e8394b8SKazutaka YOKOTA * Check rtc and BIOS data area. 9546e8394b8SKazutaka YOKOTA * XXX: we don't use BIOSDATA_EQUIPMENT, since it is not a dead 9556e8394b8SKazutaka YOKOTA * copy of RTC_EQUIPMENT. Bits 4 and 5 of ETC_EQUIPMENT are 9566e8394b8SKazutaka YOKOTA * zeros for EGA and VGA. However, the EGA/VGA BIOS sets 9576e8394b8SKazutaka YOKOTA * these bits in BIOSDATA_EQUIPMENT according to the monitor 9586e8394b8SKazutaka YOKOTA * type detected. 9596e8394b8SKazutaka YOKOTA */ 9606e8394b8SKazutaka YOKOTA #ifndef VGA_NO_BIOS 9616e8394b8SKazutaka YOKOTA switch ((rtcin(RTC_EQUIPMENT) >> 4) & 3) { /* bit 4 and 5 */ 9626e8394b8SKazutaka YOKOTA case 0: 9636e8394b8SKazutaka YOKOTA /* EGA/VGA */ 9646e8394b8SKazutaka YOKOTA fill_adapter_param(readb(BIOS_PADDRTOVADDR(0x488)) & 0x0f, 9656e8394b8SKazutaka YOKOTA biosadapter); 9666e8394b8SKazutaka YOKOTA break; 9676e8394b8SKazutaka YOKOTA case 1: 9686e8394b8SKazutaka YOKOTA /* CGA 40x25 */ 9696e8394b8SKazutaka YOKOTA /* FIXME: switch to the 80x25 mode? XXX */ 9706e8394b8SKazutaka YOKOTA biosadapter[V_ADP_PRIMARY] = adapter_init_value[DCC_CGA40]; 9716e8394b8SKazutaka YOKOTA biosadapter[V_ADP_SECONDARY] = adapter_init_value[DCC_MONO]; 9726e8394b8SKazutaka YOKOTA break; 9736e8394b8SKazutaka YOKOTA case 2: 9746e8394b8SKazutaka YOKOTA /* CGA 80x25 */ 9756e8394b8SKazutaka YOKOTA biosadapter[V_ADP_PRIMARY] = adapter_init_value[DCC_CGA80]; 9766e8394b8SKazutaka YOKOTA biosadapter[V_ADP_SECONDARY] = adapter_init_value[DCC_MONO]; 9776e8394b8SKazutaka YOKOTA break; 9786e8394b8SKazutaka YOKOTA case 3: 9796e8394b8SKazutaka YOKOTA /* MDA */ 9806e8394b8SKazutaka YOKOTA biosadapter[V_ADP_PRIMARY] = adapter_init_value[DCC_MONO]; 9816e8394b8SKazutaka YOKOTA biosadapter[V_ADP_SECONDARY] = adapter_init_value[DCC_CGA80]; 9826e8394b8SKazutaka YOKOTA break; 9836e8394b8SKazutaka YOKOTA } 9846e8394b8SKazutaka YOKOTA #else 9856e8394b8SKazutaka YOKOTA /* assume EGA/VGA? XXX */ 9866e8394b8SKazutaka YOKOTA biosadapter[V_ADP_PRIMARY] = adapter_init_value[DCC_EGA80]; 9876e8394b8SKazutaka YOKOTA biosadapter[V_ADP_SECONDARY] = adapter_init_value[DCC_MONO]; 9886e8394b8SKazutaka YOKOTA #endif /* VGA_NO_BIOS */ 9896e8394b8SKazutaka YOKOTA 9906e8394b8SKazutaka YOKOTA biosadapters = 0; 9916e8394b8SKazutaka YOKOTA if (verify_adapter(&biosadapter[V_ADP_SECONDARY]) == 0) { 9926e8394b8SKazutaka YOKOTA ++biosadapters; 9936e8394b8SKazutaka YOKOTA biosadapter[V_ADP_SECONDARY].va_flags |= V_ADP_PROBED; 9946e8394b8SKazutaka YOKOTA biosadapter[V_ADP_SECONDARY].va_mode = 9956e8394b8SKazutaka YOKOTA biosadapter[V_ADP_SECONDARY].va_initial_mode = 9966e8394b8SKazutaka YOKOTA map_bios_mode_num(biosadapter[V_ADP_SECONDARY].va_type, 9976e8394b8SKazutaka YOKOTA biosadapter[V_ADP_SECONDARY].va_flags 9986e8394b8SKazutaka YOKOTA & V_ADP_COLOR, 9996e8394b8SKazutaka YOKOTA biosadapter[V_ADP_SECONDARY].va_initial_bios_mode); 10006e8394b8SKazutaka YOKOTA } else { 10016e8394b8SKazutaka YOKOTA biosadapter[V_ADP_SECONDARY].va_type = -1; 10026e8394b8SKazutaka YOKOTA } 10036e8394b8SKazutaka YOKOTA if (verify_adapter(&biosadapter[V_ADP_PRIMARY]) == 0) { 10046e8394b8SKazutaka YOKOTA ++biosadapters; 10056e8394b8SKazutaka YOKOTA biosadapter[V_ADP_PRIMARY].va_flags |= V_ADP_PROBED; 10066e8394b8SKazutaka YOKOTA #ifndef VGA_NO_BIOS 10076e8394b8SKazutaka YOKOTA biosadapter[V_ADP_PRIMARY].va_initial_bios_mode = 10086e8394b8SKazutaka YOKOTA readb(BIOS_PADDRTOVADDR(0x449)); 10096e8394b8SKazutaka YOKOTA #else 10106e8394b8SKazutaka YOKOTA biosadapter[V_ADP_PRIMARY].va_initial_bios_mode = 3; /* XXX */ 10116e8394b8SKazutaka YOKOTA #endif 10126e8394b8SKazutaka YOKOTA biosadapter[V_ADP_PRIMARY].va_mode = 10136e8394b8SKazutaka YOKOTA biosadapter[V_ADP_PRIMARY].va_initial_mode = 10146e8394b8SKazutaka YOKOTA map_bios_mode_num(biosadapter[V_ADP_PRIMARY].va_type, 10156e8394b8SKazutaka YOKOTA biosadapter[V_ADP_PRIMARY].va_flags & V_ADP_COLOR, 10166e8394b8SKazutaka YOKOTA biosadapter[V_ADP_PRIMARY].va_initial_bios_mode); 10176e8394b8SKazutaka YOKOTA } else { 10186e8394b8SKazutaka YOKOTA biosadapter[V_ADP_PRIMARY] = biosadapter[V_ADP_SECONDARY]; 10196e8394b8SKazutaka YOKOTA biosadapter[V_ADP_SECONDARY].va_type = -1; 10206e8394b8SKazutaka YOKOTA } 10216e8394b8SKazutaka YOKOTA if (biosadapters == 0) 10226e8394b8SKazutaka YOKOTA return biosadapters; 10236e8394b8SKazutaka YOKOTA biosadapter[V_ADP_PRIMARY].va_unit = V_ADP_PRIMARY; 10246e8394b8SKazutaka YOKOTA biosadapter[V_ADP_SECONDARY].va_unit = V_ADP_SECONDARY; 10256e8394b8SKazutaka YOKOTA 10266e8394b8SKazutaka YOKOTA #if 0 /* we don't need these... */ 10276e8394b8SKazutaka YOKOTA fb_init_struct(&biosadapter[V_ADP_PRIMARY], ...); 10286e8394b8SKazutaka YOKOTA fb_init_struct(&biosadapter[V_ADP_SECONDARY], ...); 10296e8394b8SKazutaka YOKOTA #endif 10306e8394b8SKazutaka YOKOTA 10316e8394b8SKazutaka YOKOTA #if notyet 10326e8394b8SKazutaka YOKOTA /* 10336e8394b8SKazutaka YOKOTA * We cannot have two video adapter of the same type; there must be 10346e8394b8SKazutaka YOKOTA * only one of color or mono adapter, or one each of them. 10356e8394b8SKazutaka YOKOTA */ 10366e8394b8SKazutaka YOKOTA if (biosadapters > 1) { 10376e8394b8SKazutaka YOKOTA if (!((biosadapter[0].va_flags ^ biosadapter[1].va_flags) 10386e8394b8SKazutaka YOKOTA & V_ADP_COLOR)) 10396e8394b8SKazutaka YOKOTA /* we have two mono or color adapters!! */ 10406e8394b8SKazutaka YOKOTA return (biosadapters = 0); 10416e8394b8SKazutaka YOKOTA } 10426e8394b8SKazutaka YOKOTA #endif 10436e8394b8SKazutaka YOKOTA 10446e8394b8SKazutaka YOKOTA /* 10456e8394b8SKazutaka YOKOTA * Ensure a zero start address. This is mainly to recover after 10466e8394b8SKazutaka YOKOTA * switching from pcvt using userconfig(). The registers are w/o 10476e8394b8SKazutaka YOKOTA * for old hardware so it's too hard to relocate the active screen 10486e8394b8SKazutaka YOKOTA * memory. 10496e8394b8SKazutaka YOKOTA * This must be done before vga_save_state() for VGA. 10506e8394b8SKazutaka YOKOTA */ 10516e8394b8SKazutaka YOKOTA outb(biosadapter[V_ADP_PRIMARY].va_crtc_addr, 12); 10526e8394b8SKazutaka YOKOTA outb(biosadapter[V_ADP_PRIMARY].va_crtc_addr + 1, 0); 10536e8394b8SKazutaka YOKOTA outb(biosadapter[V_ADP_PRIMARY].va_crtc_addr, 13); 10546e8394b8SKazutaka YOKOTA outb(biosadapter[V_ADP_PRIMARY].va_crtc_addr + 1, 0); 10556e8394b8SKazutaka YOKOTA 10566e8394b8SKazutaka YOKOTA /* the video mode parameter table in EGA/VGA BIOS */ 10576e8394b8SKazutaka YOKOTA /* NOTE: there can be only one EGA/VGA, wheather color or mono, 10586e8394b8SKazutaka YOKOTA * recognized by the video BIOS. 10596e8394b8SKazutaka YOKOTA */ 10606e8394b8SKazutaka YOKOTA if ((biosadapter[V_ADP_PRIMARY].va_type == KD_EGA) || 10616e8394b8SKazutaka YOKOTA (biosadapter[V_ADP_PRIMARY].va_type == KD_VGA)) { 10626e8394b8SKazutaka YOKOTA adp = &biosadapter[V_ADP_PRIMARY]; 10636e8394b8SKazutaka YOKOTA } else if ((biosadapter[V_ADP_SECONDARY].va_type == KD_EGA) || 10646e8394b8SKazutaka YOKOTA (biosadapter[V_ADP_SECONDARY].va_type == KD_VGA)) { 10656e8394b8SKazutaka YOKOTA adp = &biosadapter[V_ADP_SECONDARY]; 10666e8394b8SKazutaka YOKOTA } else { 10676e8394b8SKazutaka YOKOTA adp = NULL; 10686e8394b8SKazutaka YOKOTA } 10696e8394b8SKazutaka YOKOTA bzero(mode_map, sizeof(mode_map)); 10706e8394b8SKazutaka YOKOTA if (adp != NULL) { 10716e8394b8SKazutaka YOKOTA if (adp->va_type == KD_VGA) { 10726e8394b8SKazutaka YOKOTA vga_save_state(adp, &adpstate, sizeof(adpstate)); 10736e8394b8SKazutaka YOKOTA #if defined(VGA_NO_BIOS) || defined(VGA_NO_MODE_CHANGE) 10746e8394b8SKazutaka YOKOTA mode_map[adp->va_initial_mode] = adpstate.regs; 10756e8394b8SKazutaka YOKOTA rows_offset = 1; 10766e8394b8SKazutaka YOKOTA #else /* VGA_NO_BIOS || VGA_NO_MODE_CHANGE */ 10776e8394b8SKazutaka YOKOTA if (video_mode_ptr == NULL) { 10786e8394b8SKazutaka YOKOTA mode_map[adp->va_initial_mode] = adpstate.regs; 10796e8394b8SKazutaka YOKOTA rows_offset = 1; 10806e8394b8SKazutaka YOKOTA } else { 10816e8394b8SKazutaka YOKOTA /* discard the table if we are not familiar with it... */ 10826e8394b8SKazutaka YOKOTA map_mode_table(mode_map, video_mode_ptr, M_VGA_CG320 + 1); 10836e8394b8SKazutaka YOKOTA mp = get_mode_param(adp->va_initial_mode); 10846e8394b8SKazutaka YOKOTA if (mp != NULL) 10856e8394b8SKazutaka YOKOTA bcopy(mp, adpstate2.regs, sizeof(adpstate2.regs)); 10866e8394b8SKazutaka YOKOTA switch (comp_adpregs(adpstate.regs, mp)) { 10876e8394b8SKazutaka YOKOTA case COMP_IDENTICAL: 10886e8394b8SKazutaka YOKOTA /* 10896e8394b8SKazutaka YOKOTA * OK, this parameter table looks reasonably familiar 10906e8394b8SKazutaka YOKOTA * to us... 10916e8394b8SKazutaka YOKOTA */ 10926e8394b8SKazutaka YOKOTA /* 10936e8394b8SKazutaka YOKOTA * This is a kludge for Toshiba DynaBook SS433 10946e8394b8SKazutaka YOKOTA * whose BIOS video mode table entry has the actual # 10956e8394b8SKazutaka YOKOTA * of rows at the offset 1; BIOSes from other 10966e8394b8SKazutaka YOKOTA * manufacturers store the # of rows - 1 there. XXX 10976e8394b8SKazutaka YOKOTA */ 10986e8394b8SKazutaka YOKOTA rows_offset = adpstate.regs[1] + 1 - mp[1]; 10996e8394b8SKazutaka YOKOTA break; 11006e8394b8SKazutaka YOKOTA 11016e8394b8SKazutaka YOKOTA case COMP_SIMILAR: 11026e8394b8SKazutaka YOKOTA /* 11036e8394b8SKazutaka YOKOTA * Not exactly the same, but similar enough to be 11046e8394b8SKazutaka YOKOTA * trusted. However, use the saved register values 11056e8394b8SKazutaka YOKOTA * for the initial mode and other modes which are 11066e8394b8SKazutaka YOKOTA * based on the initial mode. 11076e8394b8SKazutaka YOKOTA */ 11086e8394b8SKazutaka YOKOTA mode_map[adp->va_initial_mode] = adpstate.regs; 11096e8394b8SKazutaka YOKOTA rows_offset = adpstate.regs[1] + 1 - mp[1]; 11106e8394b8SKazutaka YOKOTA adpstate.regs[1] -= rows_offset - 1; 11116e8394b8SKazutaka YOKOTA break; 11126e8394b8SKazutaka YOKOTA 11136e8394b8SKazutaka YOKOTA case COMP_DIFFERENT: 11146e8394b8SKazutaka YOKOTA default: 11156e8394b8SKazutaka YOKOTA /* 11166e8394b8SKazutaka YOKOTA * Don't use the paramter table in BIOS. It doesn't 11176e8394b8SKazutaka YOKOTA * look familiar to us. Video mode switching is allowed 11186e8394b8SKazutaka YOKOTA * only if the new mode is the same as or based on 11196e8394b8SKazutaka YOKOTA * the initial mode. 11206e8394b8SKazutaka YOKOTA */ 11216e8394b8SKazutaka YOKOTA video_mode_ptr = NULL; 11226e8394b8SKazutaka YOKOTA bzero(mode_map, sizeof(mode_map)); 11236e8394b8SKazutaka YOKOTA mode_map[adp->va_initial_mode] = adpstate.regs; 11246e8394b8SKazutaka YOKOTA rows_offset = 1; 11256e8394b8SKazutaka YOKOTA break; 11266e8394b8SKazutaka YOKOTA } 11276e8394b8SKazutaka YOKOTA } 11286e8394b8SKazutaka YOKOTA #endif /* VGA_NO_BIOS || VGA_NO_MODE_CHANGE */ 11296e8394b8SKazutaka YOKOTA 11306e8394b8SKazutaka YOKOTA #ifndef VGA_NO_MODE_CHANGE 11316e8394b8SKazutaka YOKOTA adp->va_flags |= V_ADP_MODECHANGE; 11326e8394b8SKazutaka YOKOTA #endif 11336e8394b8SKazutaka YOKOTA #ifndef VGA_NO_FONT_LOADING 11346e8394b8SKazutaka YOKOTA adp->va_flags |= V_ADP_FONT; 11356e8394b8SKazutaka YOKOTA #endif 11366e8394b8SKazutaka YOKOTA } else if (adp->va_type == KD_EGA) { 11376e8394b8SKazutaka YOKOTA #if defined(VGA_NO_BIOS) || defined(VGA_NO_MODE_CHANGE) 11386e8394b8SKazutaka YOKOTA rows_offset = 1; 11396e8394b8SKazutaka YOKOTA #else /* VGA_NO_BIOS || VGA_NO_MODE_CHANGE */ 11406e8394b8SKazutaka YOKOTA if (video_mode_ptr == NULL) { 11416e8394b8SKazutaka YOKOTA rows_offset = 1; 11426e8394b8SKazutaka YOKOTA } else { 11436e8394b8SKazutaka YOKOTA map_mode_table(mode_map, video_mode_ptr, M_ENH_C80x25 + 1); 11446e8394b8SKazutaka YOKOTA /* XXX how can one validate the EGA table... */ 11456e8394b8SKazutaka YOKOTA mp = get_mode_param(adp->va_initial_mode); 11466e8394b8SKazutaka YOKOTA if (mp != NULL) { 11476e8394b8SKazutaka YOKOTA adp->va_flags |= V_ADP_MODECHANGE; 11486e8394b8SKazutaka YOKOTA #ifndef VGA_NO_FONT_LOADING 11496e8394b8SKazutaka YOKOTA adp->va_flags |= V_ADP_FONT; 11506e8394b8SKazutaka YOKOTA #endif 11516e8394b8SKazutaka YOKOTA rows_offset = 1; 11526e8394b8SKazutaka YOKOTA } else { 11536e8394b8SKazutaka YOKOTA /* 11546e8394b8SKazutaka YOKOTA * This is serious. We will not be able to switch video 11556e8394b8SKazutaka YOKOTA * modes at all... 11566e8394b8SKazutaka YOKOTA */ 11576e8394b8SKazutaka YOKOTA video_mode_ptr = NULL; 11586e8394b8SKazutaka YOKOTA bzero(mode_map, sizeof(mode_map)); 11596e8394b8SKazutaka YOKOTA rows_offset = 1; 11606e8394b8SKazutaka YOKOTA } 11616e8394b8SKazutaka YOKOTA } 11626e8394b8SKazutaka YOKOTA #endif /* VGA_NO_BIOS || VGA_NO_MODE_CHANGE */ 11636e8394b8SKazutaka YOKOTA } 11646e8394b8SKazutaka YOKOTA } 11656e8394b8SKazutaka YOKOTA 11666e8394b8SKazutaka YOKOTA /* remove conflicting modes if we have more than one adapter */ 11676e8394b8SKazutaka YOKOTA if (biosadapters > 1) { 11686e8394b8SKazutaka YOKOTA for (i = 0; i < biosadapters; ++i) { 11696e8394b8SKazutaka YOKOTA if (!(biosadapter[i].va_flags & V_ADP_MODECHANGE)) 11706e8394b8SKazutaka YOKOTA continue; 11716e8394b8SKazutaka YOKOTA clear_mode_map(&biosadapter[i], mode_map, M_VGA_CG320 + 1, 11726e8394b8SKazutaka YOKOTA (biosadapter[i].va_flags & V_ADP_COLOR) ? 11736e8394b8SKazutaka YOKOTA V_INFO_COLOR : 0); 11746e8394b8SKazutaka YOKOTA if ((biosadapter[i].va_type == KD_VGA) 11756e8394b8SKazutaka YOKOTA || (biosadapter[i].va_type == KD_EGA)) { 11766e8394b8SKazutaka YOKOTA biosadapter[i].va_io_base = 11776e8394b8SKazutaka YOKOTA (biosadapter[i].va_flags & V_ADP_COLOR) ? 11786e8394b8SKazutaka YOKOTA IO_VGA : IO_MDA; 11796e8394b8SKazutaka YOKOTA biosadapter[i].va_io_size = 32; 11806e8394b8SKazutaka YOKOTA } 11816e8394b8SKazutaka YOKOTA } 11826e8394b8SKazutaka YOKOTA } 11836e8394b8SKazutaka YOKOTA 11846e8394b8SKazutaka YOKOTA /* buffer address */ 11856e8394b8SKazutaka YOKOTA vga_get_info(&biosadapter[V_ADP_PRIMARY], 11866e8394b8SKazutaka YOKOTA biosadapter[V_ADP_PRIMARY].va_initial_mode, &info); 11876e8394b8SKazutaka YOKOTA info.vi_flags &= ~V_INFO_LINEAR; /* XXX */ 11886e8394b8SKazutaka YOKOTA update_adapter_info(&biosadapter[V_ADP_PRIMARY], &info); 11896e8394b8SKazutaka YOKOTA 11906e8394b8SKazutaka YOKOTA if (biosadapters > 1) { 11916e8394b8SKazutaka YOKOTA vga_get_info(&biosadapter[V_ADP_SECONDARY], 11926e8394b8SKazutaka YOKOTA biosadapter[V_ADP_SECONDARY].va_initial_mode, &info); 11936e8394b8SKazutaka YOKOTA info.vi_flags &= ~V_INFO_LINEAR; /* XXX */ 11946e8394b8SKazutaka YOKOTA update_adapter_info(&biosadapter[V_ADP_SECONDARY], &info); 11956e8394b8SKazutaka YOKOTA } 11966e8394b8SKazutaka YOKOTA 11976e8394b8SKazutaka YOKOTA /* 11986e8394b8SKazutaka YOKOTA * XXX: we should verify the following values for the primary adapter... 11996e8394b8SKazutaka YOKOTA * crtc I/O port address: *(u_int16_t *)BIOS_PADDRTOVADDR(0x463); 12006e8394b8SKazutaka YOKOTA * color/mono display: (*(u_int8_t *)BIOS_PADDRTOVADDR(0x487) & 0x02) 12016e8394b8SKazutaka YOKOTA * ? 0 : V_ADP_COLOR; 12026e8394b8SKazutaka YOKOTA * columns: *(u_int8_t *)BIOS_PADDRTOVADDR(0x44a); 12036e8394b8SKazutaka YOKOTA * rows: *(u_int8_t *)BIOS_PADDRTOVADDR(0x484); 12046e8394b8SKazutaka YOKOTA * font size: *(u_int8_t *)BIOS_PADDRTOVADDR(0x485); 12056e8394b8SKazutaka YOKOTA * buffer size: *(u_int16_t *)BIOS_PADDRTOVADDR(0x44c); 12066e8394b8SKazutaka YOKOTA */ 12076e8394b8SKazutaka YOKOTA 12086e8394b8SKazutaka YOKOTA return biosadapters; 12096e8394b8SKazutaka YOKOTA } 12106e8394b8SKazutaka YOKOTA 12116e8394b8SKazutaka YOKOTA /* set the scan line length in pixel */ 12126e8394b8SKazutaka YOKOTA static int 12136e8394b8SKazutaka YOKOTA set_line_length(video_adapter_t *adp, int pixel) 12146e8394b8SKazutaka YOKOTA { 12156e8394b8SKazutaka YOKOTA u_char *mp; 12166e8394b8SKazutaka YOKOTA int ppw; /* pixels per word */ 12176e8394b8SKazutaka YOKOTA int bpl; /* bytes per line */ 12186e8394b8SKazutaka YOKOTA int count; 12196e8394b8SKazutaka YOKOTA 12206e8394b8SKazutaka YOKOTA if ((adp->va_type != KD_VGA) && (adp->va_type != KD_EGA)) 12216e8394b8SKazutaka YOKOTA return ENODEV; 12226e8394b8SKazutaka YOKOTA mp = get_mode_param(adp->va_mode); 12236e8394b8SKazutaka YOKOTA if (mp == NULL) 12246e8394b8SKazutaka YOKOTA return EINVAL; 12256e8394b8SKazutaka YOKOTA 12266e8394b8SKazutaka YOKOTA switch (adp->va_info.vi_mem_model) { 12276e8394b8SKazutaka YOKOTA case V_INFO_MM_PLANAR: 12286e8394b8SKazutaka YOKOTA ppw = 16/(adp->va_info.vi_depth/adp->va_info.vi_planes); 12296e8394b8SKazutaka YOKOTA count = (pixel + ppw - 1)/ppw/2; 12306e8394b8SKazutaka YOKOTA bpl = ((pixel + ppw - 1)/ppw/2)*4; 12316e8394b8SKazutaka YOKOTA break; 12326e8394b8SKazutaka YOKOTA case V_INFO_MM_PACKED: 12336e8394b8SKazutaka YOKOTA count = (pixel + 7)/8; 12346e8394b8SKazutaka YOKOTA bpl = ((pixel + 7)/8)*8; 12356e8394b8SKazutaka YOKOTA break; 12366e8394b8SKazutaka YOKOTA case V_INFO_MM_TEXT: 12376e8394b8SKazutaka YOKOTA count = (pixel + 7)/8; /* columns */ 12386e8394b8SKazutaka YOKOTA bpl = (pixel + 7)/8; /* columns */ 12396e8394b8SKazutaka YOKOTA break; 12406e8394b8SKazutaka YOKOTA default: 12416e8394b8SKazutaka YOKOTA return ENODEV; 12426e8394b8SKazutaka YOKOTA } 12436e8394b8SKazutaka YOKOTA 12446e8394b8SKazutaka YOKOTA if (mp[10 + 0x17] & 0x40) /* CRTC mode control reg */ 12456e8394b8SKazutaka YOKOTA count *= 2; /* byte mode */ 12466e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr, 0x13); 12476e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr + 1, count); 12486e8394b8SKazutaka YOKOTA adp->va_line_width = bpl; 12496e8394b8SKazutaka YOKOTA 12506e8394b8SKazutaka YOKOTA return 0; 12516e8394b8SKazutaka YOKOTA } 12526e8394b8SKazutaka YOKOTA 12536e8394b8SKazutaka YOKOTA static int 12546e8394b8SKazutaka YOKOTA set_display_start(video_adapter_t *adp, int x, int y) 12556e8394b8SKazutaka YOKOTA { 12566e8394b8SKazutaka YOKOTA int off; /* byte offset (graphics mode)/word offset (text mode) */ 12576e8394b8SKazutaka YOKOTA int poff; /* pixel offset */ 12586e8394b8SKazutaka YOKOTA int roff; /* row offset */ 12596e8394b8SKazutaka YOKOTA int ppb; /* pixels per byte */ 12606e8394b8SKazutaka YOKOTA 12616e8394b8SKazutaka YOKOTA if ((adp->va_type != KD_VGA) && (adp->va_type != KD_EGA)) 12626e8394b8SKazutaka YOKOTA x &= ~7; 12636e8394b8SKazutaka YOKOTA if (adp->va_info.vi_flags & V_INFO_GRAPHICS) { 12646e8394b8SKazutaka YOKOTA ppb = 8/(adp->va_info.vi_depth/adp->va_info.vi_planes); 12656e8394b8SKazutaka YOKOTA off = y*adp->va_line_width + x/ppb; 12666e8394b8SKazutaka YOKOTA roff = 0; 12676e8394b8SKazutaka YOKOTA poff = x%ppb; 12686e8394b8SKazutaka YOKOTA } else { 12696e8394b8SKazutaka YOKOTA if ((adp->va_type == KD_VGA) || (adp->va_type == KD_EGA)) { 12706e8394b8SKazutaka YOKOTA outb(TSIDX, 1); 12716e8394b8SKazutaka YOKOTA if (inb(TSREG) & 1) 12726e8394b8SKazutaka YOKOTA ppb = 9; 12736e8394b8SKazutaka YOKOTA else 12746e8394b8SKazutaka YOKOTA ppb = 8; 12756e8394b8SKazutaka YOKOTA } else { 12766e8394b8SKazutaka YOKOTA ppb = 8; 12776e8394b8SKazutaka YOKOTA } 12786e8394b8SKazutaka YOKOTA off = y/adp->va_info.vi_cheight*adp->va_line_width + x/ppb; 12796e8394b8SKazutaka YOKOTA roff = y%adp->va_info.vi_cheight; 12806e8394b8SKazutaka YOKOTA /* FIXME: is this correct? XXX */ 12816e8394b8SKazutaka YOKOTA if (ppb == 8) 12826e8394b8SKazutaka YOKOTA poff = x%ppb; 12836e8394b8SKazutaka YOKOTA else 12846e8394b8SKazutaka YOKOTA poff = (x + 8)%ppb; 12856e8394b8SKazutaka YOKOTA } 12866e8394b8SKazutaka YOKOTA 12876e8394b8SKazutaka YOKOTA /* start address */ 12886e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr, 0xc); /* high */ 12896e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr + 1, off >> 8); 12906e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr, 0xd); /* low */ 12916e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr + 1, off & 0xff); 12926e8394b8SKazutaka YOKOTA 12936e8394b8SKazutaka YOKOTA /* horizontal pel pan */ 12946e8394b8SKazutaka YOKOTA if ((adp->va_type == KD_VGA) || (adp->va_type == KD_EGA)) { 12956e8394b8SKazutaka YOKOTA inb(adp->va_crtc_addr + 6); 12966e8394b8SKazutaka YOKOTA outb(ATC, 0x13 | 0x20); 12976e8394b8SKazutaka YOKOTA outb(ATC, poff); 12986e8394b8SKazutaka YOKOTA inb(adp->va_crtc_addr + 6); 12996e8394b8SKazutaka YOKOTA outb(ATC, 0x20); 13006e8394b8SKazutaka YOKOTA } 13016e8394b8SKazutaka YOKOTA 13026e8394b8SKazutaka YOKOTA /* preset raw scan */ 13036e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr, 8); 13046e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr + 1, roff); 13056e8394b8SKazutaka YOKOTA 13066e8394b8SKazutaka YOKOTA adp->va_disp_start.x = x; 13076e8394b8SKazutaka YOKOTA adp->va_disp_start.y = y; 13086e8394b8SKazutaka YOKOTA return 0; 13096e8394b8SKazutaka YOKOTA } 13106e8394b8SKazutaka YOKOTA 13116e8394b8SKazutaka YOKOTA #ifdef __i386__ /* XXX */ 13126e8394b8SKazutaka YOKOTA static void 13136e8394b8SKazutaka YOKOTA fill(int val, void *d, size_t size) 13146e8394b8SKazutaka YOKOTA { 13156e8394b8SKazutaka YOKOTA u_char *p = d; 13166e8394b8SKazutaka YOKOTA 13176e8394b8SKazutaka YOKOTA while (size-- > 0) 13186e8394b8SKazutaka YOKOTA *p++ = val; 13196e8394b8SKazutaka YOKOTA } 13206e8394b8SKazutaka YOKOTA #endif /* __i386__ */ 13216e8394b8SKazutaka YOKOTA 13226e8394b8SKazutaka YOKOTA static void 13236e8394b8SKazutaka YOKOTA filll_io(int val, vm_offset_t d, size_t size) 13246e8394b8SKazutaka YOKOTA { 13256e8394b8SKazutaka YOKOTA while (size-- > 0) { 13266e8394b8SKazutaka YOKOTA writel(d, val); 13276e8394b8SKazutaka YOKOTA d += sizeof(u_int32_t); 13286e8394b8SKazutaka YOKOTA } 13296e8394b8SKazutaka YOKOTA } 13306e8394b8SKazutaka YOKOTA 13316e8394b8SKazutaka YOKOTA /* entry points */ 13326e8394b8SKazutaka YOKOTA 13336e8394b8SKazutaka YOKOTA static int 13346e8394b8SKazutaka YOKOTA vga_nop(void) 13356e8394b8SKazutaka YOKOTA { 13366e8394b8SKazutaka YOKOTA return 0; 13376e8394b8SKazutaka YOKOTA } 13386e8394b8SKazutaka YOKOTA 13396e8394b8SKazutaka YOKOTA static int 13406e8394b8SKazutaka YOKOTA vga_error(void) 13416e8394b8SKazutaka YOKOTA { 13426e8394b8SKazutaka YOKOTA return ENODEV; 13436e8394b8SKazutaka YOKOTA } 13446e8394b8SKazutaka YOKOTA 13456e8394b8SKazutaka YOKOTA static int 13466e8394b8SKazutaka YOKOTA vga_probe(int unit, video_adapter_t **adpp, void *arg, int flags) 13476e8394b8SKazutaka YOKOTA { 13486e8394b8SKazutaka YOKOTA probe_adapters(); 13496e8394b8SKazutaka YOKOTA if (unit >= biosadapters) 13506e8394b8SKazutaka YOKOTA return ENXIO; 13516e8394b8SKazutaka YOKOTA 13526e8394b8SKazutaka YOKOTA *adpp = &biosadapter[unit]; 13536e8394b8SKazutaka YOKOTA 13546e8394b8SKazutaka YOKOTA return 0; 13556e8394b8SKazutaka YOKOTA } 13566e8394b8SKazutaka YOKOTA 13576e8394b8SKazutaka YOKOTA static int 13586e8394b8SKazutaka YOKOTA vga_init(int unit, video_adapter_t *adp, int flags) 13596e8394b8SKazutaka YOKOTA { 13606e8394b8SKazutaka YOKOTA if ((unit >= biosadapters) || (adp == NULL) || !probe_done(adp)) 13616e8394b8SKazutaka YOKOTA return ENXIO; 13626e8394b8SKazutaka YOKOTA 13636e8394b8SKazutaka YOKOTA if (!init_done(adp)) { 13646e8394b8SKazutaka YOKOTA /* nothing to do really... */ 13656e8394b8SKazutaka YOKOTA adp->va_flags |= V_ADP_INITIALIZED; 13666e8394b8SKazutaka YOKOTA } 13676e8394b8SKazutaka YOKOTA 13686e8394b8SKazutaka YOKOTA if (!config_done(adp)) { 13696e8394b8SKazutaka YOKOTA if (vid_register(adp) < 0) 13706e8394b8SKazutaka YOKOTA return ENXIO; 13716e8394b8SKazutaka YOKOTA adp->va_flags |= V_ADP_REGISTERED; 13726e8394b8SKazutaka YOKOTA } 13736e8394b8SKazutaka YOKOTA if (vga_sub_configure != NULL) 13746e8394b8SKazutaka YOKOTA (*vga_sub_configure)(0); 13756e8394b8SKazutaka YOKOTA 13766e8394b8SKazutaka YOKOTA return 0; 13776e8394b8SKazutaka YOKOTA } 13786e8394b8SKazutaka YOKOTA 13796e8394b8SKazutaka YOKOTA /* 13806e8394b8SKazutaka YOKOTA * get_info(): 13816e8394b8SKazutaka YOKOTA * Return the video_info structure of the requested video mode. 13826e8394b8SKazutaka YOKOTA * 13836e8394b8SKazutaka YOKOTA * all adapters 13846e8394b8SKazutaka YOKOTA */ 13856e8394b8SKazutaka YOKOTA static int 13866e8394b8SKazutaka YOKOTA vga_get_info(video_adapter_t *adp, int mode, video_info_t *info) 13876e8394b8SKazutaka YOKOTA { 13886e8394b8SKazutaka YOKOTA int i; 13896e8394b8SKazutaka YOKOTA 13906e8394b8SKazutaka YOKOTA if (!vga_init_done) 13916e8394b8SKazutaka YOKOTA return ENXIO; 13926e8394b8SKazutaka YOKOTA 13936e8394b8SKazutaka YOKOTA mode = map_gen_mode_num(adp->va_type, adp->va_flags & V_ADP_COLOR, mode); 13946e8394b8SKazutaka YOKOTA #ifndef VGA_NO_MODE_CHANGE 13956e8394b8SKazutaka YOKOTA if (adp->va_flags & V_ADP_MODECHANGE) { 13966e8394b8SKazutaka YOKOTA /* 13976e8394b8SKazutaka YOKOTA * If the parameter table entry for this mode is not found, 13986e8394b8SKazutaka YOKOTA * the mode is not supported... 13996e8394b8SKazutaka YOKOTA */ 14006e8394b8SKazutaka YOKOTA if (get_mode_param(mode) == NULL) 14016e8394b8SKazutaka YOKOTA return EINVAL; 14026e8394b8SKazutaka YOKOTA } else 14036e8394b8SKazutaka YOKOTA #endif /* VGA_NO_MODE_CHANGE */ 14046e8394b8SKazutaka YOKOTA { 14056e8394b8SKazutaka YOKOTA /* 14066e8394b8SKazutaka YOKOTA * Even if we don't support video mode switching on this adapter, 14076e8394b8SKazutaka YOKOTA * the information on the initial (thus current) video mode 14086e8394b8SKazutaka YOKOTA * should be made available. 14096e8394b8SKazutaka YOKOTA */ 14106e8394b8SKazutaka YOKOTA if (mode != adp->va_initial_mode) 14116e8394b8SKazutaka YOKOTA return EINVAL; 14126e8394b8SKazutaka YOKOTA } 14136e8394b8SKazutaka YOKOTA 14146e8394b8SKazutaka YOKOTA for (i = 0; bios_vmode[i].vi_mode != EOT; ++i) { 14156e8394b8SKazutaka YOKOTA if (bios_vmode[i].vi_mode == NA) 14166e8394b8SKazutaka YOKOTA continue; 14176e8394b8SKazutaka YOKOTA if (mode == bios_vmode[i].vi_mode) { 14186e8394b8SKazutaka YOKOTA *info = bios_vmode[i]; 14196e8394b8SKazutaka YOKOTA /* XXX */ 14206e8394b8SKazutaka YOKOTA info->vi_buffer_size = info->vi_window_size*info->vi_planes; 14216e8394b8SKazutaka YOKOTA return 0; 14226e8394b8SKazutaka YOKOTA } 14236e8394b8SKazutaka YOKOTA } 14246e8394b8SKazutaka YOKOTA return EINVAL; 14256e8394b8SKazutaka YOKOTA } 14266e8394b8SKazutaka YOKOTA 14276e8394b8SKazutaka YOKOTA /* 14286e8394b8SKazutaka YOKOTA * query_mode(): 14296e8394b8SKazutaka YOKOTA * Find a video mode matching the requested parameters. 14306e8394b8SKazutaka YOKOTA * Fields filled with 0 are considered "don't care" fields and 14316e8394b8SKazutaka YOKOTA * match any modes. 14326e8394b8SKazutaka YOKOTA * 14336e8394b8SKazutaka YOKOTA * all adapters 14346e8394b8SKazutaka YOKOTA */ 14356e8394b8SKazutaka YOKOTA static int 14366e8394b8SKazutaka YOKOTA vga_query_mode(video_adapter_t *adp, video_info_t *info) 14376e8394b8SKazutaka YOKOTA { 14386e8394b8SKazutaka YOKOTA video_info_t buf; 14396e8394b8SKazutaka YOKOTA int i; 14406e8394b8SKazutaka YOKOTA 14416e8394b8SKazutaka YOKOTA if (!vga_init_done) 14426e8394b8SKazutaka YOKOTA return -1; 14436e8394b8SKazutaka YOKOTA 14446e8394b8SKazutaka YOKOTA for (i = 0; bios_vmode[i].vi_mode != EOT; ++i) { 14456e8394b8SKazutaka YOKOTA if (bios_vmode[i].vi_mode == NA) 14466e8394b8SKazutaka YOKOTA continue; 14476e8394b8SKazutaka YOKOTA 14486e8394b8SKazutaka YOKOTA if ((info->vi_width != 0) 14496e8394b8SKazutaka YOKOTA && (info->vi_width != bios_vmode[i].vi_width)) 14506e8394b8SKazutaka YOKOTA continue; 14516e8394b8SKazutaka YOKOTA if ((info->vi_height != 0) 14526e8394b8SKazutaka YOKOTA && (info->vi_height != bios_vmode[i].vi_height)) 14536e8394b8SKazutaka YOKOTA continue; 14546e8394b8SKazutaka YOKOTA if ((info->vi_cwidth != 0) 14556e8394b8SKazutaka YOKOTA && (info->vi_cwidth != bios_vmode[i].vi_cwidth)) 14566e8394b8SKazutaka YOKOTA continue; 14576e8394b8SKazutaka YOKOTA if ((info->vi_cheight != 0) 14586e8394b8SKazutaka YOKOTA && (info->vi_cheight != bios_vmode[i].vi_cheight)) 14596e8394b8SKazutaka YOKOTA continue; 14606e8394b8SKazutaka YOKOTA if ((info->vi_depth != 0) 14616e8394b8SKazutaka YOKOTA && (info->vi_depth != bios_vmode[i].vi_depth)) 14626e8394b8SKazutaka YOKOTA continue; 14636e8394b8SKazutaka YOKOTA if ((info->vi_planes != 0) 14646e8394b8SKazutaka YOKOTA && (info->vi_planes != bios_vmode[i].vi_planes)) 14656e8394b8SKazutaka YOKOTA continue; 14666e8394b8SKazutaka YOKOTA /* XXX: should check pixel format, memory model */ 14676e8394b8SKazutaka YOKOTA if ((info->vi_flags != 0) 14686e8394b8SKazutaka YOKOTA && (info->vi_flags != bios_vmode[i].vi_flags)) 14696e8394b8SKazutaka YOKOTA continue; 14706e8394b8SKazutaka YOKOTA 14716e8394b8SKazutaka YOKOTA /* verify if this mode is supported on this adapter */ 14726e8394b8SKazutaka YOKOTA if (vga_get_info(adp, bios_vmode[i].vi_mode, &buf)) 14736e8394b8SKazutaka YOKOTA continue; 14746e8394b8SKazutaka YOKOTA return bios_vmode[i].vi_mode; 14756e8394b8SKazutaka YOKOTA } 14766e8394b8SKazutaka YOKOTA return -1; 14776e8394b8SKazutaka YOKOTA } 14786e8394b8SKazutaka YOKOTA 14796e8394b8SKazutaka YOKOTA /* 14806e8394b8SKazutaka YOKOTA * set_mode(): 14816e8394b8SKazutaka YOKOTA * Change the video mode. 14826e8394b8SKazutaka YOKOTA * 14836e8394b8SKazutaka YOKOTA * EGA/VGA 14846e8394b8SKazutaka YOKOTA */ 14856e8394b8SKazutaka YOKOTA 14866e8394b8SKazutaka YOKOTA #ifndef VGA_NO_MODE_CHANGE 14876e8394b8SKazutaka YOKOTA #ifdef VGA_WIDTH90 14886e8394b8SKazutaka YOKOTA static void 14896e8394b8SKazutaka YOKOTA set_width90(adp_state_t *params) 14906e8394b8SKazutaka YOKOTA { 14916e8394b8SKazutaka YOKOTA /* 14926e8394b8SKazutaka YOKOTA * Based on code submitted by Kelly Yancey (kbyanc@freedomnet.com) 14936e8394b8SKazutaka YOKOTA * and alexv@sui.gda.itesm.mx. 14946e8394b8SKazutaka YOKOTA */ 14956e8394b8SKazutaka YOKOTA params->regs[5] |= 1; /* toggle 8 pixel wide fonts */ 14966e8394b8SKazutaka YOKOTA params->regs[10+0x0] = 0x6b; 14976e8394b8SKazutaka YOKOTA params->regs[10+0x1] = 0x59; 14986e8394b8SKazutaka YOKOTA params->regs[10+0x2] = 0x5a; 14996e8394b8SKazutaka YOKOTA params->regs[10+0x3] = 0x8e; 15006e8394b8SKazutaka YOKOTA params->regs[10+0x4] = 0x5e; 15016e8394b8SKazutaka YOKOTA params->regs[10+0x5] = 0x8a; 15026e8394b8SKazutaka YOKOTA params->regs[10+0x13] = 45; 15036e8394b8SKazutaka YOKOTA params->regs[35+0x13] = 0; 15046e8394b8SKazutaka YOKOTA } 15056e8394b8SKazutaka YOKOTA #endif /* VGA_WIDTH90 */ 15066e8394b8SKazutaka YOKOTA #endif /* !VGA_NO_MODE_CHANGE */ 15076e8394b8SKazutaka YOKOTA 15086e8394b8SKazutaka YOKOTA static int 15096e8394b8SKazutaka YOKOTA vga_set_mode(video_adapter_t *adp, int mode) 15106e8394b8SKazutaka YOKOTA { 15116e8394b8SKazutaka YOKOTA #ifndef VGA_NO_MODE_CHANGE 15126e8394b8SKazutaka YOKOTA video_info_t info; 15136e8394b8SKazutaka YOKOTA adp_state_t params; 15146e8394b8SKazutaka YOKOTA 15156e8394b8SKazutaka YOKOTA prologue(adp, V_ADP_MODECHANGE, ENODEV); 15166e8394b8SKazutaka YOKOTA 15176e8394b8SKazutaka YOKOTA mode = map_gen_mode_num(adp->va_type, 15186e8394b8SKazutaka YOKOTA adp->va_flags & V_ADP_COLOR, mode); 15196e8394b8SKazutaka YOKOTA if (vga_get_info(adp, mode, &info)) 15206e8394b8SKazutaka YOKOTA return EINVAL; 15216e8394b8SKazutaka YOKOTA 15226e8394b8SKazutaka YOKOTA #if VGA_DEBUG > 1 15236e8394b8SKazutaka YOKOTA printf("vga_set_mode(): setting mode %d\n", mode); 15246e8394b8SKazutaka YOKOTA #endif 15256e8394b8SKazutaka YOKOTA 15266e8394b8SKazutaka YOKOTA params.sig = V_STATE_SIG; 15276e8394b8SKazutaka YOKOTA bcopy(get_mode_param(mode), params.regs, sizeof(params.regs)); 15286e8394b8SKazutaka YOKOTA 15296e8394b8SKazutaka YOKOTA switch (mode) { 15306e8394b8SKazutaka YOKOTA #ifdef VGA_WIDTH90 15316e8394b8SKazutaka YOKOTA case M_VGA_C90x60: case M_VGA_M90x60: 15326e8394b8SKazutaka YOKOTA set_width90(¶ms); 15336e8394b8SKazutaka YOKOTA /* FALL THROUGH */ 15346e8394b8SKazutaka YOKOTA #endif 15356e8394b8SKazutaka YOKOTA case M_VGA_C80x60: case M_VGA_M80x60: 15366e8394b8SKazutaka YOKOTA params.regs[2] = 0x08; 15376e8394b8SKazutaka YOKOTA params.regs[19] = 0x47; 15386e8394b8SKazutaka YOKOTA goto special_480l; 15396e8394b8SKazutaka YOKOTA 15406e8394b8SKazutaka YOKOTA #ifdef VGA_WIDTH90 15416e8394b8SKazutaka YOKOTA case M_VGA_C90x30: case M_VGA_M90x30: 15426e8394b8SKazutaka YOKOTA set_width90(¶ms); 15436e8394b8SKazutaka YOKOTA /* FALL THROUGH */ 15446e8394b8SKazutaka YOKOTA #endif 15456e8394b8SKazutaka YOKOTA case M_VGA_C80x30: case M_VGA_M80x30: 15466e8394b8SKazutaka YOKOTA params.regs[19] = 0x4f; 15476e8394b8SKazutaka YOKOTA special_480l: 15486e8394b8SKazutaka YOKOTA params.regs[9] |= 0xc0; 15496e8394b8SKazutaka YOKOTA params.regs[16] = 0x08; 15506e8394b8SKazutaka YOKOTA params.regs[17] = 0x3e; 15516e8394b8SKazutaka YOKOTA params.regs[26] = 0xea; 15526e8394b8SKazutaka YOKOTA params.regs[28] = 0xdf; 15536e8394b8SKazutaka YOKOTA params.regs[31] = 0xe7; 15546e8394b8SKazutaka YOKOTA params.regs[32] = 0x04; 15556e8394b8SKazutaka YOKOTA goto setup_mode; 15566e8394b8SKazutaka YOKOTA 15576e8394b8SKazutaka YOKOTA #ifdef VGA_WIDTH90 15586e8394b8SKazutaka YOKOTA case M_VGA_C90x43: case M_VGA_M90x43: 15596e8394b8SKazutaka YOKOTA set_width90(¶ms); 15606e8394b8SKazutaka YOKOTA /* FALL THROUGH */ 15616e8394b8SKazutaka YOKOTA #endif 15626e8394b8SKazutaka YOKOTA case M_ENH_C80x43: case M_ENH_B80x43: 15636e8394b8SKazutaka YOKOTA params.regs[28] = 87; 15646e8394b8SKazutaka YOKOTA goto special_80x50; 15656e8394b8SKazutaka YOKOTA 15666e8394b8SKazutaka YOKOTA #ifdef VGA_WIDTH90 15676e8394b8SKazutaka YOKOTA case M_VGA_C90x50: case M_VGA_M90x50: 15686e8394b8SKazutaka YOKOTA set_width90(¶ms); 15696e8394b8SKazutaka YOKOTA /* FALL THROUGH */ 15706e8394b8SKazutaka YOKOTA #endif 15716e8394b8SKazutaka YOKOTA case M_VGA_C80x50: case M_VGA_M80x50: 15726e8394b8SKazutaka YOKOTA special_80x50: 15736e8394b8SKazutaka YOKOTA params.regs[2] = 8; 15746e8394b8SKazutaka YOKOTA params.regs[19] = 7; 15756e8394b8SKazutaka YOKOTA goto setup_mode; 15766e8394b8SKazutaka YOKOTA 15776e8394b8SKazutaka YOKOTA #ifdef VGA_WIDTH90 15786e8394b8SKazutaka YOKOTA case M_VGA_C90x25: case M_VGA_M90x25: 15796e8394b8SKazutaka YOKOTA set_width90(¶ms); 15806e8394b8SKazutaka YOKOTA /* FALL THROUGH */ 15816e8394b8SKazutaka YOKOTA #endif 15826e8394b8SKazutaka YOKOTA case M_VGA_C40x25: case M_VGA_C80x25: 15836e8394b8SKazutaka YOKOTA case M_VGA_M80x25: 15846e8394b8SKazutaka YOKOTA case M_B40x25: case M_C40x25: 15856e8394b8SKazutaka YOKOTA case M_B80x25: case M_C80x25: 15866e8394b8SKazutaka YOKOTA case M_ENH_B40x25: case M_ENH_C40x25: 15876e8394b8SKazutaka YOKOTA case M_ENH_B80x25: case M_ENH_C80x25: 15886e8394b8SKazutaka YOKOTA case M_EGAMONO80x25: 15896e8394b8SKazutaka YOKOTA 15906e8394b8SKazutaka YOKOTA setup_mode: 15916e8394b8SKazutaka YOKOTA vga_load_state(adp, ¶ms); 15926e8394b8SKazutaka YOKOTA break; 15936e8394b8SKazutaka YOKOTA 15946e8394b8SKazutaka YOKOTA case M_VGA_MODEX: 15956e8394b8SKazutaka YOKOTA /* "unchain" the VGA mode */ 15966e8394b8SKazutaka YOKOTA params.regs[5-1+0x04] &= 0xf7; 15976e8394b8SKazutaka YOKOTA params.regs[5-1+0x04] |= 0x04; 15986e8394b8SKazutaka YOKOTA /* turn off doubleword mode */ 15996e8394b8SKazutaka YOKOTA params.regs[10+0x14] &= 0xbf; 16006e8394b8SKazutaka YOKOTA /* turn off word adressing */ 16016e8394b8SKazutaka YOKOTA params.regs[10+0x17] |= 0x40; 16026e8394b8SKazutaka YOKOTA /* set logical screen width */ 16036e8394b8SKazutaka YOKOTA params.regs[10+0x13] = 80; 16046e8394b8SKazutaka YOKOTA /* set 240 lines */ 16056e8394b8SKazutaka YOKOTA params.regs[10+0x11] = 0x2c; 16066e8394b8SKazutaka YOKOTA params.regs[10+0x06] = 0x0d; 16076e8394b8SKazutaka YOKOTA params.regs[10+0x07] = 0x3e; 16086e8394b8SKazutaka YOKOTA params.regs[10+0x10] = 0xea; 16096e8394b8SKazutaka YOKOTA params.regs[10+0x11] = 0xac; 16106e8394b8SKazutaka YOKOTA params.regs[10+0x12] = 0xdf; 16116e8394b8SKazutaka YOKOTA params.regs[10+0x15] = 0xe7; 16126e8394b8SKazutaka YOKOTA params.regs[10+0x16] = 0x06; 16136e8394b8SKazutaka YOKOTA /* set vertical sync polarity to reflect aspect ratio */ 16146e8394b8SKazutaka YOKOTA params.regs[9] = 0xe3; 16156e8394b8SKazutaka YOKOTA goto setup_grmode; 16166e8394b8SKazutaka YOKOTA 16176e8394b8SKazutaka YOKOTA case M_BG320: case M_CG320: case M_BG640: 16186e8394b8SKazutaka YOKOTA case M_CG320_D: case M_CG640_E: 16196e8394b8SKazutaka YOKOTA case M_CG640x350: case M_ENH_CG640: 16206e8394b8SKazutaka YOKOTA case M_BG640x480: case M_CG640x480: case M_VGA_CG320: 16216e8394b8SKazutaka YOKOTA 16226e8394b8SKazutaka YOKOTA setup_grmode: 16236e8394b8SKazutaka YOKOTA vga_load_state(adp, ¶ms); 16246e8394b8SKazutaka YOKOTA break; 16256e8394b8SKazutaka YOKOTA 16266e8394b8SKazutaka YOKOTA default: 16276e8394b8SKazutaka YOKOTA return EINVAL; 16286e8394b8SKazutaka YOKOTA } 16296e8394b8SKazutaka YOKOTA 16306e8394b8SKazutaka YOKOTA adp->va_mode = mode; 16316e8394b8SKazutaka YOKOTA info.vi_flags &= ~V_INFO_LINEAR; /* XXX */ 16326e8394b8SKazutaka YOKOTA update_adapter_info(adp, &info); 16336e8394b8SKazutaka YOKOTA 16346e8394b8SKazutaka YOKOTA /* move hardware cursor out of the way */ 16356e8394b8SKazutaka YOKOTA (*vidsw[adp->va_index]->set_hw_cursor)(adp, -1, -1); 16366e8394b8SKazutaka YOKOTA 16376e8394b8SKazutaka YOKOTA return 0; 16386e8394b8SKazutaka YOKOTA #else /* VGA_NO_MODE_CHANGE */ 16396e8394b8SKazutaka YOKOTA return ENODEV; 16406e8394b8SKazutaka YOKOTA #endif /* VGA_NO_MODE_CHANGE */ 16416e8394b8SKazutaka YOKOTA } 16426e8394b8SKazutaka YOKOTA 16436e8394b8SKazutaka YOKOTA #ifndef VGA_NO_FONT_LOADING 16446e8394b8SKazutaka YOKOTA 16456e8394b8SKazutaka YOKOTA static void 16466e8394b8SKazutaka YOKOTA set_font_mode(video_adapter_t *adp, u_char *buf) 16476e8394b8SKazutaka YOKOTA { 16486e8394b8SKazutaka YOKOTA u_char *mp; 16496e8394b8SKazutaka YOKOTA int s; 16506e8394b8SKazutaka YOKOTA 16516e8394b8SKazutaka YOKOTA s = splhigh(); 16526e8394b8SKazutaka YOKOTA 16536e8394b8SKazutaka YOKOTA /* save register values */ 16546e8394b8SKazutaka YOKOTA if (adp->va_type == KD_VGA) { 16556e8394b8SKazutaka YOKOTA outb(TSIDX, 0x02); buf[0] = inb(TSREG); 16566e8394b8SKazutaka YOKOTA outb(TSIDX, 0x04); buf[1] = inb(TSREG); 16576e8394b8SKazutaka YOKOTA outb(GDCIDX, 0x04); buf[2] = inb(GDCREG); 16586e8394b8SKazutaka YOKOTA outb(GDCIDX, 0x05); buf[3] = inb(GDCREG); 16596e8394b8SKazutaka YOKOTA outb(GDCIDX, 0x06); buf[4] = inb(GDCREG); 16606e8394b8SKazutaka YOKOTA inb(adp->va_crtc_addr + 6); 16616e8394b8SKazutaka YOKOTA outb(ATC, 0x10); buf[5] = inb(ATC + 1); 16626e8394b8SKazutaka YOKOTA } else /* if (adp->va_type == KD_EGA) */ { 16636e8394b8SKazutaka YOKOTA /* 16646e8394b8SKazutaka YOKOTA * EGA cannot be read; copy parameters from the mode parameter 16656e8394b8SKazutaka YOKOTA * table. 16666e8394b8SKazutaka YOKOTA */ 16676e8394b8SKazutaka YOKOTA mp = get_mode_param(adp->va_mode); 16686e8394b8SKazutaka YOKOTA buf[0] = mp[5 + 0x02 - 1]; 16696e8394b8SKazutaka YOKOTA buf[1] = mp[5 + 0x04 - 1]; 16706e8394b8SKazutaka YOKOTA buf[2] = mp[55 + 0x04]; 16716e8394b8SKazutaka YOKOTA buf[3] = mp[55 + 0x05]; 16726e8394b8SKazutaka YOKOTA buf[4] = mp[55 + 0x06]; 16736e8394b8SKazutaka YOKOTA buf[5] = mp[35 + 0x10]; 16746e8394b8SKazutaka YOKOTA } 16756e8394b8SKazutaka YOKOTA 16766e8394b8SKazutaka YOKOTA /* setup vga for loading fonts */ 16776e8394b8SKazutaka YOKOTA inb(adp->va_crtc_addr + 6); /* reset flip-flop */ 16786e8394b8SKazutaka YOKOTA outb(ATC, 0x10); outb(ATC, buf[5] & ~0x01); 16796e8394b8SKazutaka YOKOTA inb(adp->va_crtc_addr + 6); /* reset flip-flop */ 16806e8394b8SKazutaka YOKOTA outb(ATC, 0x20); /* enable palette */ 16816e8394b8SKazutaka YOKOTA 16826e8394b8SKazutaka YOKOTA #if VGA_SLOW_IOACCESS 16836e8394b8SKazutaka YOKOTA #ifdef VGA_ALT_SEQACCESS 16846e8394b8SKazutaka YOKOTA outb(TSIDX, 0x00); outb(TSREG, 0x01); 16856e8394b8SKazutaka YOKOTA #endif 16866e8394b8SKazutaka YOKOTA outb(TSIDX, 0x02); outb(TSREG, 0x04); 16876e8394b8SKazutaka YOKOTA outb(TSIDX, 0x04); outb(TSREG, 0x07); 16886e8394b8SKazutaka YOKOTA #ifdef VGA_ALT_SEQACCESS 16896e8394b8SKazutaka YOKOTA outb(TSIDX, 0x00); outb(TSREG, 0x03); 16906e8394b8SKazutaka YOKOTA #endif 16916e8394b8SKazutaka YOKOTA outb(GDCIDX, 0x04); outb(GDCREG, 0x02); 16926e8394b8SKazutaka YOKOTA outb(GDCIDX, 0x05); outb(GDCREG, 0x00); 16936e8394b8SKazutaka YOKOTA outb(GDCIDX, 0x06); outb(GDCREG, 0x04); 16946e8394b8SKazutaka YOKOTA #else /* VGA_SLOW_IOACCESS */ 16956e8394b8SKazutaka YOKOTA #ifdef VGA_ALT_SEQACCESS 16966e8394b8SKazutaka YOKOTA outw(TSIDX, 0x0100); 16976e8394b8SKazutaka YOKOTA #endif 16986e8394b8SKazutaka YOKOTA outw(TSIDX, 0x0402); 16996e8394b8SKazutaka YOKOTA outw(TSIDX, 0x0704); 17006e8394b8SKazutaka YOKOTA #ifdef VGA_ALT_SEQACCESS 17016e8394b8SKazutaka YOKOTA outw(TSIDX, 0x0300); 17026e8394b8SKazutaka YOKOTA #endif 17036e8394b8SKazutaka YOKOTA outw(GDCIDX, 0x0204); 17046e8394b8SKazutaka YOKOTA outw(GDCIDX, 0x0005); 17056e8394b8SKazutaka YOKOTA outw(GDCIDX, 0x0406); /* addr = a0000, 64kb */ 17066e8394b8SKazutaka YOKOTA #endif /* VGA_SLOW_IOACCESS */ 17076e8394b8SKazutaka YOKOTA 17086e8394b8SKazutaka YOKOTA splx(s); 17096e8394b8SKazutaka YOKOTA } 17106e8394b8SKazutaka YOKOTA 17116e8394b8SKazutaka YOKOTA static void 17126e8394b8SKazutaka YOKOTA set_normal_mode(video_adapter_t *adp, u_char *buf) 17136e8394b8SKazutaka YOKOTA { 17146e8394b8SKazutaka YOKOTA int s; 17156e8394b8SKazutaka YOKOTA 17166e8394b8SKazutaka YOKOTA s = splhigh(); 17176e8394b8SKazutaka YOKOTA 17186e8394b8SKazutaka YOKOTA /* setup vga for normal operation mode again */ 17196e8394b8SKazutaka YOKOTA inb(adp->va_crtc_addr + 6); /* reset flip-flop */ 17206e8394b8SKazutaka YOKOTA outb(ATC, 0x10); outb(ATC, buf[5]); 17216e8394b8SKazutaka YOKOTA inb(adp->va_crtc_addr + 6); /* reset flip-flop */ 17226e8394b8SKazutaka YOKOTA outb(ATC, 0x20); /* enable palette */ 17236e8394b8SKazutaka YOKOTA 17246e8394b8SKazutaka YOKOTA #if VGA_SLOW_IOACCESS 17256e8394b8SKazutaka YOKOTA #ifdef VGA_ALT_SEQACCESS 17266e8394b8SKazutaka YOKOTA outb(TSIDX, 0x00); outb(TSREG, 0x01); 17276e8394b8SKazutaka YOKOTA #endif 17286e8394b8SKazutaka YOKOTA outb(TSIDX, 0x02); outb(TSREG, buf[0]); 17296e8394b8SKazutaka YOKOTA outb(TSIDX, 0x04); outb(TSREG, buf[1]); 17306e8394b8SKazutaka YOKOTA #ifdef VGA_ALT_SEQACCESS 17316e8394b8SKazutaka YOKOTA outb(TSIDX, 0x00); outb(TSREG, 0x03); 17326e8394b8SKazutaka YOKOTA #endif 17336e8394b8SKazutaka YOKOTA outb(GDCIDX, 0x04); outb(GDCREG, buf[2]); 17346e8394b8SKazutaka YOKOTA outb(GDCIDX, 0x05); outb(GDCREG, buf[3]); 17356e8394b8SKazutaka YOKOTA if (adp->va_crtc_addr == MONO_CRTC) { 17366e8394b8SKazutaka YOKOTA outb(GDCIDX, 0x06); outb(GDCREG,(buf[4] & 0x03) | 0x08); 17376e8394b8SKazutaka YOKOTA } else { 17386e8394b8SKazutaka YOKOTA outb(GDCIDX, 0x06); outb(GDCREG,(buf[4] & 0x03) | 0x0c); 17396e8394b8SKazutaka YOKOTA } 17406e8394b8SKazutaka YOKOTA #else /* VGA_SLOW_IOACCESS */ 17416e8394b8SKazutaka YOKOTA #ifdef VGA_ALT_SEQACCESS 17426e8394b8SKazutaka YOKOTA outw(TSIDX, 0x0100); 17436e8394b8SKazutaka YOKOTA #endif 17446e8394b8SKazutaka YOKOTA outw(TSIDX, 0x0002 | (buf[0] << 8)); 17456e8394b8SKazutaka YOKOTA outw(TSIDX, 0x0004 | (buf[1] << 8)); 17466e8394b8SKazutaka YOKOTA #ifdef VGA_ALT_SEQACCESS 17476e8394b8SKazutaka YOKOTA outw(TSIDX, 0x0300); 17486e8394b8SKazutaka YOKOTA #endif 17496e8394b8SKazutaka YOKOTA outw(GDCIDX, 0x0004 | (buf[2] << 8)); 17506e8394b8SKazutaka YOKOTA outw(GDCIDX, 0x0005 | (buf[3] << 8)); 17516e8394b8SKazutaka YOKOTA if (adp->va_crtc_addr == MONO_CRTC) 17526e8394b8SKazutaka YOKOTA outw(GDCIDX, 0x0006 | (((buf[4] & 0x03) | 0x08)<<8)); 17536e8394b8SKazutaka YOKOTA else 17546e8394b8SKazutaka YOKOTA outw(GDCIDX, 0x0006 | (((buf[4] & 0x03) | 0x0c)<<8)); 17556e8394b8SKazutaka YOKOTA #endif /* VGA_SLOW_IOACCESS */ 17566e8394b8SKazutaka YOKOTA 17576e8394b8SKazutaka YOKOTA splx(s); 17586e8394b8SKazutaka YOKOTA } 17596e8394b8SKazutaka YOKOTA 17606e8394b8SKazutaka YOKOTA #endif /* VGA_NO_FONT_LOADING */ 17616e8394b8SKazutaka YOKOTA 17626e8394b8SKazutaka YOKOTA /* 17636e8394b8SKazutaka YOKOTA * save_font(): 17646e8394b8SKazutaka YOKOTA * Read the font data in the requested font page from the video adapter. 17656e8394b8SKazutaka YOKOTA * 17666e8394b8SKazutaka YOKOTA * EGA/VGA 17676e8394b8SKazutaka YOKOTA */ 17686e8394b8SKazutaka YOKOTA static int 17696e8394b8SKazutaka YOKOTA vga_save_font(video_adapter_t *adp, int page, int fontsize, u_char *data, 17706e8394b8SKazutaka YOKOTA int ch, int count) 17716e8394b8SKazutaka YOKOTA { 17726e8394b8SKazutaka YOKOTA #ifndef VGA_NO_FONT_LOADING 17736e8394b8SKazutaka YOKOTA u_char buf[PARAM_BUFSIZE]; 17746e8394b8SKazutaka YOKOTA u_int32_t segment; 17756e8394b8SKazutaka YOKOTA int c; 17766e8394b8SKazutaka YOKOTA #ifdef VGA_ALT_SEQACCESS 17776e8394b8SKazutaka YOKOTA int s; 17786e8394b8SKazutaka YOKOTA u_char val = 0; 17796e8394b8SKazutaka YOKOTA #endif 17806e8394b8SKazutaka YOKOTA 17816e8394b8SKazutaka YOKOTA prologue(adp, V_ADP_FONT, ENODEV); 17826e8394b8SKazutaka YOKOTA 17836e8394b8SKazutaka YOKOTA if (fontsize < 14) { 17846e8394b8SKazutaka YOKOTA /* FONT_8 */ 17856e8394b8SKazutaka YOKOTA fontsize = 8; 17866e8394b8SKazutaka YOKOTA } else if (fontsize >= 32) { 17876e8394b8SKazutaka YOKOTA fontsize = 32; 17886e8394b8SKazutaka YOKOTA } else if (fontsize >= 16) { 17896e8394b8SKazutaka YOKOTA /* FONT_16 */ 17906e8394b8SKazutaka YOKOTA fontsize = 16; 17916e8394b8SKazutaka YOKOTA } else { 17926e8394b8SKazutaka YOKOTA /* FONT_14 */ 17936e8394b8SKazutaka YOKOTA fontsize = 14; 17946e8394b8SKazutaka YOKOTA } 17956e8394b8SKazutaka YOKOTA 17966e8394b8SKazutaka YOKOTA if (page < 0 || page >= 8) 17976e8394b8SKazutaka YOKOTA return EINVAL; 17986e8394b8SKazutaka YOKOTA segment = FONT_BUF + 0x4000*page; 17996e8394b8SKazutaka YOKOTA if (page > 3) 18006e8394b8SKazutaka YOKOTA segment -= 0xe000; 18016e8394b8SKazutaka YOKOTA 18026e8394b8SKazutaka YOKOTA #ifdef VGA_ALT_SEQACCESS 18036e8394b8SKazutaka YOKOTA if (adp->va_type == KD_VGA) { /* what about EGA? XXX */ 18046e8394b8SKazutaka YOKOTA s = splhigh(); 18056e8394b8SKazutaka YOKOTA outb(TSIDX, 0x00); outb(TSREG, 0x01); 18066e8394b8SKazutaka YOKOTA outb(TSIDX, 0x01); val = inb(TSREG); /* disable screen */ 18076e8394b8SKazutaka YOKOTA outb(TSIDX, 0x01); outb(TSREG, val | 0x20); 18086e8394b8SKazutaka YOKOTA outb(TSIDX, 0x00); outb(TSREG, 0x03); 18096e8394b8SKazutaka YOKOTA splx(s); 18106e8394b8SKazutaka YOKOTA } 18116e8394b8SKazutaka YOKOTA #endif 18126e8394b8SKazutaka YOKOTA 18136e8394b8SKazutaka YOKOTA set_font_mode(adp, buf); 18146e8394b8SKazutaka YOKOTA if (fontsize == 32) { 18156e8394b8SKazutaka YOKOTA bcopy_fromio(segment + ch*32, data, fontsize*count); 18166e8394b8SKazutaka YOKOTA } else { 18176e8394b8SKazutaka YOKOTA for (c = ch; count > 0; ++c, --count) { 18186e8394b8SKazutaka YOKOTA bcopy_fromio(segment + c*32, data, fontsize); 18196e8394b8SKazutaka YOKOTA data += fontsize; 18206e8394b8SKazutaka YOKOTA } 18216e8394b8SKazutaka YOKOTA } 18226e8394b8SKazutaka YOKOTA set_normal_mode(adp, buf); 18236e8394b8SKazutaka YOKOTA 18246e8394b8SKazutaka YOKOTA #ifdef VGA_ALT_SEQACCESS 18256e8394b8SKazutaka YOKOTA if (adp->va_type == KD_VGA) { 18266e8394b8SKazutaka YOKOTA s = splhigh(); 18276e8394b8SKazutaka YOKOTA outb(TSIDX, 0x00); outb(TSREG, 0x01); 18286e8394b8SKazutaka YOKOTA outb(TSIDX, 0x01); outb(TSREG, val & 0xdf); /* enable screen */ 18296e8394b8SKazutaka YOKOTA outb(TSIDX, 0x00); outb(TSREG, 0x03); 18306e8394b8SKazutaka YOKOTA splx(s); 18316e8394b8SKazutaka YOKOTA } 18326e8394b8SKazutaka YOKOTA #endif 18336e8394b8SKazutaka YOKOTA 18346e8394b8SKazutaka YOKOTA return 0; 18356e8394b8SKazutaka YOKOTA #else /* VGA_NO_FONT_LOADING */ 18366e8394b8SKazutaka YOKOTA return ENODEV; 18376e8394b8SKazutaka YOKOTA #endif /* VGA_NO_FONT_LOADING */ 18386e8394b8SKazutaka YOKOTA } 18396e8394b8SKazutaka YOKOTA 18406e8394b8SKazutaka YOKOTA /* 18416e8394b8SKazutaka YOKOTA * load_font(): 18426e8394b8SKazutaka YOKOTA * Set the font data in the requested font page. 18436e8394b8SKazutaka YOKOTA * NOTE: it appears that some recent video adapters do not support 18446e8394b8SKazutaka YOKOTA * the font page other than 0... XXX 18456e8394b8SKazutaka YOKOTA * 18466e8394b8SKazutaka YOKOTA * EGA/VGA 18476e8394b8SKazutaka YOKOTA */ 18486e8394b8SKazutaka YOKOTA static int 18496e8394b8SKazutaka YOKOTA vga_load_font(video_adapter_t *adp, int page, int fontsize, u_char *data, 18506e8394b8SKazutaka YOKOTA int ch, int count) 18516e8394b8SKazutaka YOKOTA { 18526e8394b8SKazutaka YOKOTA #ifndef VGA_NO_FONT_LOADING 18536e8394b8SKazutaka YOKOTA u_char buf[PARAM_BUFSIZE]; 18546e8394b8SKazutaka YOKOTA u_int32_t segment; 18556e8394b8SKazutaka YOKOTA int c; 18566e8394b8SKazutaka YOKOTA #ifdef VGA_ALT_SEQACCESS 18576e8394b8SKazutaka YOKOTA int s; 18586e8394b8SKazutaka YOKOTA u_char val = 0; 18596e8394b8SKazutaka YOKOTA #endif 18606e8394b8SKazutaka YOKOTA 18616e8394b8SKazutaka YOKOTA prologue(adp, V_ADP_FONT, ENODEV); 18626e8394b8SKazutaka YOKOTA 18636e8394b8SKazutaka YOKOTA if (fontsize < 14) { 18646e8394b8SKazutaka YOKOTA /* FONT_8 */ 18656e8394b8SKazutaka YOKOTA fontsize = 8; 18666e8394b8SKazutaka YOKOTA } else if (fontsize >= 32) { 18676e8394b8SKazutaka YOKOTA fontsize = 32; 18686e8394b8SKazutaka YOKOTA } else if (fontsize >= 16) { 18696e8394b8SKazutaka YOKOTA /* FONT_16 */ 18706e8394b8SKazutaka YOKOTA fontsize = 16; 18716e8394b8SKazutaka YOKOTA } else { 18726e8394b8SKazutaka YOKOTA /* FONT_14 */ 18736e8394b8SKazutaka YOKOTA fontsize = 14; 18746e8394b8SKazutaka YOKOTA } 18756e8394b8SKazutaka YOKOTA 18766e8394b8SKazutaka YOKOTA if (page < 0 || page >= 8) 18776e8394b8SKazutaka YOKOTA return EINVAL; 18786e8394b8SKazutaka YOKOTA segment = FONT_BUF + 0x4000*page; 18796e8394b8SKazutaka YOKOTA if (page > 3) 18806e8394b8SKazutaka YOKOTA segment -= 0xe000; 18816e8394b8SKazutaka YOKOTA 18826e8394b8SKazutaka YOKOTA #ifdef VGA_ALT_SEQACCESS 18836e8394b8SKazutaka YOKOTA if (adp->va_type == KD_VGA) { /* what about EGA? XXX */ 18846e8394b8SKazutaka YOKOTA s = splhigh(); 18856e8394b8SKazutaka YOKOTA outb(TSIDX, 0x00); outb(TSREG, 0x01); 18866e8394b8SKazutaka YOKOTA outb(TSIDX, 0x01); val = inb(TSREG); /* disable screen */ 18876e8394b8SKazutaka YOKOTA outb(TSIDX, 0x01); outb(TSREG, val | 0x20); 18886e8394b8SKazutaka YOKOTA outb(TSIDX, 0x00); outb(TSREG, 0x03); 18896e8394b8SKazutaka YOKOTA splx(s); 18906e8394b8SKazutaka YOKOTA } 18916e8394b8SKazutaka YOKOTA #endif 18926e8394b8SKazutaka YOKOTA 18936e8394b8SKazutaka YOKOTA set_font_mode(adp, buf); 18946e8394b8SKazutaka YOKOTA if (fontsize == 32) { 18956e8394b8SKazutaka YOKOTA bcopy_toio(data, segment + ch*32, fontsize*count); 18966e8394b8SKazutaka YOKOTA } else { 18976e8394b8SKazutaka YOKOTA for (c = ch; count > 0; ++c, --count) { 18986e8394b8SKazutaka YOKOTA bcopy_toio(data, segment + c*32, fontsize); 18996e8394b8SKazutaka YOKOTA data += fontsize; 19006e8394b8SKazutaka YOKOTA } 19016e8394b8SKazutaka YOKOTA } 19026e8394b8SKazutaka YOKOTA set_normal_mode(adp, buf); 19036e8394b8SKazutaka YOKOTA 19046e8394b8SKazutaka YOKOTA #ifdef VGA_ALT_SEQACCESS 19056e8394b8SKazutaka YOKOTA if (adp->va_type == KD_VGA) { 19066e8394b8SKazutaka YOKOTA s = splhigh(); 19076e8394b8SKazutaka YOKOTA outb(TSIDX, 0x00); outb(TSREG, 0x01); 19086e8394b8SKazutaka YOKOTA outb(TSIDX, 0x01); outb(TSREG, val & 0xdf); /* enable screen */ 19096e8394b8SKazutaka YOKOTA outb(TSIDX, 0x00); outb(TSREG, 0x03); 19106e8394b8SKazutaka YOKOTA splx(s); 19116e8394b8SKazutaka YOKOTA } 19126e8394b8SKazutaka YOKOTA #endif 19136e8394b8SKazutaka YOKOTA 19146e8394b8SKazutaka YOKOTA return 0; 19156e8394b8SKazutaka YOKOTA #else /* VGA_NO_FONT_LOADING */ 19166e8394b8SKazutaka YOKOTA return ENODEV; 19176e8394b8SKazutaka YOKOTA #endif /* VGA_NO_FONT_LOADING */ 19186e8394b8SKazutaka YOKOTA } 19196e8394b8SKazutaka YOKOTA 19206e8394b8SKazutaka YOKOTA /* 19216e8394b8SKazutaka YOKOTA * show_font(): 19226e8394b8SKazutaka YOKOTA * Activate the requested font page. 19236e8394b8SKazutaka YOKOTA * NOTE: it appears that some recent video adapters do not support 19246e8394b8SKazutaka YOKOTA * the font page other than 0... XXX 19256e8394b8SKazutaka YOKOTA * 19266e8394b8SKazutaka YOKOTA * EGA/VGA 19276e8394b8SKazutaka YOKOTA */ 19286e8394b8SKazutaka YOKOTA static int 19296e8394b8SKazutaka YOKOTA vga_show_font(video_adapter_t *adp, int page) 19306e8394b8SKazutaka YOKOTA { 19316e8394b8SKazutaka YOKOTA #ifndef VGA_NO_FONT_LOADING 19326e8394b8SKazutaka YOKOTA static u_char cg[] = { 0x00, 0x05, 0x0a, 0x0f, 0x30, 0x35, 0x3a, 0x3f }; 19336e8394b8SKazutaka YOKOTA int s; 19346e8394b8SKazutaka YOKOTA 19356e8394b8SKazutaka YOKOTA prologue(adp, V_ADP_FONT, ENODEV); 19366e8394b8SKazutaka YOKOTA if (page < 0 || page >= 8) 19376e8394b8SKazutaka YOKOTA return EINVAL; 19386e8394b8SKazutaka YOKOTA 19396e8394b8SKazutaka YOKOTA s = splhigh(); 19406e8394b8SKazutaka YOKOTA outb(TSIDX, 0x03); outb(TSREG, cg[page]); 19416e8394b8SKazutaka YOKOTA splx(s); 19426e8394b8SKazutaka YOKOTA 19436e8394b8SKazutaka YOKOTA return 0; 19446e8394b8SKazutaka YOKOTA #else /* VGA_NO_FONT_LOADING */ 19456e8394b8SKazutaka YOKOTA return ENODEV; 19466e8394b8SKazutaka YOKOTA #endif /* VGA_NO_FONT_LOADING */ 19476e8394b8SKazutaka YOKOTA } 19486e8394b8SKazutaka YOKOTA 19496e8394b8SKazutaka YOKOTA /* 19506e8394b8SKazutaka YOKOTA * save_palette(): 19516e8394b8SKazutaka YOKOTA * Read DAC values. The values have expressed in 8 bits. 19526e8394b8SKazutaka YOKOTA * 19536e8394b8SKazutaka YOKOTA * VGA 19546e8394b8SKazutaka YOKOTA */ 19556e8394b8SKazutaka YOKOTA static int 19566e8394b8SKazutaka YOKOTA vga_save_palette(video_adapter_t *adp, u_char *palette) 19576e8394b8SKazutaka YOKOTA { 19586e8394b8SKazutaka YOKOTA int i; 19596e8394b8SKazutaka YOKOTA 19606e8394b8SKazutaka YOKOTA prologue(adp, V_ADP_PALETTE, ENODEV); 19616e8394b8SKazutaka YOKOTA 19626e8394b8SKazutaka YOKOTA /* 19636e8394b8SKazutaka YOKOTA * We store 8 bit values in the palette buffer, while the standard 19646e8394b8SKazutaka YOKOTA * VGA has 6 bit DAC . 19656e8394b8SKazutaka YOKOTA */ 19666e8394b8SKazutaka YOKOTA outb(PALRADR, 0x00); 19676e8394b8SKazutaka YOKOTA for (i = 0; i < 256*3; ++i) 19686e8394b8SKazutaka YOKOTA palette[i] = inb(PALDATA) << 2; 19696e8394b8SKazutaka YOKOTA inb(adp->va_crtc_addr + 6); /* reset flip/flop */ 19706e8394b8SKazutaka YOKOTA return 0; 19716e8394b8SKazutaka YOKOTA } 19726e8394b8SKazutaka YOKOTA 19736e8394b8SKazutaka YOKOTA static int 19746e8394b8SKazutaka YOKOTA vga_save_palette2(video_adapter_t *adp, int base, int count, 19756e8394b8SKazutaka YOKOTA u_char *r, u_char *g, u_char *b) 19766e8394b8SKazutaka YOKOTA { 19776e8394b8SKazutaka YOKOTA int i; 19786e8394b8SKazutaka YOKOTA 19796e8394b8SKazutaka YOKOTA prologue(adp, V_ADP_PALETTE, ENODEV); 19806e8394b8SKazutaka YOKOTA 19816e8394b8SKazutaka YOKOTA outb(PALRADR, base); 19826e8394b8SKazutaka YOKOTA for (i = 0; i < count; ++i) { 19836e8394b8SKazutaka YOKOTA r[i] = inb(PALDATA) << 2; 19846e8394b8SKazutaka YOKOTA g[i] = inb(PALDATA) << 2; 19856e8394b8SKazutaka YOKOTA b[i] = inb(PALDATA) << 2; 19866e8394b8SKazutaka YOKOTA } 19876e8394b8SKazutaka YOKOTA inb(adp->va_crtc_addr + 6); /* reset flip/flop */ 19886e8394b8SKazutaka YOKOTA return 0; 19896e8394b8SKazutaka YOKOTA } 19906e8394b8SKazutaka YOKOTA 19916e8394b8SKazutaka YOKOTA /* 19926e8394b8SKazutaka YOKOTA * load_palette(): 19936e8394b8SKazutaka YOKOTA * Set DAC values. 19946e8394b8SKazutaka YOKOTA * 19956e8394b8SKazutaka YOKOTA * VGA 19966e8394b8SKazutaka YOKOTA */ 19976e8394b8SKazutaka YOKOTA static int 19986e8394b8SKazutaka YOKOTA vga_load_palette(video_adapter_t *adp, u_char *palette) 19996e8394b8SKazutaka YOKOTA { 20006e8394b8SKazutaka YOKOTA int i; 20016e8394b8SKazutaka YOKOTA 20026e8394b8SKazutaka YOKOTA prologue(adp, V_ADP_PALETTE, ENODEV); 20036e8394b8SKazutaka YOKOTA 20046e8394b8SKazutaka YOKOTA outb(PIXMASK, 0xff); /* no pixelmask */ 20056e8394b8SKazutaka YOKOTA outb(PALWADR, 0x00); 20066e8394b8SKazutaka YOKOTA for (i = 0; i < 256*3; ++i) 20076e8394b8SKazutaka YOKOTA outb(PALDATA, palette[i] >> 2); 20086e8394b8SKazutaka YOKOTA inb(adp->va_crtc_addr + 6); /* reset flip/flop */ 20096e8394b8SKazutaka YOKOTA outb(ATC, 0x20); /* enable palette */ 20106e8394b8SKazutaka YOKOTA return 0; 20116e8394b8SKazutaka YOKOTA } 20126e8394b8SKazutaka YOKOTA 20136e8394b8SKazutaka YOKOTA static int 20146e8394b8SKazutaka YOKOTA vga_load_palette2(video_adapter_t *adp, int base, int count, 20156e8394b8SKazutaka YOKOTA u_char *r, u_char *g, u_char *b) 20166e8394b8SKazutaka YOKOTA { 20176e8394b8SKazutaka YOKOTA int i; 20186e8394b8SKazutaka YOKOTA 20196e8394b8SKazutaka YOKOTA prologue(adp, V_ADP_PALETTE, ENODEV); 20206e8394b8SKazutaka YOKOTA 20216e8394b8SKazutaka YOKOTA outb(PIXMASK, 0xff); /* no pixelmask */ 20226e8394b8SKazutaka YOKOTA outb(PALWADR, base); 20236e8394b8SKazutaka YOKOTA for (i = 0; i < count; ++i) { 20246e8394b8SKazutaka YOKOTA outb(PALDATA, r[i] >> 2); 20256e8394b8SKazutaka YOKOTA outb(PALDATA, g[i] >> 2); 20266e8394b8SKazutaka YOKOTA outb(PALDATA, b[i] >> 2); 20276e8394b8SKazutaka YOKOTA } 20286e8394b8SKazutaka YOKOTA inb(adp->va_crtc_addr + 6); /* reset flip/flop */ 20296e8394b8SKazutaka YOKOTA outb(ATC, 0x20); /* enable palette */ 20306e8394b8SKazutaka YOKOTA return 0; 20316e8394b8SKazutaka YOKOTA } 20326e8394b8SKazutaka YOKOTA 20336e8394b8SKazutaka YOKOTA /* 20346e8394b8SKazutaka YOKOTA * set_border(): 20356e8394b8SKazutaka YOKOTA * Change the border color. 20366e8394b8SKazutaka YOKOTA * 20376e8394b8SKazutaka YOKOTA * CGA/EGA/VGA 20386e8394b8SKazutaka YOKOTA */ 20396e8394b8SKazutaka YOKOTA static int 20406e8394b8SKazutaka YOKOTA vga_set_border(video_adapter_t *adp, int color) 20416e8394b8SKazutaka YOKOTA { 20426e8394b8SKazutaka YOKOTA prologue(adp, V_ADP_BORDER, ENODEV); 20436e8394b8SKazutaka YOKOTA 20446e8394b8SKazutaka YOKOTA switch (adp->va_type) { 20456e8394b8SKazutaka YOKOTA case KD_EGA: 20466e8394b8SKazutaka YOKOTA case KD_VGA: 20476e8394b8SKazutaka YOKOTA inb(adp->va_crtc_addr + 6); /* reset flip-flop */ 20486e8394b8SKazutaka YOKOTA outb(ATC, 0x31); outb(ATC, color & 0xff); 20496e8394b8SKazutaka YOKOTA break; 20506e8394b8SKazutaka YOKOTA case KD_CGA: 20516e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr + 5, color & 0x0f); /* color select register */ 20526e8394b8SKazutaka YOKOTA break; 20536e8394b8SKazutaka YOKOTA case KD_MONO: 20546e8394b8SKazutaka YOKOTA case KD_HERCULES: 20556e8394b8SKazutaka YOKOTA default: 20566e8394b8SKazutaka YOKOTA break; 20576e8394b8SKazutaka YOKOTA } 20586e8394b8SKazutaka YOKOTA return 0; 20596e8394b8SKazutaka YOKOTA } 20606e8394b8SKazutaka YOKOTA 20616e8394b8SKazutaka YOKOTA /* 20626e8394b8SKazutaka YOKOTA * save_state(): 20636e8394b8SKazutaka YOKOTA * Read video register values. 20646e8394b8SKazutaka YOKOTA * NOTE: this function only reads the standard EGA/VGA registers. 20656e8394b8SKazutaka YOKOTA * any extra/extended registers of SVGA adapters are not saved. 20666e8394b8SKazutaka YOKOTA * 20676e8394b8SKazutaka YOKOTA * VGA 20686e8394b8SKazutaka YOKOTA */ 20696e8394b8SKazutaka YOKOTA static int 20706e8394b8SKazutaka YOKOTA vga_save_state(video_adapter_t *adp, void *p, size_t size) 20716e8394b8SKazutaka YOKOTA { 20726e8394b8SKazutaka YOKOTA video_info_t info; 20736e8394b8SKazutaka YOKOTA u_char *buf; 20746e8394b8SKazutaka YOKOTA int crtc_addr; 20756e8394b8SKazutaka YOKOTA int i, j; 20766e8394b8SKazutaka YOKOTA int s; 20776e8394b8SKazutaka YOKOTA 20786e8394b8SKazutaka YOKOTA if (size == 0) { 20796e8394b8SKazutaka YOKOTA /* return the required buffer size */ 20806e8394b8SKazutaka YOKOTA prologue(adp, V_ADP_STATESAVE, 0); 20816e8394b8SKazutaka YOKOTA return sizeof(adp_state_t); 20826e8394b8SKazutaka YOKOTA } else { 20836e8394b8SKazutaka YOKOTA prologue(adp, V_ADP_STATESAVE, ENODEV); 20846e8394b8SKazutaka YOKOTA if (size < sizeof(adp_state_t)) 20856e8394b8SKazutaka YOKOTA return EINVAL; 20866e8394b8SKazutaka YOKOTA } 20876e8394b8SKazutaka YOKOTA 20886e8394b8SKazutaka YOKOTA ((adp_state_t *)p)->sig = V_STATE_SIG; 20896e8394b8SKazutaka YOKOTA buf = ((adp_state_t *)p)->regs; 20906e8394b8SKazutaka YOKOTA bzero(buf, V_MODE_PARAM_SIZE); 20916e8394b8SKazutaka YOKOTA crtc_addr = adp->va_crtc_addr; 20926e8394b8SKazutaka YOKOTA 20936e8394b8SKazutaka YOKOTA s = splhigh(); 20946e8394b8SKazutaka YOKOTA 20956e8394b8SKazutaka YOKOTA outb(TSIDX, 0x00); outb(TSREG, 0x01); /* stop sequencer */ 20966e8394b8SKazutaka YOKOTA for (i = 0, j = 5; i < 4; i++) { 20976e8394b8SKazutaka YOKOTA outb(TSIDX, i + 1); 20986e8394b8SKazutaka YOKOTA buf[j++] = inb(TSREG); 20996e8394b8SKazutaka YOKOTA } 21006e8394b8SKazutaka YOKOTA buf[9] = inb(MISC + 10); /* dot-clock */ 21016e8394b8SKazutaka YOKOTA outb(TSIDX, 0x00); outb(TSREG, 0x03); /* start sequencer */ 21026e8394b8SKazutaka YOKOTA 21036e8394b8SKazutaka YOKOTA for (i = 0, j = 10; i < 25; i++) { /* crtc */ 21046e8394b8SKazutaka YOKOTA outb(crtc_addr, i); 21056e8394b8SKazutaka YOKOTA buf[j++] = inb(crtc_addr + 1); 21066e8394b8SKazutaka YOKOTA } 21076e8394b8SKazutaka YOKOTA for (i = 0, j = 35; i < 20; i++) { /* attribute ctrl */ 21086e8394b8SKazutaka YOKOTA inb(crtc_addr + 6); /* reset flip-flop */ 21096e8394b8SKazutaka YOKOTA outb(ATC, i); 21106e8394b8SKazutaka YOKOTA buf[j++] = inb(ATC + 1); 21116e8394b8SKazutaka YOKOTA } 21126e8394b8SKazutaka YOKOTA for (i = 0, j = 55; i < 9; i++) { /* graph data ctrl */ 21136e8394b8SKazutaka YOKOTA outb(GDCIDX, i); 21146e8394b8SKazutaka YOKOTA buf[j++] = inb(GDCREG); 21156e8394b8SKazutaka YOKOTA } 21166e8394b8SKazutaka YOKOTA inb(crtc_addr + 6); /* reset flip-flop */ 21176e8394b8SKazutaka YOKOTA outb(ATC, 0x20); /* enable palette */ 21186e8394b8SKazutaka YOKOTA 21196e8394b8SKazutaka YOKOTA splx(s); 21206e8394b8SKazutaka YOKOTA 21216e8394b8SKazutaka YOKOTA #if 1 21226e8394b8SKazutaka YOKOTA if (vga_get_info(adp, adp->va_mode, &info) == 0) { 21236e8394b8SKazutaka YOKOTA if (info.vi_flags & V_INFO_GRAPHICS) { 21246e8394b8SKazutaka YOKOTA buf[0] = info.vi_width/info.vi_cwidth; /* COLS */ 21256e8394b8SKazutaka YOKOTA buf[1] = info.vi_height/info.vi_cheight - 1; /* ROWS */ 21266e8394b8SKazutaka YOKOTA } else { 21276e8394b8SKazutaka YOKOTA buf[0] = info.vi_width; /* COLS */ 21286e8394b8SKazutaka YOKOTA buf[1] = info.vi_height - 1; /* ROWS */ 21296e8394b8SKazutaka YOKOTA } 21306e8394b8SKazutaka YOKOTA buf[2] = info.vi_cheight; /* POINTS */ 21316e8394b8SKazutaka YOKOTA } else { 21326e8394b8SKazutaka YOKOTA /* XXX: shouldn't be happening... */ 21336e8394b8SKazutaka YOKOTA printf("vga%d: %s: failed to obtain mode info. (vga_save_state())\n", 21346e8394b8SKazutaka YOKOTA adp->va_unit, adp->va_name); 21356e8394b8SKazutaka YOKOTA } 21366e8394b8SKazutaka YOKOTA #else 21376e8394b8SKazutaka YOKOTA buf[0] = readb(BIOS_PADDRTOVADDR(0x44a)); /* COLS */ 21386e8394b8SKazutaka YOKOTA buf[1] = readb(BIOS_PADDRTOVADDR(0x484)); /* ROWS */ 21396e8394b8SKazutaka YOKOTA buf[2] = readb(BIOS_PADDRTOVADDR(0x485)); /* POINTS */ 21406e8394b8SKazutaka YOKOTA buf[3] = readb(BIOS_PADDRTOVADDR(0x44c)); 21416e8394b8SKazutaka YOKOTA buf[4] = readb(BIOS_PADDRTOVADDR(0x44d)); 21426e8394b8SKazutaka YOKOTA #endif 21436e8394b8SKazutaka YOKOTA 21446e8394b8SKazutaka YOKOTA return 0; 21456e8394b8SKazutaka YOKOTA } 21466e8394b8SKazutaka YOKOTA 21476e8394b8SKazutaka YOKOTA /* 21486e8394b8SKazutaka YOKOTA * load_state(): 21496e8394b8SKazutaka YOKOTA * Set video registers at once. 21506e8394b8SKazutaka YOKOTA * NOTE: this function only updates the standard EGA/VGA registers. 21516e8394b8SKazutaka YOKOTA * any extra/extended registers of SVGA adapters are not changed. 21526e8394b8SKazutaka YOKOTA * 21536e8394b8SKazutaka YOKOTA * EGA/VGA 21546e8394b8SKazutaka YOKOTA */ 21556e8394b8SKazutaka YOKOTA static int 21566e8394b8SKazutaka YOKOTA vga_load_state(video_adapter_t *adp, void *p) 21576e8394b8SKazutaka YOKOTA { 21586e8394b8SKazutaka YOKOTA u_char *buf; 21596e8394b8SKazutaka YOKOTA int crtc_addr; 21606e8394b8SKazutaka YOKOTA int s; 21616e8394b8SKazutaka YOKOTA int i; 21626e8394b8SKazutaka YOKOTA 21636e8394b8SKazutaka YOKOTA prologue(adp, V_ADP_STATELOAD, ENODEV); 21646e8394b8SKazutaka YOKOTA if (((adp_state_t *)p)->sig != V_STATE_SIG) 21656e8394b8SKazutaka YOKOTA return EINVAL; 21666e8394b8SKazutaka YOKOTA 21676e8394b8SKazutaka YOKOTA buf = ((adp_state_t *)p)->regs; 21686e8394b8SKazutaka YOKOTA crtc_addr = adp->va_crtc_addr; 21696e8394b8SKazutaka YOKOTA 21706e8394b8SKazutaka YOKOTA #if VGA_DEBUG > 1 21716e8394b8SKazutaka YOKOTA dump_buffer(buf, V_MODE_PARAM_SIZE); 21726e8394b8SKazutaka YOKOTA #endif 21736e8394b8SKazutaka YOKOTA 21746e8394b8SKazutaka YOKOTA s = splhigh(); 21756e8394b8SKazutaka YOKOTA 21766e8394b8SKazutaka YOKOTA outb(TSIDX, 0x00); outb(TSREG, 0x01); /* stop sequencer */ 21776e8394b8SKazutaka YOKOTA for (i = 0; i < 4; ++i) { /* program sequencer */ 21786e8394b8SKazutaka YOKOTA outb(TSIDX, i + 1); 21796e8394b8SKazutaka YOKOTA outb(TSREG, buf[i + 5]); 21806e8394b8SKazutaka YOKOTA } 21816e8394b8SKazutaka YOKOTA outb(MISC, buf[9]); /* set dot-clock */ 21826e8394b8SKazutaka YOKOTA outb(TSIDX, 0x00); outb(TSREG, 0x03); /* start sequencer */ 21836e8394b8SKazutaka YOKOTA outb(crtc_addr, 0x11); 21846e8394b8SKazutaka YOKOTA outb(crtc_addr + 1, inb(crtc_addr + 1) & 0x7F); 21856e8394b8SKazutaka YOKOTA for (i = 0; i < 25; ++i) { /* program crtc */ 21866e8394b8SKazutaka YOKOTA outb(crtc_addr, i); 21876e8394b8SKazutaka YOKOTA outb(crtc_addr + 1, buf[i + 10]); 21886e8394b8SKazutaka YOKOTA } 21896e8394b8SKazutaka YOKOTA inb(crtc_addr+6); /* reset flip-flop */ 21906e8394b8SKazutaka YOKOTA for (i = 0; i < 20; ++i) { /* program attribute ctrl */ 21916e8394b8SKazutaka YOKOTA outb(ATC, i); 21926e8394b8SKazutaka YOKOTA outb(ATC, buf[i + 35]); 21936e8394b8SKazutaka YOKOTA } 21946e8394b8SKazutaka YOKOTA for (i = 0; i < 9; ++i) { /* program graph data ctrl */ 21956e8394b8SKazutaka YOKOTA outb(GDCIDX, i); 21966e8394b8SKazutaka YOKOTA outb(GDCREG, buf[i + 55]); 21976e8394b8SKazutaka YOKOTA } 21986e8394b8SKazutaka YOKOTA inb(crtc_addr + 6); /* reset flip-flop */ 21996e8394b8SKazutaka YOKOTA outb(ATC, 0x20); /* enable palette */ 22006e8394b8SKazutaka YOKOTA 22016e8394b8SKazutaka YOKOTA #if notyet /* a temporary workaround for kernel panic, XXX */ 22026e8394b8SKazutaka YOKOTA #ifndef VGA_NO_BIOS 22036e8394b8SKazutaka YOKOTA if (adp->va_unit == V_ADP_PRIMARY) { 22046e8394b8SKazutaka YOKOTA writeb(BIOS_PADDRTOVADDR(0x44a), buf[0]); /* COLS */ 22056e8394b8SKazutaka YOKOTA writeb(BIOS_PADDRTOVADDR(0x484), buf[1] + rows_offset - 1); /* ROWS */ 22066e8394b8SKazutaka YOKOTA writeb(BIOS_PADDRTOVADDR(0x485), buf[2]); /* POINTS */ 22076e8394b8SKazutaka YOKOTA #if 0 22086e8394b8SKazutaka YOKOTA writeb(BIOS_PADDRTOVADDR(0x44c), buf[3]); 22096e8394b8SKazutaka YOKOTA writeb(BIOS_PADDRTOVADDR(0x44d), buf[4]); 22106e8394b8SKazutaka YOKOTA #endif 22116e8394b8SKazutaka YOKOTA } 22126e8394b8SKazutaka YOKOTA #endif /* VGA_NO_BIOS */ 22136e8394b8SKazutaka YOKOTA #endif /* notyet */ 22146e8394b8SKazutaka YOKOTA 22156e8394b8SKazutaka YOKOTA splx(s); 22166e8394b8SKazutaka YOKOTA return 0; 22176e8394b8SKazutaka YOKOTA } 22186e8394b8SKazutaka YOKOTA 22196e8394b8SKazutaka YOKOTA /* 22206e8394b8SKazutaka YOKOTA * set_origin(): 22216e8394b8SKazutaka YOKOTA * Change the origin (window mapping) of the banked frame buffer. 22226e8394b8SKazutaka YOKOTA */ 22236e8394b8SKazutaka YOKOTA static int 22246e8394b8SKazutaka YOKOTA vga_set_origin(video_adapter_t *adp, off_t offset) 22256e8394b8SKazutaka YOKOTA { 22266e8394b8SKazutaka YOKOTA /* 22276e8394b8SKazutaka YOKOTA * The standard video modes do not require window mapping; 22286e8394b8SKazutaka YOKOTA * always return error. 22296e8394b8SKazutaka YOKOTA */ 22306e8394b8SKazutaka YOKOTA return ENODEV; 22316e8394b8SKazutaka YOKOTA } 22326e8394b8SKazutaka YOKOTA 22336e8394b8SKazutaka YOKOTA /* 22346e8394b8SKazutaka YOKOTA * read_hw_cursor(): 22356e8394b8SKazutaka YOKOTA * Read the position of the hardware text cursor. 22366e8394b8SKazutaka YOKOTA * 22376e8394b8SKazutaka YOKOTA * all adapters 22386e8394b8SKazutaka YOKOTA */ 22396e8394b8SKazutaka YOKOTA static int 22406e8394b8SKazutaka YOKOTA vga_read_hw_cursor(video_adapter_t *adp, int *col, int *row) 22416e8394b8SKazutaka YOKOTA { 22426e8394b8SKazutaka YOKOTA u_int16_t off; 22436e8394b8SKazutaka YOKOTA int s; 22446e8394b8SKazutaka YOKOTA 22456e8394b8SKazutaka YOKOTA if (!vga_init_done) 22466e8394b8SKazutaka YOKOTA return ENXIO; 22476e8394b8SKazutaka YOKOTA 22486e8394b8SKazutaka YOKOTA if (adp->va_info.vi_flags & V_INFO_GRAPHICS) 22496e8394b8SKazutaka YOKOTA return ENODEV; 22506e8394b8SKazutaka YOKOTA 22516e8394b8SKazutaka YOKOTA s = spltty(); 22526e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr, 14); 22536e8394b8SKazutaka YOKOTA off = inb(adp->va_crtc_addr + 1); 22546e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr, 15); 22556e8394b8SKazutaka YOKOTA off = (off << 8) | inb(adp->va_crtc_addr + 1); 22566e8394b8SKazutaka YOKOTA splx(s); 22576e8394b8SKazutaka YOKOTA 22586e8394b8SKazutaka YOKOTA *row = off / adp->va_info.vi_width; 22596e8394b8SKazutaka YOKOTA *col = off % adp->va_info.vi_width; 22606e8394b8SKazutaka YOKOTA 22616e8394b8SKazutaka YOKOTA return 0; 22626e8394b8SKazutaka YOKOTA } 22636e8394b8SKazutaka YOKOTA 22646e8394b8SKazutaka YOKOTA /* 22656e8394b8SKazutaka YOKOTA * set_hw_cursor(): 22666e8394b8SKazutaka YOKOTA * Move the hardware text cursor. If col and row are both -1, 22676e8394b8SKazutaka YOKOTA * the cursor won't be shown. 22686e8394b8SKazutaka YOKOTA * 22696e8394b8SKazutaka YOKOTA * all adapters 22706e8394b8SKazutaka YOKOTA */ 22716e8394b8SKazutaka YOKOTA static int 22726e8394b8SKazutaka YOKOTA vga_set_hw_cursor(video_adapter_t *adp, int col, int row) 22736e8394b8SKazutaka YOKOTA { 22746e8394b8SKazutaka YOKOTA u_int16_t off; 22756e8394b8SKazutaka YOKOTA int s; 22766e8394b8SKazutaka YOKOTA 22776e8394b8SKazutaka YOKOTA if (!vga_init_done) 22786e8394b8SKazutaka YOKOTA return ENXIO; 22796e8394b8SKazutaka YOKOTA 22806e8394b8SKazutaka YOKOTA if ((col == -1) && (row == -1)) { 22816e8394b8SKazutaka YOKOTA off = -1; 22826e8394b8SKazutaka YOKOTA } else { 22836e8394b8SKazutaka YOKOTA if (adp->va_info.vi_flags & V_INFO_GRAPHICS) 22846e8394b8SKazutaka YOKOTA return ENODEV; 22856e8394b8SKazutaka YOKOTA off = row*adp->va_info.vi_width + col; 22866e8394b8SKazutaka YOKOTA } 22876e8394b8SKazutaka YOKOTA 22886e8394b8SKazutaka YOKOTA s = spltty(); 22896e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr, 14); 22906e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr + 1, off >> 8); 22916e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr, 15); 22926e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr + 1, off & 0x00ff); 22936e8394b8SKazutaka YOKOTA splx(s); 22946e8394b8SKazutaka YOKOTA 22956e8394b8SKazutaka YOKOTA return 0; 22966e8394b8SKazutaka YOKOTA } 22976e8394b8SKazutaka YOKOTA 22986e8394b8SKazutaka YOKOTA /* 22996e8394b8SKazutaka YOKOTA * set_hw_cursor_shape(): 23006e8394b8SKazutaka YOKOTA * Change the shape of the hardware text cursor. If the height is 23016e8394b8SKazutaka YOKOTA * zero or negative, the cursor won't be shown. 23026e8394b8SKazutaka YOKOTA * 23036e8394b8SKazutaka YOKOTA * all adapters 23046e8394b8SKazutaka YOKOTA */ 23056e8394b8SKazutaka YOKOTA static int 23066e8394b8SKazutaka YOKOTA vga_set_hw_cursor_shape(video_adapter_t *adp, int base, int height, 23076e8394b8SKazutaka YOKOTA int celsize, int blink) 23086e8394b8SKazutaka YOKOTA { 23096e8394b8SKazutaka YOKOTA int s; 23106e8394b8SKazutaka YOKOTA 23116e8394b8SKazutaka YOKOTA if (!vga_init_done) 23126e8394b8SKazutaka YOKOTA return ENXIO; 23136e8394b8SKazutaka YOKOTA 23146e8394b8SKazutaka YOKOTA s = spltty(); 23156e8394b8SKazutaka YOKOTA switch (adp->va_type) { 23166e8394b8SKazutaka YOKOTA case KD_VGA: 23176e8394b8SKazutaka YOKOTA case KD_CGA: 23186e8394b8SKazutaka YOKOTA case KD_MONO: 23196e8394b8SKazutaka YOKOTA case KD_HERCULES: 23206e8394b8SKazutaka YOKOTA default: 23216e8394b8SKazutaka YOKOTA if (height <= 0) { 23226e8394b8SKazutaka YOKOTA /* make the cursor invisible */ 23236e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr, 10); 23246e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr + 1, 32); 23256e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr, 11); 23266e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr + 1, 0); 23276e8394b8SKazutaka YOKOTA } else { 23286e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr, 10); 23296e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr + 1, celsize - base - height); 23306e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr, 11); 23316e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr + 1, celsize - base - 1); 23326e8394b8SKazutaka YOKOTA } 23336e8394b8SKazutaka YOKOTA break; 23346e8394b8SKazutaka YOKOTA case KD_EGA: 23356e8394b8SKazutaka YOKOTA if (height <= 0) { 23366e8394b8SKazutaka YOKOTA /* make the cursor invisible */ 23376e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr, 10); 23386e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr + 1, celsize); 23396e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr, 11); 23406e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr + 1, 0); 23416e8394b8SKazutaka YOKOTA } else { 23426e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr, 10); 23436e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr + 1, celsize - base - height); 23446e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr, 11); 23456e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr + 1, celsize - base); 23466e8394b8SKazutaka YOKOTA } 23476e8394b8SKazutaka YOKOTA break; 23486e8394b8SKazutaka YOKOTA } 23496e8394b8SKazutaka YOKOTA splx(s); 23506e8394b8SKazutaka YOKOTA 23516e8394b8SKazutaka YOKOTA return 0; 23526e8394b8SKazutaka YOKOTA } 23536e8394b8SKazutaka YOKOTA 23546e8394b8SKazutaka YOKOTA /* 23556e8394b8SKazutaka YOKOTA * blank_display() 23566e8394b8SKazutaka YOKOTA * Put the display in power save/power off mode. 23576e8394b8SKazutaka YOKOTA * 23586e8394b8SKazutaka YOKOTA * all adapters 23596e8394b8SKazutaka YOKOTA */ 23606e8394b8SKazutaka YOKOTA static int 23616e8394b8SKazutaka YOKOTA vga_blank_display(video_adapter_t *adp, int mode) 23626e8394b8SKazutaka YOKOTA { 23636e8394b8SKazutaka YOKOTA u_char val; 23646e8394b8SKazutaka YOKOTA int s; 23656e8394b8SKazutaka YOKOTA 23666e8394b8SKazutaka YOKOTA s = splhigh(); 23676e8394b8SKazutaka YOKOTA switch (adp->va_type) { 23686e8394b8SKazutaka YOKOTA case KD_VGA: 23696e8394b8SKazutaka YOKOTA switch (mode) { 23706e8394b8SKazutaka YOKOTA case V_DISPLAY_SUSPEND: 23716e8394b8SKazutaka YOKOTA case V_DISPLAY_STAND_BY: 23726e8394b8SKazutaka YOKOTA outb(TSIDX, 0x01); 23736e8394b8SKazutaka YOKOTA val = inb(TSREG); 23746e8394b8SKazutaka YOKOTA outb(TSIDX, 0x01); 23756e8394b8SKazutaka YOKOTA outb(TSREG, val | 0x20); 23766e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr, 0x17); 23776e8394b8SKazutaka YOKOTA val = inb(adp->va_crtc_addr + 1); 23786e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr + 1, val & ~0x80); 23796e8394b8SKazutaka YOKOTA break; 23806e8394b8SKazutaka YOKOTA case V_DISPLAY_BLANK: 23816e8394b8SKazutaka YOKOTA outb(TSIDX, 0x01); 23826e8394b8SKazutaka YOKOTA val = inb(TSREG); 23836e8394b8SKazutaka YOKOTA outb(TSIDX, 0x01); 23846e8394b8SKazutaka YOKOTA outb(TSREG, val | 0x20); 23856e8394b8SKazutaka YOKOTA break; 23866e8394b8SKazutaka YOKOTA case V_DISPLAY_ON: 23876e8394b8SKazutaka YOKOTA outb(TSIDX, 0x01); 23886e8394b8SKazutaka YOKOTA val = inb(TSREG); 23896e8394b8SKazutaka YOKOTA outb(TSIDX, 0x01); 23906e8394b8SKazutaka YOKOTA outb(TSREG, val & 0xDF); 23916e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr, 0x17); 23926e8394b8SKazutaka YOKOTA val = inb(adp->va_crtc_addr + 1); 23936e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr + 1, val | 0x80); 23946e8394b8SKazutaka YOKOTA break; 23956e8394b8SKazutaka YOKOTA } 23966e8394b8SKazutaka YOKOTA break; 23976e8394b8SKazutaka YOKOTA 23986e8394b8SKazutaka YOKOTA case KD_EGA: 23996e8394b8SKazutaka YOKOTA /* no support yet */ 24006e8394b8SKazutaka YOKOTA return ENODEV; 24016e8394b8SKazutaka YOKOTA 24026e8394b8SKazutaka YOKOTA case KD_CGA: 24036e8394b8SKazutaka YOKOTA switch (mode) { 24046e8394b8SKazutaka YOKOTA case V_DISPLAY_SUSPEND: 24056e8394b8SKazutaka YOKOTA case V_DISPLAY_STAND_BY: 24066e8394b8SKazutaka YOKOTA case V_DISPLAY_BLANK: 24076e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr + 4, 0x25); 24086e8394b8SKazutaka YOKOTA break; 24096e8394b8SKazutaka YOKOTA case V_DISPLAY_ON: 24106e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr + 4, 0x2d); 24116e8394b8SKazutaka YOKOTA break; 24126e8394b8SKazutaka YOKOTA } 24136e8394b8SKazutaka YOKOTA break; 24146e8394b8SKazutaka YOKOTA 24156e8394b8SKazutaka YOKOTA case KD_MONO: 24166e8394b8SKazutaka YOKOTA case KD_HERCULES: 24176e8394b8SKazutaka YOKOTA switch (mode) { 24186e8394b8SKazutaka YOKOTA case V_DISPLAY_SUSPEND: 24196e8394b8SKazutaka YOKOTA case V_DISPLAY_STAND_BY: 24206e8394b8SKazutaka YOKOTA case V_DISPLAY_BLANK: 24216e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr + 4, 0x21); 24226e8394b8SKazutaka YOKOTA break; 24236e8394b8SKazutaka YOKOTA case V_DISPLAY_ON: 24246e8394b8SKazutaka YOKOTA outb(adp->va_crtc_addr + 4, 0x29); 24256e8394b8SKazutaka YOKOTA break; 24266e8394b8SKazutaka YOKOTA } 24276e8394b8SKazutaka YOKOTA break; 24286e8394b8SKazutaka YOKOTA default: 24296e8394b8SKazutaka YOKOTA break; 24306e8394b8SKazutaka YOKOTA } 24316e8394b8SKazutaka YOKOTA splx(s); 24326e8394b8SKazutaka YOKOTA 24336e8394b8SKazutaka YOKOTA return 0; 24346e8394b8SKazutaka YOKOTA } 24356e8394b8SKazutaka YOKOTA 24366e8394b8SKazutaka YOKOTA /* 24376e8394b8SKazutaka YOKOTA * mmap(): 24386e8394b8SKazutaka YOKOTA * Mmap frame buffer. 24396e8394b8SKazutaka YOKOTA * 24406e8394b8SKazutaka YOKOTA * all adapters 24416e8394b8SKazutaka YOKOTA */ 24426e8394b8SKazutaka YOKOTA static int 24436e8394b8SKazutaka YOKOTA vga_mmap_buf(video_adapter_t *adp, vm_offset_t offset, int prot) 24446e8394b8SKazutaka YOKOTA { 24456e8394b8SKazutaka YOKOTA if (adp->va_info.vi_flags & V_INFO_LINEAR) 24466e8394b8SKazutaka YOKOTA return -1; 24476e8394b8SKazutaka YOKOTA 24486e8394b8SKazutaka YOKOTA #if VGA_DEBUG > 0 24496e8394b8SKazutaka YOKOTA printf("vga_mmap_buf(): window:0x%x, offset:0x%x\n", 24506e8394b8SKazutaka YOKOTA adp->va_info.vi_window, offset); 24516e8394b8SKazutaka YOKOTA #endif 24526e8394b8SKazutaka YOKOTA 24536e8394b8SKazutaka YOKOTA /* XXX: is this correct? */ 24546e8394b8SKazutaka YOKOTA if (offset > adp->va_window_size - PAGE_SIZE) 24556e8394b8SKazutaka YOKOTA return -1; 24566e8394b8SKazutaka YOKOTA 24576e8394b8SKazutaka YOKOTA #ifdef __i386__ 24586e8394b8SKazutaka YOKOTA return i386_btop(adp->va_info.vi_window + offset); 24596e8394b8SKazutaka YOKOTA #endif 24606e8394b8SKazutaka YOKOTA #ifdef __alpha__ 24616e8394b8SKazutaka YOKOTA return alpha_btop(adp->va_info.vi_window + offset); 24626e8394b8SKazutaka YOKOTA #endif 24636e8394b8SKazutaka YOKOTA } 24646e8394b8SKazutaka YOKOTA 24656e8394b8SKazutaka YOKOTA #ifndef VGA_NO_MODE_CHANGE 24666e8394b8SKazutaka YOKOTA 24676e8394b8SKazutaka YOKOTA static void 24686e8394b8SKazutaka YOKOTA planar_fill(video_adapter_t *adp, int val) 24696e8394b8SKazutaka YOKOTA { 24706e8394b8SKazutaka YOKOTA int length; 24716e8394b8SKazutaka YOKOTA int at; /* position in the frame buffer */ 24726e8394b8SKazutaka YOKOTA int l; 24736e8394b8SKazutaka YOKOTA 24746e8394b8SKazutaka YOKOTA outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */ 24756e8394b8SKazutaka YOKOTA outw(GDCIDX, 0x0003); /* data rotate/function select */ 24766e8394b8SKazutaka YOKOTA outw(GDCIDX, 0x0f01); /* set/reset enable */ 24776e8394b8SKazutaka YOKOTA outw(GDCIDX, 0xff08); /* bit mask */ 24786e8394b8SKazutaka YOKOTA outw(GDCIDX, (val << 8) | 0x00); /* set/reset */ 24796e8394b8SKazutaka YOKOTA at = 0; 24806e8394b8SKazutaka YOKOTA length = adp->va_line_width*adp->va_info.vi_height; 24816e8394b8SKazutaka YOKOTA while (length > 0) { 24826e8394b8SKazutaka YOKOTA l = imin(length, adp->va_window_size); 24836e8394b8SKazutaka YOKOTA (*vidsw[adp->va_index]->set_win_org)(adp, at); 24846e8394b8SKazutaka YOKOTA bzero_io(adp->va_window, l); 24856e8394b8SKazutaka YOKOTA length -= l; 24866e8394b8SKazutaka YOKOTA at += l; 24876e8394b8SKazutaka YOKOTA } 24886e8394b8SKazutaka YOKOTA outw(GDCIDX, 0x0000); /* set/reset */ 24896e8394b8SKazutaka YOKOTA outw(GDCIDX, 0x0001); /* set/reset enable */ 24906e8394b8SKazutaka YOKOTA } 24916e8394b8SKazutaka YOKOTA 24926e8394b8SKazutaka YOKOTA static void 24936e8394b8SKazutaka YOKOTA packed_fill(video_adapter_t *adp, int val) 24946e8394b8SKazutaka YOKOTA { 24956e8394b8SKazutaka YOKOTA int length; 24966e8394b8SKazutaka YOKOTA int at; /* position in the frame buffer */ 24976e8394b8SKazutaka YOKOTA int l; 24986e8394b8SKazutaka YOKOTA 24996e8394b8SKazutaka YOKOTA at = 0; 25006e8394b8SKazutaka YOKOTA length = adp->va_line_width*adp->va_info.vi_height; 25016e8394b8SKazutaka YOKOTA while (length > 0) { 25026e8394b8SKazutaka YOKOTA l = imin(length, adp->va_window_size); 25036e8394b8SKazutaka YOKOTA (*vidsw[adp->va_index]->set_win_org)(adp, at); 25046e8394b8SKazutaka YOKOTA fill_io(val, adp->va_window, l); 25056e8394b8SKazutaka YOKOTA length -= l; 25066e8394b8SKazutaka YOKOTA at += l; 25076e8394b8SKazutaka YOKOTA } 25086e8394b8SKazutaka YOKOTA } 25096e8394b8SKazutaka YOKOTA 25106e8394b8SKazutaka YOKOTA static void 25116e8394b8SKazutaka YOKOTA direct_fill(video_adapter_t *adp, int val) 25126e8394b8SKazutaka YOKOTA { 25136e8394b8SKazutaka YOKOTA int length; 25146e8394b8SKazutaka YOKOTA int at; /* position in the frame buffer */ 25156e8394b8SKazutaka YOKOTA int l; 25166e8394b8SKazutaka YOKOTA 25176e8394b8SKazutaka YOKOTA at = 0; 25186e8394b8SKazutaka YOKOTA length = adp->va_line_width*adp->va_info.vi_height; 25196e8394b8SKazutaka YOKOTA while (length > 0) { 25206e8394b8SKazutaka YOKOTA l = imin(length, adp->va_window_size); 25216e8394b8SKazutaka YOKOTA (*vidsw[adp->va_index]->set_win_org)(adp, at); 25226e8394b8SKazutaka YOKOTA switch (adp->va_info.vi_pixel_size) { 25236e8394b8SKazutaka YOKOTA case sizeof(u_int16_t): 25246e8394b8SKazutaka YOKOTA fillw_io(val, adp->va_window, l/sizeof(u_int16_t)); 25256e8394b8SKazutaka YOKOTA break; 25266e8394b8SKazutaka YOKOTA case 3: 25276e8394b8SKazutaka YOKOTA /* FIXME */ 25286e8394b8SKazutaka YOKOTA break; 25296e8394b8SKazutaka YOKOTA case sizeof(u_int32_t): 25306e8394b8SKazutaka YOKOTA filll_io(val, adp->va_window, l/sizeof(u_int32_t)); 25316e8394b8SKazutaka YOKOTA break; 25326e8394b8SKazutaka YOKOTA } 25336e8394b8SKazutaka YOKOTA length -= l; 25346e8394b8SKazutaka YOKOTA at += l; 25356e8394b8SKazutaka YOKOTA } 25366e8394b8SKazutaka YOKOTA } 25376e8394b8SKazutaka YOKOTA 25386e8394b8SKazutaka YOKOTA static int 25396e8394b8SKazutaka YOKOTA vga_clear(video_adapter_t *adp) 25406e8394b8SKazutaka YOKOTA { 25416e8394b8SKazutaka YOKOTA switch (adp->va_info.vi_mem_model) { 25426e8394b8SKazutaka YOKOTA case V_INFO_MM_TEXT: 25436e8394b8SKazutaka YOKOTA /* do nothing? XXX */ 25446e8394b8SKazutaka YOKOTA break; 25456e8394b8SKazutaka YOKOTA case V_INFO_MM_PLANAR: 25466e8394b8SKazutaka YOKOTA planar_fill(adp, 0); 25476e8394b8SKazutaka YOKOTA break; 25486e8394b8SKazutaka YOKOTA case V_INFO_MM_PACKED: 25496e8394b8SKazutaka YOKOTA packed_fill(adp, 0); 25506e8394b8SKazutaka YOKOTA break; 25516e8394b8SKazutaka YOKOTA case V_INFO_MM_DIRECT: 25526e8394b8SKazutaka YOKOTA direct_fill(adp, 0); 25536e8394b8SKazutaka YOKOTA break; 25546e8394b8SKazutaka YOKOTA } 25556e8394b8SKazutaka YOKOTA return 0; 25566e8394b8SKazutaka YOKOTA } 25576e8394b8SKazutaka YOKOTA 25586e8394b8SKazutaka YOKOTA #ifdef notyet 25596e8394b8SKazutaka YOKOTA static void 25606e8394b8SKazutaka YOKOTA planar_fill_rect(video_adapter_t *adp, int val, int x, int y, int cx, int cy) 25616e8394b8SKazutaka YOKOTA { 25626e8394b8SKazutaka YOKOTA int banksize; 25636e8394b8SKazutaka YOKOTA int bank; 25646e8394b8SKazutaka YOKOTA int pos; 25656e8394b8SKazutaka YOKOTA int offset; /* offset within window */ 25666e8394b8SKazutaka YOKOTA int bx; 25676e8394b8SKazutaka YOKOTA int l; 25686e8394b8SKazutaka YOKOTA 25696e8394b8SKazutaka YOKOTA outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */ 25706e8394b8SKazutaka YOKOTA outw(GDCIDX, 0x0003); /* data rotate/function select */ 25716e8394b8SKazutaka YOKOTA outw(GDCIDX, 0x0f01); /* set/reset enable */ 25726e8394b8SKazutaka YOKOTA outw(GDCIDX, 0xff08); /* bit mask */ 25736e8394b8SKazutaka YOKOTA outw(GDCIDX, (val << 8) | 0x00); /* set/reset */ 25746e8394b8SKazutaka YOKOTA 25756e8394b8SKazutaka YOKOTA banksize = adp->va_window_size; 25766e8394b8SKazutaka YOKOTA bank = -1; 25776e8394b8SKazutaka YOKOTA while (cy > 0) { 25786e8394b8SKazutaka YOKOTA pos = adp->va_line_width*y + x/8; 25796e8394b8SKazutaka YOKOTA if (bank != pos/banksize) { 25806e8394b8SKazutaka YOKOTA (*vidsw[adp->va_index]->set_win_org)(adp, pos); 25816e8394b8SKazutaka YOKOTA bank = pos/banksize; 25826e8394b8SKazutaka YOKOTA } 25836e8394b8SKazutaka YOKOTA offset = pos%banksize; 25846e8394b8SKazutaka YOKOTA bx = (x + cx)/8 - x/8; 25856e8394b8SKazutaka YOKOTA if (x % 8) { 25866e8394b8SKazutaka YOKOTA outw(GDCIDX, ((0xff00 >> (x % 8)) & 0xff00) | 0x08); 25876e8394b8SKazutaka YOKOTA writeb(adp->va_window + offset, 0); 25886e8394b8SKazutaka YOKOTA ++offset; 25896e8394b8SKazutaka YOKOTA --bx; 25906e8394b8SKazutaka YOKOTA if (offset >= banksize) { 25916e8394b8SKazutaka YOKOTA offset = 0; 25926e8394b8SKazutaka YOKOTA ++bank; /* next bank */ 25936e8394b8SKazutaka YOKOTA (*vidsw[adp->va_index]->set_win_org)(adp, bank*banksize); 25946e8394b8SKazutaka YOKOTA } 25956e8394b8SKazutaka YOKOTA outw(GDCIDX, 0xff08); /* bit mask */ 25966e8394b8SKazutaka YOKOTA } 25976e8394b8SKazutaka YOKOTA while (bx > 0) { 25986e8394b8SKazutaka YOKOTA l = imin(bx, banksize); 25996e8394b8SKazutaka YOKOTA bzero_io(adp->va_window + offset, l); 26006e8394b8SKazutaka YOKOTA offset += l; 26016e8394b8SKazutaka YOKOTA bx -= l; 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 } 26086e8394b8SKazutaka YOKOTA if ((x + cx) % 8) { 26096e8394b8SKazutaka YOKOTA outw(GDCIDX, (~(0xff00 >> ((x + cx) % 8)) & 0xff00) | 0x08); 26106e8394b8SKazutaka YOKOTA writeb(adp->va_window + offset, 0); 26116e8394b8SKazutaka YOKOTA ++offset; 26126e8394b8SKazutaka YOKOTA if (offset >= banksize) { 26136e8394b8SKazutaka YOKOTA offset = 0; 26146e8394b8SKazutaka YOKOTA ++bank; /* next bank */ 26156e8394b8SKazutaka YOKOTA (*vidsw[adp->va_index]->set_win_org)(adp, bank*banksize); 26166e8394b8SKazutaka YOKOTA } 26176e8394b8SKazutaka YOKOTA outw(GDCIDX, 0xff08); /* bit mask */ 26186e8394b8SKazutaka YOKOTA } 26196e8394b8SKazutaka YOKOTA ++y; 26206e8394b8SKazutaka YOKOTA --cy; 26216e8394b8SKazutaka YOKOTA } 26226e8394b8SKazutaka YOKOTA 26236e8394b8SKazutaka YOKOTA outw(GDCIDX, 0xff08); /* bit mask */ 26246e8394b8SKazutaka YOKOTA outw(GDCIDX, 0x0000); /* set/reset */ 26256e8394b8SKazutaka YOKOTA outw(GDCIDX, 0x0001); /* set/reset enable */ 26266e8394b8SKazutaka YOKOTA } 26276e8394b8SKazutaka YOKOTA 26286e8394b8SKazutaka YOKOTA static void 26296e8394b8SKazutaka YOKOTA packed_fill_rect(video_adapter_t *adp, int val, int x, int y, int cx, int cy) 26306e8394b8SKazutaka YOKOTA { 26316e8394b8SKazutaka YOKOTA int banksize; 26326e8394b8SKazutaka YOKOTA int bank; 26336e8394b8SKazutaka YOKOTA int pos; 26346e8394b8SKazutaka YOKOTA int offset; /* offset within window */ 26356e8394b8SKazutaka YOKOTA int end; 26366e8394b8SKazutaka YOKOTA 26376e8394b8SKazutaka YOKOTA banksize = adp->va_window_size; 26386e8394b8SKazutaka YOKOTA bank = -1; 26396e8394b8SKazutaka YOKOTA cx *= adp->va_info.vi_pixel_size; 26406e8394b8SKazutaka YOKOTA while (cy > 0) { 26416e8394b8SKazutaka YOKOTA pos = adp->va_line_width*y + x*adp->va_info.vi_pixel_size; 26426e8394b8SKazutaka YOKOTA if (bank != pos/banksize) { 26436e8394b8SKazutaka YOKOTA (*vidsw[adp->va_index]->set_win_org)(adp, pos); 26446e8394b8SKazutaka YOKOTA bank = pos/banksize; 26456e8394b8SKazutaka YOKOTA } 26466e8394b8SKazutaka YOKOTA offset = pos%banksize; 26476e8394b8SKazutaka YOKOTA end = imin(offset + cx, banksize); 26486e8394b8SKazutaka YOKOTA fill_io(val, adp->va_window + offset, 26496e8394b8SKazutaka YOKOTA (end - offset)/adp->va_info.vi_pixel_size); 26506e8394b8SKazutaka YOKOTA /* the line may cross the window boundary */ 26516e8394b8SKazutaka YOKOTA if (offset + cx > banksize) { 26526e8394b8SKazutaka YOKOTA ++bank; /* next bank */ 26536e8394b8SKazutaka YOKOTA (*vidsw[adp->va_index]->set_win_org)(adp, bank*banksize); 26546e8394b8SKazutaka YOKOTA end = offset + cx - banksize; 26556e8394b8SKazutaka YOKOTA fill_io(val, adp->va_window, end/adp->va_info.vi_pixel_size); 26566e8394b8SKazutaka YOKOTA } 26576e8394b8SKazutaka YOKOTA ++y; 26586e8394b8SKazutaka YOKOTA --cy; 26596e8394b8SKazutaka YOKOTA } 26606e8394b8SKazutaka YOKOTA } 26616e8394b8SKazutaka YOKOTA 26626e8394b8SKazutaka YOKOTA static void 26636e8394b8SKazutaka YOKOTA direct_fill_rect16(video_adapter_t *adp, int val, int x, int y, int cx, int cy) 26646e8394b8SKazutaka YOKOTA { 26656e8394b8SKazutaka YOKOTA int banksize; 26666e8394b8SKazutaka YOKOTA int bank; 26676e8394b8SKazutaka YOKOTA int pos; 26686e8394b8SKazutaka YOKOTA int offset; /* offset within window */ 26696e8394b8SKazutaka YOKOTA int end; 26706e8394b8SKazutaka YOKOTA 26716e8394b8SKazutaka YOKOTA /* 26726e8394b8SKazutaka YOKOTA * XXX: the function assumes that banksize is a muliple of 26736e8394b8SKazutaka YOKOTA * sizeof(u_int16_t). 26746e8394b8SKazutaka YOKOTA */ 26756e8394b8SKazutaka YOKOTA banksize = adp->va_window_size; 26766e8394b8SKazutaka YOKOTA bank = -1; 26776e8394b8SKazutaka YOKOTA cx *= sizeof(u_int16_t); 26786e8394b8SKazutaka YOKOTA while (cy > 0) { 26796e8394b8SKazutaka YOKOTA pos = adp->va_line_width*y + x*sizeof(u_int16_t); 26806e8394b8SKazutaka YOKOTA if (bank != pos/banksize) { 26816e8394b8SKazutaka YOKOTA (*vidsw[adp->va_index]->set_win_org)(adp, pos); 26826e8394b8SKazutaka YOKOTA bank = pos/banksize; 26836e8394b8SKazutaka YOKOTA } 26846e8394b8SKazutaka YOKOTA offset = pos%banksize; 26856e8394b8SKazutaka YOKOTA end = imin(offset + cx, banksize); 26866e8394b8SKazutaka YOKOTA fillw_io(val, adp->va_window + offset, 26876e8394b8SKazutaka YOKOTA (end - offset)/sizeof(u_int16_t)); 26886e8394b8SKazutaka YOKOTA /* the line may cross the window boundary */ 26896e8394b8SKazutaka YOKOTA if (offset + cx > banksize) { 26906e8394b8SKazutaka YOKOTA ++bank; /* next bank */ 26916e8394b8SKazutaka YOKOTA (*vidsw[adp->va_index]->set_win_org)(adp, bank*banksize); 26926e8394b8SKazutaka YOKOTA end = offset + cx - banksize; 26936e8394b8SKazutaka YOKOTA fillw_io(val, adp->va_window, end/sizeof(u_int16_t)); 26946e8394b8SKazutaka YOKOTA } 26956e8394b8SKazutaka YOKOTA ++y; 26966e8394b8SKazutaka YOKOTA --cy; 26976e8394b8SKazutaka YOKOTA } 26986e8394b8SKazutaka YOKOTA } 26996e8394b8SKazutaka YOKOTA 27006e8394b8SKazutaka YOKOTA static void 27016e8394b8SKazutaka YOKOTA direct_fill_rect24(video_adapter_t *adp, int val, int x, int y, int cx, int cy) 27026e8394b8SKazutaka YOKOTA { 27036e8394b8SKazutaka YOKOTA int banksize; 27046e8394b8SKazutaka YOKOTA int bank; 27056e8394b8SKazutaka YOKOTA int pos; 27066e8394b8SKazutaka YOKOTA int offset; /* offset within window */ 27076e8394b8SKazutaka YOKOTA int end; 27086e8394b8SKazutaka YOKOTA int i; 27096e8394b8SKazutaka YOKOTA int j; 27106e8394b8SKazutaka YOKOTA u_int8_t b[3]; 27116e8394b8SKazutaka YOKOTA 27126e8394b8SKazutaka YOKOTA b[0] = val & 0x0000ff; 27136e8394b8SKazutaka YOKOTA b[1] = (val >> 8) & 0x0000ff; 27146e8394b8SKazutaka YOKOTA b[2] = (val >> 16) & 0x0000ff; 27156e8394b8SKazutaka YOKOTA banksize = adp->va_window_size; 27166e8394b8SKazutaka YOKOTA bank = -1; 27176e8394b8SKazutaka YOKOTA cx *= 3; 27186e8394b8SKazutaka YOKOTA while (cy > 0) { 27196e8394b8SKazutaka YOKOTA pos = adp->va_line_width*y + x*3; 27206e8394b8SKazutaka YOKOTA if (bank != pos/banksize) { 27216e8394b8SKazutaka YOKOTA (*vidsw[adp->va_index]->set_win_org)(adp, pos); 27226e8394b8SKazutaka YOKOTA bank = pos/banksize; 27236e8394b8SKazutaka YOKOTA } 27246e8394b8SKazutaka YOKOTA offset = pos%banksize; 27256e8394b8SKazutaka YOKOTA end = imin(offset + cx, banksize); 27266e8394b8SKazutaka YOKOTA for (i = 0, j = offset; j < end; i = (++i)%3, ++j) { 27276e8394b8SKazutaka YOKOTA writeb(adp->va_window + j, b[i]); 27286e8394b8SKazutaka YOKOTA } 27296e8394b8SKazutaka YOKOTA /* the line may cross the window boundary */ 27306e8394b8SKazutaka YOKOTA if (offset + cx >= banksize) { 27316e8394b8SKazutaka YOKOTA ++bank; /* next bank */ 27326e8394b8SKazutaka YOKOTA (*vidsw[adp->va_index]->set_win_org)(adp, bank*banksize); 27336e8394b8SKazutaka YOKOTA j = 0; 27346e8394b8SKazutaka YOKOTA end = offset + cx - banksize; 27356e8394b8SKazutaka YOKOTA for (; j < end; i = (++i)%3, ++j) { 27366e8394b8SKazutaka YOKOTA writeb(adp->va_window + j, b[i]); 27376e8394b8SKazutaka YOKOTA } 27386e8394b8SKazutaka YOKOTA } 27396e8394b8SKazutaka YOKOTA ++y; 27406e8394b8SKazutaka YOKOTA --cy; 27416e8394b8SKazutaka YOKOTA } 27426e8394b8SKazutaka YOKOTA } 27436e8394b8SKazutaka YOKOTA 27446e8394b8SKazutaka YOKOTA static void 27456e8394b8SKazutaka YOKOTA direct_fill_rect32(video_adapter_t *adp, int val, int x, int y, int cx, int cy) 27466e8394b8SKazutaka YOKOTA { 27476e8394b8SKazutaka YOKOTA int banksize; 27486e8394b8SKazutaka YOKOTA int bank; 27496e8394b8SKazutaka YOKOTA int pos; 27506e8394b8SKazutaka YOKOTA int offset; /* offset within window */ 27516e8394b8SKazutaka YOKOTA int end; 27526e8394b8SKazutaka YOKOTA 27536e8394b8SKazutaka YOKOTA /* 27546e8394b8SKazutaka YOKOTA * XXX: the function assumes that banksize is a muliple of 27556e8394b8SKazutaka YOKOTA * sizeof(u_int32_t). 27566e8394b8SKazutaka YOKOTA */ 27576e8394b8SKazutaka YOKOTA banksize = adp->va_window_size; 27586e8394b8SKazutaka YOKOTA bank = -1; 27596e8394b8SKazutaka YOKOTA cx *= sizeof(u_int32_t); 27606e8394b8SKazutaka YOKOTA while (cy > 0) { 27616e8394b8SKazutaka YOKOTA pos = adp->va_line_width*y + x*sizeof(u_int32_t); 27626e8394b8SKazutaka YOKOTA if (bank != pos/banksize) { 27636e8394b8SKazutaka YOKOTA (*vidsw[adp->va_index]->set_win_org)(adp, pos); 27646e8394b8SKazutaka YOKOTA bank = pos/banksize; 27656e8394b8SKazutaka YOKOTA } 27666e8394b8SKazutaka YOKOTA offset = pos%banksize; 27676e8394b8SKazutaka YOKOTA end = imin(offset + cx, banksize); 27686e8394b8SKazutaka YOKOTA filll_io(val, adp->va_window + offset, 27696e8394b8SKazutaka YOKOTA (end - offset)/sizeof(u_int32_t)); 27706e8394b8SKazutaka YOKOTA /* the line may cross the window boundary */ 27716e8394b8SKazutaka YOKOTA if (offset + cx > banksize) { 27726e8394b8SKazutaka YOKOTA ++bank; /* next bank */ 27736e8394b8SKazutaka YOKOTA (*vidsw[adp->va_index]->set_win_org)(adp, bank*banksize); 27746e8394b8SKazutaka YOKOTA end = offset + cx - banksize; 27756e8394b8SKazutaka YOKOTA filll_io(val, adp->va_window, end/sizeof(u_int32_t)); 27766e8394b8SKazutaka YOKOTA } 27776e8394b8SKazutaka YOKOTA ++y; 27786e8394b8SKazutaka YOKOTA --cy; 27796e8394b8SKazutaka YOKOTA } 27806e8394b8SKazutaka YOKOTA } 27816e8394b8SKazutaka YOKOTA 27826e8394b8SKazutaka YOKOTA static int 27836e8394b8SKazutaka YOKOTA vga_fill_rect(video_adapter_t *adp, int val, int x, int y, int cx, int cy) 27846e8394b8SKazutaka YOKOTA { 27856e8394b8SKazutaka YOKOTA switch (adp->va_info.vi_mem_model) { 27866e8394b8SKazutaka YOKOTA case V_INFO_MM_TEXT: 27876e8394b8SKazutaka YOKOTA /* do nothing? XXX */ 27886e8394b8SKazutaka YOKOTA break; 27896e8394b8SKazutaka YOKOTA case V_INFO_MM_PLANAR: 27906e8394b8SKazutaka YOKOTA planar_fill_rect(adp, val, x, y, cx, cy); 27916e8394b8SKazutaka YOKOTA break; 27926e8394b8SKazutaka YOKOTA case V_INFO_MM_PACKED: 27936e8394b8SKazutaka YOKOTA packed_fill_rect(adp, val, x, y, cx, cy); 27946e8394b8SKazutaka YOKOTA break; 27956e8394b8SKazutaka YOKOTA case V_INFO_MM_DIRECT: 27966e8394b8SKazutaka YOKOTA switch (adp->va_info.vi_pixel_size) { 27976e8394b8SKazutaka YOKOTA case sizeof(u_int16_t): 27986e8394b8SKazutaka YOKOTA direct_fill_rect16(adp, val, x, y, cx, cy); 27996e8394b8SKazutaka YOKOTA break; 28006e8394b8SKazutaka YOKOTA case 3: 28016e8394b8SKazutaka YOKOTA direct_fill_rect24(adp, val, x, y, cx, cy); 28026e8394b8SKazutaka YOKOTA break; 28036e8394b8SKazutaka YOKOTA case sizeof(u_int32_t): 28046e8394b8SKazutaka YOKOTA direct_fill_rect32(adp, val, x, y, cx, cy); 28056e8394b8SKazutaka YOKOTA break; 28066e8394b8SKazutaka YOKOTA } 28076e8394b8SKazutaka YOKOTA break; 28086e8394b8SKazutaka YOKOTA } 28096e8394b8SKazutaka YOKOTA return 0; 28106e8394b8SKazutaka YOKOTA } 28116e8394b8SKazutaka YOKOTA #else /* !notyet */ 28126e8394b8SKazutaka YOKOTA static int 28136e8394b8SKazutaka YOKOTA vga_fill_rect(video_adapter_t *adp, int val, int x, int y, int cx, int cy) 28146e8394b8SKazutaka YOKOTA { 28156e8394b8SKazutaka YOKOTA return ENODEV; 28166e8394b8SKazutaka YOKOTA } 28176e8394b8SKazutaka YOKOTA #endif /* notyet */ 28186e8394b8SKazutaka YOKOTA 28196e8394b8SKazutaka YOKOTA static int 28206e8394b8SKazutaka YOKOTA vga_bitblt(video_adapter_t *adp,...) 28216e8394b8SKazutaka YOKOTA { 28226e8394b8SKazutaka YOKOTA /* FIXME */ 28236e8394b8SKazutaka YOKOTA return ENODEV; 28246e8394b8SKazutaka YOKOTA } 28256e8394b8SKazutaka YOKOTA 28266e8394b8SKazutaka YOKOTA #endif /* !VGA_NO_MODE_CHANGE */ 28276e8394b8SKazutaka YOKOTA 28286e8394b8SKazutaka YOKOTA static int 28296e8394b8SKazutaka YOKOTA get_palette(video_adapter_t *adp, int base, int count, 28306e8394b8SKazutaka YOKOTA u_char *red, u_char *green, u_char *blue, u_char *trans) 28316e8394b8SKazutaka YOKOTA { 28326e8394b8SKazutaka YOKOTA u_char *r; 28336e8394b8SKazutaka YOKOTA u_char *g; 28346e8394b8SKazutaka YOKOTA u_char *b; 28356e8394b8SKazutaka YOKOTA 28366e8394b8SKazutaka YOKOTA if ((base < 0) || (base >= 256) || (base + count > 256)) 28376e8394b8SKazutaka YOKOTA return EINVAL; 28386e8394b8SKazutaka YOKOTA 28396e8394b8SKazutaka YOKOTA r = malloc(count*3, M_DEVBUF, M_WAITOK); 28406e8394b8SKazutaka YOKOTA g = r + count; 28416e8394b8SKazutaka YOKOTA b = g + count; 28426e8394b8SKazutaka YOKOTA if (vga_save_palette2(adp, base, count, r, g, b)) 28436e8394b8SKazutaka YOKOTA return ENODEV; 28446e8394b8SKazutaka YOKOTA copyout(r, red, count); 28456e8394b8SKazutaka YOKOTA copyout(g, green, count); 28466e8394b8SKazutaka YOKOTA copyout(b, blue, count); 28476e8394b8SKazutaka YOKOTA if (trans != NULL) { 28486e8394b8SKazutaka YOKOTA bzero(r, count); 28496e8394b8SKazutaka YOKOTA copyout(r, trans, count); 28506e8394b8SKazutaka YOKOTA } 28516e8394b8SKazutaka YOKOTA free(r, M_DEVBUF); 28526e8394b8SKazutaka YOKOTA 28536e8394b8SKazutaka YOKOTA return 0; 28546e8394b8SKazutaka YOKOTA } 28556e8394b8SKazutaka YOKOTA 28566e8394b8SKazutaka YOKOTA static int 28576e8394b8SKazutaka YOKOTA set_palette(video_adapter_t *adp, int base, int count, 28586e8394b8SKazutaka YOKOTA u_char *red, u_char *green, u_char *blue, u_char *trans) 28596e8394b8SKazutaka YOKOTA { 28606e8394b8SKazutaka YOKOTA u_char *r; 28616e8394b8SKazutaka YOKOTA u_char *g; 28626e8394b8SKazutaka YOKOTA u_char *b; 28636e8394b8SKazutaka YOKOTA int err; 28646e8394b8SKazutaka YOKOTA 28656e8394b8SKazutaka YOKOTA if ((base < 0) || (base >= 256) || (base + count > 256)) 28666e8394b8SKazutaka YOKOTA return EINVAL; 28676e8394b8SKazutaka YOKOTA 28686e8394b8SKazutaka YOKOTA r = malloc(count*3, M_DEVBUF, M_WAITOK); 28696e8394b8SKazutaka YOKOTA g = r + count; 28706e8394b8SKazutaka YOKOTA b = g + count; 28716e8394b8SKazutaka YOKOTA copyin(red, r, count); 28726e8394b8SKazutaka YOKOTA copyin(green, g, count); 28736e8394b8SKazutaka YOKOTA copyin(blue, b, count); 28746e8394b8SKazutaka YOKOTA err = vga_load_palette2(adp, base, count, r, g, b); 28756e8394b8SKazutaka YOKOTA free(r, M_DEVBUF); 28766e8394b8SKazutaka YOKOTA 28776e8394b8SKazutaka YOKOTA return (err ? ENODEV : 0); 28786e8394b8SKazutaka YOKOTA } 28796e8394b8SKazutaka YOKOTA 28806e8394b8SKazutaka YOKOTA static int 28816e8394b8SKazutaka YOKOTA vga_dev_ioctl(video_adapter_t *adp, u_long cmd, caddr_t arg) 28826e8394b8SKazutaka YOKOTA { 28836e8394b8SKazutaka YOKOTA switch (cmd) { 28846e8394b8SKazutaka YOKOTA case FBIO_GETWINORG: /* get frame buffer window origin */ 28856e8394b8SKazutaka YOKOTA *(u_int *)arg = 0; 28866e8394b8SKazutaka YOKOTA return 0; 28876e8394b8SKazutaka YOKOTA 28886e8394b8SKazutaka YOKOTA case FBIO_SETWINORG: /* set frame buffer window origin */ 28896e8394b8SKazutaka YOKOTA return ENODEV; 28906e8394b8SKazutaka YOKOTA 28916e8394b8SKazutaka YOKOTA case FBIO_SETDISPSTART: /* set display start address */ 28926e8394b8SKazutaka YOKOTA return (set_display_start(adp, 28936e8394b8SKazutaka YOKOTA ((video_display_start_t *)arg)->x, 28946e8394b8SKazutaka YOKOTA ((video_display_start_t *)arg)->y) 28956e8394b8SKazutaka YOKOTA ? ENODEV : 0); 28966e8394b8SKazutaka YOKOTA 28976e8394b8SKazutaka YOKOTA case FBIO_SETLINEWIDTH: /* set scan line length in pixel */ 28986e8394b8SKazutaka YOKOTA return (set_line_length(adp, *(u_int *)arg) ? ENODEV : 0); 28996e8394b8SKazutaka YOKOTA 29006e8394b8SKazutaka YOKOTA case FBIO_GETPALETTE: /* get color palette */ 29016e8394b8SKazutaka YOKOTA return get_palette(adp, ((video_color_palette_t *)arg)->index, 29026e8394b8SKazutaka YOKOTA ((video_color_palette_t *)arg)->count, 29036e8394b8SKazutaka YOKOTA ((video_color_palette_t *)arg)->red, 29046e8394b8SKazutaka YOKOTA ((video_color_palette_t *)arg)->green, 29056e8394b8SKazutaka YOKOTA ((video_color_palette_t *)arg)->blue, 29066e8394b8SKazutaka YOKOTA ((video_color_palette_t *)arg)->transparent); 29076e8394b8SKazutaka YOKOTA 29086e8394b8SKazutaka YOKOTA case FBIO_SETPALETTE: /* set color palette */ 29096e8394b8SKazutaka YOKOTA return set_palette(adp, ((video_color_palette_t *)arg)->index, 29106e8394b8SKazutaka YOKOTA ((video_color_palette_t *)arg)->count, 29116e8394b8SKazutaka YOKOTA ((video_color_palette_t *)arg)->red, 29126e8394b8SKazutaka YOKOTA ((video_color_palette_t *)arg)->green, 29136e8394b8SKazutaka YOKOTA ((video_color_palette_t *)arg)->blue, 29146e8394b8SKazutaka YOKOTA ((video_color_palette_t *)arg)->transparent); 29156e8394b8SKazutaka YOKOTA 29166e8394b8SKazutaka YOKOTA case FBIOGTYPE: /* get frame buffer type info. */ 29176e8394b8SKazutaka YOKOTA ((struct fbtype *)arg)->fb_type = fb_type(adp->va_type); 29186e8394b8SKazutaka YOKOTA ((struct fbtype *)arg)->fb_height = adp->va_info.vi_height; 29196e8394b8SKazutaka YOKOTA ((struct fbtype *)arg)->fb_width = adp->va_info.vi_width; 29206e8394b8SKazutaka YOKOTA ((struct fbtype *)arg)->fb_depth = adp->va_info.vi_depth; 29216e8394b8SKazutaka YOKOTA if ((adp->va_info.vi_depth <= 1) || (adp->va_info.vi_depth > 8)) 29226e8394b8SKazutaka YOKOTA ((struct fbtype *)arg)->fb_cmsize = 0; 29236e8394b8SKazutaka YOKOTA else 29246e8394b8SKazutaka YOKOTA ((struct fbtype *)arg)->fb_cmsize = 1 << adp->va_info.vi_depth; 29256e8394b8SKazutaka YOKOTA ((struct fbtype *)arg)->fb_size = adp->va_buffer_size; 29266e8394b8SKazutaka YOKOTA return 0; 29276e8394b8SKazutaka YOKOTA 29286e8394b8SKazutaka YOKOTA case FBIOGETCMAP: /* get color palette */ 29296e8394b8SKazutaka YOKOTA return get_palette(adp, ((struct fbcmap *)arg)->index, 29306e8394b8SKazutaka YOKOTA ((struct fbcmap *)arg)->count, 29316e8394b8SKazutaka YOKOTA ((struct fbcmap *)arg)->red, 29326e8394b8SKazutaka YOKOTA ((struct fbcmap *)arg)->green, 29336e8394b8SKazutaka YOKOTA ((struct fbcmap *)arg)->blue, NULL); 29346e8394b8SKazutaka YOKOTA 29356e8394b8SKazutaka YOKOTA case FBIOPUTCMAP: /* set color palette */ 29366e8394b8SKazutaka YOKOTA return set_palette(adp, ((struct fbcmap *)arg)->index, 29376e8394b8SKazutaka YOKOTA ((struct fbcmap *)arg)->count, 29386e8394b8SKazutaka YOKOTA ((struct fbcmap *)arg)->red, 29396e8394b8SKazutaka YOKOTA ((struct fbcmap *)arg)->green, 29406e8394b8SKazutaka YOKOTA ((struct fbcmap *)arg)->blue, NULL); 29416e8394b8SKazutaka YOKOTA 29426e8394b8SKazutaka YOKOTA default: 29436e8394b8SKazutaka YOKOTA return fb_commonioctl(adp, cmd, arg); 29446e8394b8SKazutaka YOKOTA } 29456e8394b8SKazutaka YOKOTA } 29466e8394b8SKazutaka YOKOTA 29476e8394b8SKazutaka YOKOTA static void 29486e8394b8SKazutaka YOKOTA dump_buffer(u_char *buf, size_t len) 29496e8394b8SKazutaka YOKOTA { 29506e8394b8SKazutaka YOKOTA int i; 29516e8394b8SKazutaka YOKOTA 29526e8394b8SKazutaka YOKOTA for(i = 0; i < len;) { 29536e8394b8SKazutaka YOKOTA printf("%02x ", buf[i]); 29546e8394b8SKazutaka YOKOTA if ((++i % 16) == 0) 29556e8394b8SKazutaka YOKOTA printf("\n"); 29566e8394b8SKazutaka YOKOTA } 29576e8394b8SKazutaka YOKOTA } 29586e8394b8SKazutaka YOKOTA 29596e8394b8SKazutaka YOKOTA /* 29606e8394b8SKazutaka YOKOTA * diag(): 29616e8394b8SKazutaka YOKOTA * Print some information about the video adapter and video modes, 29626e8394b8SKazutaka YOKOTA * with requested level of details. 29636e8394b8SKazutaka YOKOTA * 29646e8394b8SKazutaka YOKOTA * all adapters 29656e8394b8SKazutaka YOKOTA */ 29666e8394b8SKazutaka YOKOTA static int 29676e8394b8SKazutaka YOKOTA vga_diag(video_adapter_t *adp, int level) 29686e8394b8SKazutaka YOKOTA { 29696e8394b8SKazutaka YOKOTA u_char *mp; 29706e8394b8SKazutaka YOKOTA #if FB_DEBUG > 1 29716e8394b8SKazutaka YOKOTA video_info_t info; 29726e8394b8SKazutaka YOKOTA int i; 29736e8394b8SKazutaka YOKOTA #endif 29746e8394b8SKazutaka YOKOTA 29756e8394b8SKazutaka YOKOTA if (!vga_init_done) 29766e8394b8SKazutaka YOKOTA return ENXIO; 29776e8394b8SKazutaka YOKOTA 29786e8394b8SKazutaka YOKOTA #if FB_DEBUG > 1 29796e8394b8SKazutaka YOKOTA #ifndef VGA_NO_BIOS 29806e8394b8SKazutaka YOKOTA printf("vga: RTC equip. code:0x%02x, DCC code:0x%02x\n", 29816e8394b8SKazutaka YOKOTA rtcin(RTC_EQUIPMENT), readb(BIOS_PADDRTOVADDR(0x488))); 29826e8394b8SKazutaka YOKOTA printf("vga: CRTC:0x%x, video option:0x%02x, ", 29836e8394b8SKazutaka YOKOTA readw(BIOS_PADDRTOVADDR(0x463)), 29846e8394b8SKazutaka YOKOTA readb(BIOS_PADDRTOVADDR(0x487))); 29856e8394b8SKazutaka YOKOTA printf("rows:%d, cols:%d, font height:%d\n", 29866e8394b8SKazutaka YOKOTA readb(BIOS_PADDRTOVADDR(0x44a)), 29876e8394b8SKazutaka YOKOTA readb(BIOS_PADDRTOVADDR(0x484)) + 1, 29886e8394b8SKazutaka YOKOTA readb(BIOS_PADDRTOVADDR(0x485))); 29896e8394b8SKazutaka YOKOTA #endif /* VGA_NO_BIOS */ 29906e8394b8SKazutaka YOKOTA #if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE) 29916e8394b8SKazutaka YOKOTA printf("vga: param table EGA/VGA:%p", video_mode_ptr); 29926e8394b8SKazutaka YOKOTA printf(", CGA/MDA:%p\n", video_mode_ptr2); 29936e8394b8SKazutaka YOKOTA printf("vga: rows_offset:%d\n", rows_offset); 29946e8394b8SKazutaka YOKOTA #endif 29956e8394b8SKazutaka YOKOTA #endif /* FB_DEBUG > 1 */ 29966e8394b8SKazutaka YOKOTA 29976e8394b8SKazutaka YOKOTA fb_dump_adp_info(VGA_DRIVER_NAME, adp, level); 29986e8394b8SKazutaka YOKOTA 29996e8394b8SKazutaka YOKOTA #if FB_DEBUG > 1 30006e8394b8SKazutaka YOKOTA if (adp->va_flags & V_ADP_MODECHANGE) { 30016e8394b8SKazutaka YOKOTA for (i = 0; bios_vmode[i].vi_mode != EOT; ++i) { 30026e8394b8SKazutaka YOKOTA if (bios_vmode[i].vi_mode == NA) 30036e8394b8SKazutaka YOKOTA continue; 30046e8394b8SKazutaka YOKOTA if (get_mode_param(bios_vmode[i].vi_mode) == NULL) 30056e8394b8SKazutaka YOKOTA continue; 30066e8394b8SKazutaka YOKOTA fb_dump_mode_info(VGA_DRIVER_NAME, adp, &bios_vmode[i], level); 30076e8394b8SKazutaka YOKOTA } 30086e8394b8SKazutaka YOKOTA } else { 30096e8394b8SKazutaka YOKOTA vga_get_info(adp, adp->va_initial_mode, &info); /* shouldn't fail */ 30106e8394b8SKazutaka YOKOTA fb_dump_mode_info(VGA_DRIVER_NAME, adp, &info, level); 30116e8394b8SKazutaka YOKOTA } 30126e8394b8SKazutaka YOKOTA #endif /* FB_DEBUG > 1 */ 30136e8394b8SKazutaka YOKOTA 30146e8394b8SKazutaka YOKOTA if ((adp->va_type != KD_EGA) && (adp->va_type != KD_VGA)) 30156e8394b8SKazutaka YOKOTA return 0; 30166e8394b8SKazutaka YOKOTA #if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE) 30176e8394b8SKazutaka YOKOTA if (video_mode_ptr == NULL) 30186e8394b8SKazutaka YOKOTA printf("vga%d: %s: WARNING: video mode switching is not " 30196e8394b8SKazutaka YOKOTA "fully supported on this adapter\n", 30206e8394b8SKazutaka YOKOTA adp->va_unit, adp->va_name); 30216e8394b8SKazutaka YOKOTA #endif 30226e8394b8SKazutaka YOKOTA if (level <= 0) 30236e8394b8SKazutaka YOKOTA return 0; 30246e8394b8SKazutaka YOKOTA 30256e8394b8SKazutaka YOKOTA if (adp->va_type == KD_VGA) { 30266e8394b8SKazutaka YOKOTA printf("VGA parameters upon power-up\n"); 30276e8394b8SKazutaka YOKOTA dump_buffer(adpstate.regs, sizeof(adpstate.regs)); 30286e8394b8SKazutaka YOKOTA printf("VGA parameters in BIOS for mode %d\n", adp->va_initial_mode); 30296e8394b8SKazutaka YOKOTA dump_buffer(adpstate2.regs, sizeof(adpstate2.regs)); 30306e8394b8SKazutaka YOKOTA } 30316e8394b8SKazutaka YOKOTA 30326e8394b8SKazutaka YOKOTA mp = get_mode_param(adp->va_initial_mode); 30336e8394b8SKazutaka YOKOTA if (mp == NULL) /* this shouldn't be happening */ 30346e8394b8SKazutaka YOKOTA return 0; 30356e8394b8SKazutaka YOKOTA printf("EGA/VGA parameters to be used for mode %d\n", adp->va_initial_mode); 30366e8394b8SKazutaka YOKOTA dump_buffer(mp, V_MODE_PARAM_SIZE); 30376e8394b8SKazutaka YOKOTA 30386e8394b8SKazutaka YOKOTA return 0; 30396e8394b8SKazutaka YOKOTA } 30406e8394b8SKazutaka YOKOTA 30416e8394b8SKazutaka YOKOTA #endif /* NVGA > 0 */ 3042