2 * Copyright (c) 2001 Andrew Miklic
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * Copyright (c) 1995, 1996 Carnegie-Mellon University.
28 * All rights reserved.
30 * Author: Chris G. Demetriou
32 * Permission to use, copy, modify and distribute this software and
33 * its documentation is hereby granted, provided that both the copyright
34 * notice and this permission notice appear in all copies of the
35 * software, derivative works or modified versions, and any portions
36 * thereof, and that both notices appear in supporting documentation.
38 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
39 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
40 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
42 * Carnegie Mellon requests users of this software to return to
44 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
45 * School of Computer Science
46 * Carnegie Mellon University
47 * Pittsburgh PA 15213-3890
49 * any improvements or extensions that they make and grant Carnegie the
50 * rights to redistribute these changes.
53 #include <sys/cdefs.h>
54 __FBSDID("$FreeBSD$");
56 #include <machine/stdarg.h>
58 #include <sys/param.h>
59 #include <sys/systm.h>
60 #include <sys/kernel.h>
63 #include <sys/fcntl.h>
64 #include <sys/malloc.h>
68 #include <vm/vm_param.h>
71 #include <machine/md_var.h>
72 #include <machine/pc/bios.h>
73 #include <machine/clock.h>
74 #include <machine/bus_memio.h>
75 #include <machine/bus.h>
76 #include <machine/pc/vesa.h>
77 #include <machine/resource.h>
78 #include <machine/rpb.h>
83 #include <pci/pcireg.h>
84 #include <pci/pcivar.h>
86 #include <dev/fb/fbreg.h>
87 #include <dev/fb/gfb.h>
88 #include <dev/gfb/gfb_pci.h>
92 struct gfb_softc *gfb_device_softcs[2][MAX_NUM_GFB_CARDS] = {
94 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
95 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
98 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
99 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
104 The following 9 variables exist only because we need statically
105 allocated structures very early in boot to support gfb_configure()...
107 struct gfb_softc console;
108 video_adapter_t console_adp;
109 struct gfb_conf console_gfbc;
110 u_char console_palette_red[256];
111 u_char console_palette_green[256];
112 u_char console_palette_blue[256];
113 u_char console_cursor_palette_red[3];
114 u_char console_cursor_palette_green[3];
115 u_char console_cursor_palette_blue[3];
117 extern struct gfb_font bold8x16;
119 /*****************************************************************************
121 * FB-generic functions
123 ****************************************************************************/
126 gfb_probe(int unit, video_adapter_t **adpp, void *arg, int flags)
130 /* Assume the best... */
133 if((*adpp = vid_get_adapter(vid_find_adapter((char *)arg, unit))) == NULL)
136 (*adpp)->va_flags |= V_ADP_PROBED;
142 gfb_init(int unit, video_adapter_t *adp, int flags)
144 struct gfb_softc *sc;
145 struct gfb_conf *gfbc;
148 /* Assume the best... */
151 if(!init_done(adp)) {
152 sc = gfb_device_softcs[adp->va_model][unit];
155 /* Initialize the RAMDAC... */
156 (*gfbc->ramdac_init)(sc);
158 /* Initialize the palettes... */
159 (*gfbc->ramdac_load_palette)(sc->adp, &sc->gfbc->palette);
160 (*gfbc->ramdac_load_cursor_palette)(sc->adp,
161 &sc->gfbc->cursor_palette);
163 /* Prepare the default font... */
164 (*vidsw[adp->va_index]->load_font)(adp, 0, bold8x16.height,
165 bold8x16.data, 0, 256);
166 adp->va_info.vi_cwidth = gfbc->fonts[0].width;
167 adp->va_info.vi_cheight = gfbc->fonts[0].height;
170 Normalize vi_width and vi_height to be in terms of
171 on-screen characters, rather than pixels (*_init()
172 leaves them in terms of pixels...
174 adp->va_info.vi_width /= adp->va_info.vi_cwidth;
175 adp->va_info.vi_height /= adp->va_info.vi_cheight;
177 /* Enable the default font... */
178 (*vidsw[adp->va_index]->show_font)(adp, 0);
180 /* Enable future font-loading... */
181 adp->va_flags |= V_ADP_FONT;
183 /* Flag this initialization for this adapter... */
184 adp->va_flags |= V_ADP_INITIALIZED;
190 gfb_get_info(video_adapter_t *adp, int mode, video_info_t *info)
194 /* Assume the best... */
198 The info for GFB adapters does not depend on its mode,
199 so just copy it indiscriminantly (actually, we originally
200 checked the mode, but the current fb framework is somewhat
201 sloppily done in places, and assumes VGA in several places,
202 which makes such checks always fail for such GFBs as TGA)...
204 bcopy(&adp->va_info, info, sizeof(video_info_t));
209 gfb_set_mode(video_adapter_t *adp, int mode)
217 gfb_save_font(video_adapter_t *adp, int page, int fontsize, u_char *data,
220 struct gfb_softc *sc;
225 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
227 /* Check the font information... */
228 if((sc->gfbc->fonts[page].height != fontsize) ||
229 (sc->gfbc->fonts[page].width != 8))
234 Copy the character pixel array from our
235 very own private cache...
237 for(i = ch; i < count * fontsize; i++)
238 data[i] = adp->va_little_bitian ?
239 BIT_REVERSE(sc->gfbc->fonts[page].data[i]) :
240 sc->gfbc->fonts[page].data[i];
246 gfb_load_font(video_adapter_t *adp, int page, int fontsize, u_char *data,
249 struct gfb_softc *sc;
254 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
256 /* Copy the character pixel array into our very own private cache... */
257 for(i = ch; i < count * fontsize; i++)
258 sc->gfbc->fonts[page].data[i] = adp->va_little_bitian ?
259 BIT_REVERSE(data[i]) : data[i];
261 /* Save the font information... */
262 sc->gfbc->fonts[page].height = fontsize;
263 sc->gfbc->fonts[page].width = 8;
269 gfb_show_font(video_adapter_t *adp, int page)
271 struct gfb_softc *sc;
275 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
277 /* Normalize adapter values... */
278 adp->va_info.vi_height *= adp->va_info.vi_cheight;
279 adp->va_info.vi_width *= adp->va_info.vi_cwidth;
281 /* Set the current font pixels... */
282 sc->gfbc->font = sc->gfbc->fonts[page].data;
284 /* Set the current font width... */
285 adp->va_info.vi_cwidth = sc->gfbc->fonts[page].width;
287 /* Set the current font height... */
288 adp->va_info.vi_cheight = sc->gfbc->fonts[page].height;
290 /* Recompute adapter values... */
291 adp->va_info.vi_height /= adp->va_info.vi_cheight;
292 adp->va_info.vi_width /= adp->va_info.vi_cwidth;
298 gfb_save_palette(video_adapter_t *adp, u_char *palette)
300 struct gfb_softc *sc;
305 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
308 /* If we have a RAMDAC-specific counterpart, use it... */
309 if(sc->gfbc->ramdac_save_palette)
310 error = sc->gfbc->ramdac_save_palette(adp, &sc->gfbc->palette);
313 /* Otherwise, use the built-in functionality... */
314 error = sc->gfbc->builtin_save_palette(adp, &sc->gfbc->palette);
317 for(i = 0; i < sc->gfbc->palette.count; i++) {
318 palette[(3 * i)] = sc->gfbc->palette.red[i];
319 palette[(3 * i) + 1] = sc->gfbc->palette.green[i];
320 palette[(3 * i) + 2] = sc->gfbc->palette.blue[i];
326 gfb_load_palette(video_adapter_t *adp, u_char *palette)
328 struct gfb_softc *sc;
333 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
335 for(i = 0; i < sc->gfbc->palette.count; i++) {
336 sc->gfbc->palette.red[i] = palette[(3 * i)];
337 sc->gfbc->palette.green[i] = palette[(3 * i) + 1];
338 sc->gfbc->palette.blue[i] = palette[(3 * i) + 2];
341 /* If we have a RAMDAC-specific counterpart, use it... */
342 if(sc->gfbc->ramdac_load_palette)
343 error = sc->gfbc->ramdac_load_palette(adp, &sc->gfbc->palette);
345 /* Otherwise, use the built-in functionality... */
346 error = sc->gfbc->builtin_load_palette(adp, &sc->gfbc->palette);
352 gfb_set_border(video_adapter_t *adp, int color)
359 gfb_save_state(video_adapter_t *adp, void *p, size_t size)
364 regs = (u_int32_t *)p;
366 for(i = 1; i <= size; i++)
367 regs[i] = READ_GFB_REGISTER(adp, i);
372 gfb_load_state(video_adapter_t *adp, void *p)
378 regs = (u_int32_t *)p;
380 for(i = 1; i <= size; i++)
381 WRITE_GFB_REGISTER(adp, i, regs[i]);
386 gfb_set_win_org(video_adapter_t *adp, off_t offset)
389 adp->va_window_orig = offset;
394 gfb_read_hw_cursor(video_adapter_t *adp, int *col, int *row)
396 struct gfb_softc *sc;
399 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
401 /* If we have a RAMDAC-specific counterpart, use it... */
402 if(sc->gfbc->ramdac_read_hw_cursor)
403 error = sc->gfbc->ramdac_read_hw_cursor(adp, col, row);
405 /* Otherwise, use the built-in functionality... */
406 error = sc->gfbc->builtin_read_hw_cursor(adp, col, row);
412 gfb_set_hw_cursor(adp, col, row)
413 video_adapter_t *adp;
418 struct gfb_softc *sc;
420 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
422 /* If we have a RAMDAC-specific counterpart, use it... */
423 if(sc->gfbc->ramdac_set_hw_cursor)
424 error = sc->gfbc->ramdac_set_hw_cursor(adp, col, row);
426 /* Otherwise, use the built-in functionality... */
428 error = sc->gfbc->builtin_set_hw_cursor(adp, col, row);
433 gfb_set_hw_cursor_shape(video_adapter_t *adp, int base, int height,
434 int cellsize, int blink)
436 struct gfb_softc *sc;
439 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
441 /* If we have a RAMDAC-specific counterpart, use it... */
442 if(sc->gfbc->ramdac_set_hw_cursor_shape)
443 error = sc->gfbc->ramdac_set_hw_cursor_shape(adp, base, height,
446 /* Otherwise, use the built-in functionality... */
447 error = sc->gfbc->builtin_set_hw_cursor_shape(adp, base,
448 height, cellsize, blink);
454 gfb_mmap(video_adapter_t *adp, vm_offset_t offset, int prot)
458 if(offset > adp->va_window_size - PAGE_SIZE)
461 error = i386_btop(adp->va_info.vi_window + offset);
462 #elsif defined(__alpha__)
463 error = alpha_btop(adp->va_info.vi_window + offset);
471 gfb_ioctl(video_adapter_t *adp, u_long cmd, caddr_t arg)
473 struct gfb_softc *sc;
477 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
486 case FBIO_SETDISPSTART:
488 case FBIO_SETLINEWIDTH:
490 case FBIO_GETPALETTE:
497 error = fb_commonioctl(adp, cmd, arg);
503 gfb_fill_rect(video_adapter_t *adp, int val, int x, int y, int cx, int cy)
508 Just traverse the buffer, one pixel span at a time, setting
509 each pixel to the block-color...
511 for(off = (x * y); off < ((x + cx) * (y + cy)); off++)
512 (*vidsw[adp->va_index]->putp)(adp, off, 0x000007ff, 0xffffffff,
513 sizeof(u_int32_t), 1, 0, 0);
519 gfb_bitblt(video_adapter_t *adp, ...)
522 vm_offset_t src, dst;
528 src = (va_arg(args, vm_offset_t) + adp->va_window_orig) &
530 dst = (va_arg(args, vm_offset_t) + adp->va_window_orig) &
532 count = va_arg(args, int);
533 for(i = 0; i < count; i++, src++, dst++) {
534 val = READ_GFB_BUFFER(adp, src);
535 WRITE_GFB_BUFFER(adp, dst, val);
542 /*gfb_clear(video_adapter_t *adp, int n)*/
543 gfb_clear(video_adapter_t *adp)
553 Just traverse the buffer, one 2K-pixel span at a time, clearing
556 /* for(off = 0; off < (n * adp->va_line_width); off += (2 KB)) */
557 for(off = 0; off < adp->va_window_size; off++)
558 (*vidsw[adp->va_index]->putp)(adp, off, 0x000007ff, 0xffffffff,
559 sizeof(u_int32_t), 1, 0, 0);
565 gfb_diag(video_adapter_t *adp, int level)
568 struct gfb_softc *sc;
571 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
573 /* Just dump everything we know about the adapter to the screen... */
574 fb_dump_adp_info(sc->driver_name, adp, level);
576 /* Try to get the info on this adapter... */
577 if(!(error = (*vidsw[adp->va_index]->get_info)(adp,
578 adp->va_initial_mode, &info)))
580 Just dump everything we know about the adapter's mode
583 fb_dump_mode_info(sc->driver_name, adp, &info, level);
589 gfb_save_cursor_palette(video_adapter_t *adp, u_char *palette)
591 struct gfb_softc *sc;
595 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
598 /* If we have a RAMDAC-specific counterpart, use it... */
599 if(sc->gfbc->ramdac_save_cursor_palette)
600 error = sc->gfbc->ramdac_save_cursor_palette(adp,
601 &sc->gfbc->cursor_palette);
604 /* Otherwise, use the built-in functionality... */
605 error = sc->gfbc->builtin_save_cursor_palette(adp,
606 &sc->gfbc->cursor_palette);
609 for(i = 0; i < sc->gfbc->cursor_palette.count; i++) {
610 palette[(3 * i)] = sc->gfbc->cursor_palette.red[i];
611 palette[(3 * i) + 1] = sc->gfbc->cursor_palette.green[i];
612 palette[(3 * i) + 2] = sc->gfbc->cursor_palette.blue[i];
618 gfb_load_cursor_palette(video_adapter_t *adp, u_char *palette)
620 struct gfb_softc *sc;
624 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
626 for(i = 0; i < sc->gfbc->cursor_palette.count; i++) {
627 sc->gfbc->cursor_palette.red[i] = palette[(3 * i)];
628 sc->gfbc->cursor_palette.green[i] = palette[(3 * i) + 1];
629 sc->gfbc->cursor_palette.blue[i] = palette[(3 * i) + 2];
632 /* If we have a RAMDAC-specific counterpart, use it... */
633 if(sc->gfbc->ramdac_load_cursor_palette)
634 error = sc->gfbc->ramdac_load_cursor_palette(adp,
635 &sc->gfbc->cursor_palette);
637 /* Otherwise, use the built-in functionality... */
638 error = sc->gfbc->builtin_load_cursor_palette(adp,
639 &sc->gfbc->cursor_palette);
645 gfb_copy(video_adapter_t *adp, vm_offset_t src, vm_offset_t dst, int n)
647 int error, num_pixels;
651 num_pixels = adp->va_info.vi_cheight * adp->va_line_width;
652 error = (*vidsw[adp->va_index]->bitblt)(adp, src * num_pixels,
653 dst * num_pixels, n * num_pixels);
658 gfb_putp(video_adapter_t *adp, vm_offset_t off, u_int32_t p, u_int32_t a,
659 int size, int bpp, int bit_ltor, int byte_ltor)
661 int i, j, k, num_shifts;
662 u_int32_t _p, val[32];
668 If we don't display bits right-to-left (little-bitian?),
669 then perform a bit-swap on p...
672 num_shifts = 8 * size;
673 for(i = 0, _p = 0; i < num_shifts; i++, p >>= 1) {
675 _p |= (p & 0x00000001);
681 /* Accelerate the simplest cases... */
683 if((a & 0x00000001) == 0)
688 val[0] = _p & 0x000000ff;
690 val[0] = _p & 0x0000ffff;
692 val[0] = _p & 0x00ffffff;
694 val[0] = _p & 0xffffffff;
697 /* Only do the following if we are not a simple case... */
702 if(_p & 0x00000001) val[0] |= (a);
703 if(_p & 0x00000002) val[0] |= (a << 8);
704 if(_p & 0x00000004) val[0] |= (a << 16);
705 if(_p & 0x00000008) val[0] |= (a << 24);
707 if(_p & 0x00000010) val[1] |= (a);
708 if(_p & 0x00000020) val[1] |= (a << 8);
709 if(_p & 0x00000040) val[1] |= (a << 16);
710 if(_p & 0x00000080) val[1] |= (a << 24);
714 if(_p & 0x00000100) val[2] |= (a);
715 if(_p & 0x00000200) val[2] |= (a << 8);
716 if(_p & 0x00000400) val[2] |= (a << 16);
717 if(_p & 0x00000800) val[2] |= (a << 24);
719 if(_p & 0x00001000) val[3] |= (a);
720 if(_p & 0x00002000) val[3] |= (a << 8);
721 if(_p & 0x00004000) val[3] |= (a << 16);
722 if(_p & 0x00008000) val[3] |= (a << 24);
726 if(_p & 0x00010000) val[4] |= (a);
727 if(_p & 0x00020000) val[4] |= (a << 8);
728 if(_p & 0x00040000) val[4] |= (a << 16);
729 if(_p & 0x00080000) val[4] |= (a << 24);
731 if(_p & 0x00100000) val[5] |= (a);
732 if(_p & 0x00200000) val[5] |= (a << 8);
733 if(_p & 0x00400000) val[5] |= (a << 16);
734 if(_p & 0x00800080) val[5] |= (a << 24);
738 if(_p & 0x01000000) val[6] |= (a);
739 if(_p & 0x02000000) val[6] |= (a << 8);
740 if(_p & 0x04000000) val[6] |= (a << 16);
741 if(_p & 0x08000000) val[6] |= (a << 24);
743 if(_p & 0x10000000) val[7] |= (a);
744 if(_p & 0x20000000) val[7] |= (a << 8);
745 if(_p & 0x40000000) val[7] |= (a << 16);
746 if(_p & 0x80000000) val[7] |= (a << 24);
752 if(_p & 0x00000001) val[0] |= (a);
753 if(_p & 0x00000002) val[0] |= (a << 16);
754 if(_p & 0x00000004) val[1] |= (a);
755 if(_p & 0x00000008) val[1] |= (a << 16);
756 if(_p & 0x00000010) val[2] |= (a);
757 if(_p & 0x00000020) val[2] |= (a << 16);
758 if(_p & 0x00000040) val[3] |= (a);
759 if(_p & 0x00000080) val[3] |= (a << 16);
762 if(_p & 0x00000100) val[4] |= (a);
763 if(_p & 0x00000200) val[4] |= (a << 16);
764 if(_p & 0x00000400) val[5] |= (a);
765 if(_p & 0x00000800) val[5] |= (a << 16);
766 if(_p & 0x00001000) val[6] |= (a);
767 if(_p & 0x00002000) val[6] |= (a << 16);
768 if(_p & 0x00004000) val[7] |= (a);
769 if(_p & 0x00008000) val[7] |= (a << 16);
772 if(_p & 0x00010000) val[8] |= (a);
773 if(_p & 0x00020000) val[8] |= (a << 16);
774 if(_p & 0x00040000) val[9] |= (a);
775 if(_p & 0x00080000) val[9] |= (a << 16);
776 if(_p & 0x00100000) val[10] |= (a);
777 if(_p & 0x00200000) val[10] |= (a << 16);
778 if(_p & 0x00400000) val[11] |= (a);
779 if(_p & 0x00800000) val[11] |= (a << 16);
782 if(_p & 0x01000000) val[12] |= (a);
783 if(_p & 0x02000000) val[12] |= (a << 16);
784 if(_p & 0x04000000) val[13] |= (a);
785 if(_p & 0x08000000) val[13] |= (a << 16);
786 if(_p & 0x10000000) val[14] |= (a);
787 if(_p & 0x20000000) val[14] |= (a << 16);
788 if(_p & 0x40000000) val[15] |= (a);
789 if(_p & 0x80000000) val[15] |= (a << 16);
795 if(_p & 0x00000001) val[0] = (a);
796 if(_p & 0x00000002) val[1] = (a);
797 if(_p & 0x00000004) val[2] = (a);
798 if(_p & 0x00000008) val[3] = (a);
799 if(_p & 0x00000010) val[4] = (a);
800 if(_p & 0x00000020) val[5] = (a);
801 if(_p & 0x00000040) val[6] = (a);
802 if(_p & 0x00000080) val[7] = (a);
805 if(_p & 0x00000100) val[8] = (a);
806 if(_p & 0x00000200) val[9] = (a);
807 if(_p & 0x00000400) val[10] = (a);
808 if(_p & 0x00000800) val[11] = (a);
809 if(_p & 0x00001000) val[12] = (a);
810 if(_p & 0x00002000) val[13] = (a);
811 if(_p & 0x00004000) val[14] = (a);
812 if(_p & 0x00008000) val[15] = (a);
815 if(_p & 0x00010000) val[16] = (a);
816 if(_p & 0x00020000) val[17] = (a);
817 if(_p & 0x00040000) val[18] = (a);
818 if(_p & 0x00080000) val[19] = (a);
819 if(_p & 0x00100000) val[20] = (a);
820 if(_p & 0x00200000) val[21] = (a);
821 if(_p & 0x00400000) val[22] = (a);
822 if(_p & 0x00800000) val[23] = (a);
825 if(_p & 0x01000000) val[24] = (a);
826 if(_p & 0x02000000) val[25] = (a);
827 if(_p & 0x04000000) val[26] = (a);
828 if(_p & 0x08000000) val[27] = (a);
829 if(_p & 0x10000000) val[28] = (a);
830 if(_p & 0x20000000) val[29] = (a);
831 if(_p & 0x40000000) val[30] = (a);
832 if(_p & 0x80000000) val[31] = (a);
838 j = (bpp == 1) ? 1 : bpp * size / sizeof(u_int32_t);
841 If we don't display bytes right-to-left (little-endian),
842 then perform a byte-swap on p (we don't have to swap if
843 bpp == 1 and val[0] == 0)...
845 if((byte_ltor) && (j > 1) && (val[j] != 0)) {
846 for(i = 0; i < (j - i); i++) {
851 for(i = 0; i < j; i++) {
853 for(k = 0, val[i] = 0; k < sizeof(u_int32_t);
856 val[i] |= (_p & 0xff);
861 for(i = 0; i < j; i++) {
862 /* Write the pixel-row... */
863 WRITE_GFB_BUFFER(adp, (off + i), val[i]);
869 gfb_putc(video_adapter_t *adp, vm_offset_t off, u_int8_t c, u_int8_t a)
872 struct gfb_softc *sc;
877 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
878 pixel_size = adp->va_info.vi_depth / 8;
880 /* Get the start of the array of pixels rows for this character... */
881 pixel = sc->gfbc->font + (c * adp->va_info.vi_cheight);
883 /* Calculate the new cursor position... */
884 row = off / adp->va_info.vi_width;
885 col = off % adp->va_info.vi_width;
887 /* Iterate over all the pixel rows for this character... */
888 for(i = 0; i < adp->va_info.vi_cheight; i++) {
889 /* Get the address of the character's pixel-row... */
890 poff = ((col * adp->va_info.vi_cwidth * pixel_size) +
891 (((row * adp->va_info.vi_cheight) + i) *
892 adp->va_line_width)) / sizeof(u_int32_t);
894 /* Now display the current pixel row... */
895 (*vidsw[adp->va_index]->putp)(adp, poff, pixel[i], a,
896 sizeof(u_int8_t), 1, 1, 0);
902 gfb_puts(video_adapter_t *adp, vm_offset_t off, u_int16_t *s, int len)
904 struct gfb_softc *sc;
907 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
909 /* If the string in empty, just return now... */
913 for(i = 0; i < len; i++)
914 (*vidsw[adp->va_index]->putc)(adp, off + i, s[i] & 0x00ff,
915 (s[i] & 0xff00) >> 8);
921 gfb_putm(video_adapter_t *adp, int x, int y, u_int8_t *pixel_image,
922 u_int32_t pixel_mask, int size)
927 pixel_size = adp->va_info.vi_depth / 8;
929 /* Iterate over all the pixel rows for the mouse pointer... */
930 for(i = 0; i < size; i++) {
931 /* Get the address of the mouse pointer's pixel-row... */
932 poff = ((x * pixel_size) + ((y + i) * adp->va_line_width)) /
934 /* Now display the current pixel-row... */
935 (*vidsw[adp->va_index]->putp)(adp, poff, pixel_image[i],
936 pixel_mask, sizeof(u_int8_t), 1, 1, 0);