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