FreeBSD/Linux Kernel Cross Reference
sys/dev/fb/gfb.c
1 /*-
2 * Copyright (c) 2001 Andrew Miklic
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
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.
13 *
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
24 * SUCH DAMAGE.
25 */
26 /*
27 * Copyright (c) 1995, 1996 Carnegie-Mellon University.
28 * All rights reserved.
29 *
30 * Author: Chris G. Demetriou
31 *
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.
37 *
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.
41 *
42 * Carnegie Mellon requests users of this software to return to
43 *
44 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
45 * School of Computer Science
46 * Carnegie Mellon University
47 * Pittsburgh PA 15213-3890
48 *
49 * any improvements or extensions that they make and grant Carnegie the
50 * rights to redistribute these changes.
51 */
52
53 #include <sys/cdefs.h>
54 __FBSDID("$FreeBSD$");
55
56 #include <machine/stdarg.h>
57
58 #include <sys/param.h>
59 #include <sys/systm.h>
60 #include <sys/kernel.h>
61 #include <sys/conf.h>
62 #include <sys/proc.h>
63 #include <sys/fcntl.h>
64 #include <sys/malloc.h>
65 #include <sys/fbio.h>
66
67 #include <vm/vm.h>
68 #include <vm/vm_param.h>
69 #include <vm/pmap.h>
70
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>
79
80 #include <sys/bus.h>
81 #include <sys/rman.h>
82
83 #include <pci/pcireg.h>
84 #include <pci/pcivar.h>
85
86 #include <dev/fb/fbreg.h>
87 #include <dev/fb/gfb.h>
88 #include <dev/gfb/gfb_pci.h>
89
90 #include "opt_gfb.h"
91
92 struct gfb_softc *gfb_device_softcs[2][MAX_NUM_GFB_CARDS] = {
93 {
94 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
95 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
96 },
97 {
98 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
99 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
100 },
101 };
102
103 /*
104 The following 9 variables exist only because we need statically
105 allocated structures very early in boot to support gfb_configure()...
106 */
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];
116
117 extern struct gfb_font bold8x16;
118
119 /*****************************************************************************
120 *
121 * FB-generic functions
122 *
123 ****************************************************************************/
124
125 int
126 gfb_probe(int unit, video_adapter_t **adpp, void *arg, int flags)
127 {
128 int error;
129
130 /* Assume the best... */
131 error = 0;
132
133 if((*adpp = vid_get_adapter(vid_find_adapter((char *)arg, unit))) == NULL)
134 error = ENODEV;
135 else
136 (*adpp)->va_flags |= V_ADP_PROBED;
137
138 return(error);
139 }
140
141 int
142 gfb_init(int unit, video_adapter_t *adp, int flags)
143 {
144 struct gfb_softc *sc;
145 struct gfb_conf *gfbc;
146 int error;
147
148 /* Assume the best... */
149 error = 0;
150
151 if(!init_done(adp)) {
152 sc = gfb_device_softcs[adp->va_model][unit];
153 gfbc = sc->gfbc;
154
155 /* Initialize the RAMDAC... */
156 (*gfbc->ramdac_init)(sc);
157
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);
162
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;
168
169 /*
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...
173 */
174 adp->va_info.vi_width /= adp->va_info.vi_cwidth;
175 adp->va_info.vi_height /= adp->va_info.vi_cheight;
176
177 /* Enable the default font... */
178 (*vidsw[adp->va_index]->show_font)(adp, 0);
179
180 /* Enable future font-loading... */
181 adp->va_flags |= V_ADP_FONT;
182
183 /* Flag this initialization for this adapter... */
184 adp->va_flags |= V_ADP_INITIALIZED;
185 }
186 return(error);
187 }
188
189 int
190 gfb_get_info(video_adapter_t *adp, int mode, video_info_t *info)
191 {
192 int error;
193
194 /* Assume the best... */
195 error = 0;
196
197 /*
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)...
203 */
204 bcopy(&adp->va_info, info, sizeof(video_info_t));
205 return(error);
206 }
207
208 int
209 gfb_set_mode(video_adapter_t *adp, int mode)
210 {
211
212 adp->va_mode = mode;
213 return(0);
214 }
215
216 int
217 gfb_save_font(video_adapter_t *adp, int page, int fontsize, u_char *data,
218 int ch, int count)
219 {
220 struct gfb_softc *sc;
221 int error;
222 int i;
223
224 error = 0;
225 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
226
227 /* Check the font information... */
228 if((sc->gfbc->fonts[page].height != fontsize) ||
229 (sc->gfbc->fonts[page].width != 8))
230 error = EINVAL;
231 else
232
233 /*
234 Copy the character pixel array from our
235 very own private cache...
236 */
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];
241
242 return(error);
243 }
244
245 int
246 gfb_load_font(video_adapter_t *adp, int page, int fontsize, u_char *data,
247 int ch, int count)
248 {
249 struct gfb_softc *sc;
250 int error;
251 int i;
252
253 error = 0;
254 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
255
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];
260
261 /* Save the font information... */
262 sc->gfbc->fonts[page].height = fontsize;
263 sc->gfbc->fonts[page].width = 8;
264
265 return(error);
266 }
267
268 int
269 gfb_show_font(video_adapter_t *adp, int page)
270 {
271 struct gfb_softc *sc;
272 int error;
273
274 error = 0;
275 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
276
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;
280
281 /* Set the current font pixels... */
282 sc->gfbc->font = sc->gfbc->fonts[page].data;
283
284 /* Set the current font width... */
285 adp->va_info.vi_cwidth = sc->gfbc->fonts[page].width;
286
287 /* Set the current font height... */
288 adp->va_info.vi_cheight = sc->gfbc->fonts[page].height;
289
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;
293
294 return(error);
295 }
296
297 int
298 gfb_save_palette(video_adapter_t *adp, u_char *palette)
299 {
300 struct gfb_softc *sc;
301 int error;
302 int i;
303
304 error = 0;
305 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
306
307 #if 0
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);
311
312 else
313 /* Otherwise, use the built-in functionality... */
314 error = sc->gfbc->builtin_save_palette(adp, &sc->gfbc->palette);
315 #endif
316
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];
321 }
322 return(error);
323 }
324
325 int
326 gfb_load_palette(video_adapter_t *adp, u_char *palette)
327 {
328 struct gfb_softc *sc;
329 int error;
330 int i;
331
332 error = 0;
333 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
334
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];
339 }
340
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);
344 else
345 /* Otherwise, use the built-in functionality... */
346 error = sc->gfbc->builtin_load_palette(adp, &sc->gfbc->palette);
347
348 return(error);
349 }
350
351 int
352 gfb_set_border(video_adapter_t *adp, int color)
353 {
354
355 return(ENODEV);
356 }
357
358 int
359 gfb_save_state(video_adapter_t *adp, void *p, size_t size)
360 {
361 int i;
362 u_int32_t *regs;
363
364 regs = (u_int32_t *)p;
365 regs[0] = size;
366 for(i = 1; i <= size; i++)
367 regs[i] = READ_GFB_REGISTER(adp, i);
368 return(0);
369 }
370
371 int
372 gfb_load_state(video_adapter_t *adp, void *p)
373 {
374 size_t size;
375 int i;
376 u_int32_t *regs;
377
378 regs = (u_int32_t *)p;
379 size = regs[0];
380 for(i = 1; i <= size; i++)
381 WRITE_GFB_REGISTER(adp, i, regs[i]);
382 return(0);
383 }
384
385 int
386 gfb_set_win_org(video_adapter_t *adp, off_t offset)
387 {
388
389 adp->va_window_orig = offset;
390 return(0);
391 }
392
393 int
394 gfb_read_hw_cursor(video_adapter_t *adp, int *col, int *row)
395 {
396 struct gfb_softc *sc;
397 int error;
398
399 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
400
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);
404 else
405 /* Otherwise, use the built-in functionality... */
406 error = sc->gfbc->builtin_read_hw_cursor(adp, col, row);
407
408 return(error);
409 }
410
411 int
412 gfb_set_hw_cursor(adp, col, row)
413 video_adapter_t *adp;
414 int col;
415 int row;
416 {
417 int error;
418 struct gfb_softc *sc;
419
420 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
421
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);
425
426 /* Otherwise, use the built-in functionality... */
427 else
428 error = sc->gfbc->builtin_set_hw_cursor(adp, col, row);
429 return(error);
430 }
431
432 int
433 gfb_set_hw_cursor_shape(video_adapter_t *adp, int base, int height,
434 int cellsize, int blink)
435 {
436 struct gfb_softc *sc;
437 int error;
438
439 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
440
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,
444 cellsize, blink);
445 else
446 /* Otherwise, use the built-in functionality... */
447 error = sc->gfbc->builtin_set_hw_cursor_shape(adp, base,
448 height, cellsize, blink);
449
450 return(error);
451 }
452
453 int
454 gfb_mmap(video_adapter_t *adp, vm_offset_t offset, int prot)
455 {
456 int error;
457
458 if(offset > adp->va_window_size - PAGE_SIZE)
459 error = ENXIO;
460 #ifdef __i386__
461 error = i386_btop(adp->va_info.vi_window + offset);
462 #elsif defined(__alpha__)
463 error = alpha_btop(adp->va_info.vi_window + offset);
464 #else
465 error = ENXIO;
466 #endif
467 return(error);
468 }
469
470 int
471 gfb_ioctl(video_adapter_t *adp, u_long cmd, caddr_t arg)
472 {
473 struct gfb_softc *sc;
474 int error;
475
476 error = 0;
477 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
478
479 switch (cmd) {
480 case FBIOPUTCMAP:
481 /* FALLTHROUGH */
482 case FBIO_GETWINORG:
483 /* FALLTHROUGH */
484 case FBIO_SETWINORG:
485 /* FALLTHROUGH */
486 case FBIO_SETDISPSTART:
487 /* FALLTHROUGH */
488 case FBIO_SETLINEWIDTH:
489 /* FALLTHROUGH */
490 case FBIO_GETPALETTE:
491 /* FALLTHROUGH */
492 case FBIOGTYPE:
493 /* FALLTHROUGH */
494 case FBIOGETCMAP:
495 /* FALLTHROUGH */
496 default:
497 error = fb_commonioctl(adp, cmd, arg);
498 }
499 return(error);
500 }
501
502 int
503 gfb_fill_rect(video_adapter_t *adp, int val, int x, int y, int cx, int cy)
504 {
505 int off;
506
507 /*
508 Just traverse the buffer, one pixel span at a time, setting
509 each pixel to the block-color...
510 */
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);
514
515 return(0);
516 }
517
518 int
519 gfb_bitblt(video_adapter_t *adp, ...)
520 {
521 va_list args;
522 vm_offset_t src, dst;
523 int count, i;
524 u_int32_t val;
525
526 va_start(args, adp);
527
528 src = (va_arg(args, vm_offset_t) + adp->va_window_orig) &
529 0x0000000000fffff8;
530 dst = (va_arg(args, vm_offset_t) + adp->va_window_orig) &
531 0x0000000000fffff8;
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);
536 }
537 va_end(args);
538 return(0);
539 }
540
541 int
542 /*gfb_clear(video_adapter_t *adp, int n)*/
543 gfb_clear(video_adapter_t *adp)
544 video_adapter_t *adp;
545 {
546 int off;
547
548 #if 0
549 if(n == 0)
550 return(0);
551 #endif
552
553 /*
554 Just traverse the buffer, one 2K-pixel span at a time, clearing
555 each pixel...
556 */
557 /* for(off = 0; off < (n * adp->va_line_width); off += (2 KB)) */
558 for(off = 0; off < adp->va_window_size; off++)
559 (*vidsw[adp->va_index]->putp)(adp, off, 0x000007ff, 0xffffffff,
560 sizeof(u_int32_t), 1, 0, 0);
561
562 return(0);
563 }
564
565 int
566 gfb_diag(video_adapter_t *adp, int level)
567 {
568 video_info_t info;
569 struct gfb_softc *sc;
570 int error;
571
572 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
573
574 /* Just dump everything we know about the adapter to the screen... */
575 fb_dump_adp_info(sc->driver_name, adp, level);
576
577 /* Try to get the info on this adapter... */
578 if(!(error = (*vidsw[adp->va_index]->get_info)(adp,
579 adp->va_initial_mode, &info)))
580 /*
581 Just dump everything we know about the adapter's mode
582 to the screen...
583 */
584 fb_dump_mode_info(sc->driver_name, adp, &info, level);
585
586 return(error);
587 }
588
589 int
590 gfb_save_cursor_palette(video_adapter_t *adp, u_char *palette)
591 {
592 struct gfb_softc *sc;
593 int error, i;
594
595 error = 0;
596 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
597
598 #if 0
599 /* If we have a RAMDAC-specific counterpart, use it... */
600 if(sc->gfbc->ramdac_save_cursor_palette)
601 error = sc->gfbc->ramdac_save_cursor_palette(adp,
602 &sc->gfbc->cursor_palette);
603
604 else
605 /* Otherwise, use the built-in functionality... */
606 error = sc->gfbc->builtin_save_cursor_palette(adp,
607 &sc->gfbc->cursor_palette);
608 #endif
609
610 for(i = 0; i < sc->gfbc->cursor_palette.count; i++) {
611 palette[(3 * i)] = sc->gfbc->cursor_palette.red[i];
612 palette[(3 * i) + 1] = sc->gfbc->cursor_palette.green[i];
613 palette[(3 * i) + 2] = sc->gfbc->cursor_palette.blue[i];
614 }
615 return(error);
616 }
617
618 int
619 gfb_load_cursor_palette(video_adapter_t *adp, u_char *palette)
620 {
621 struct gfb_softc *sc;
622 int error, i;
623
624 error = 0;
625 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
626
627 for(i = 0; i < sc->gfbc->cursor_palette.count; i++) {
628 sc->gfbc->cursor_palette.red[i] = palette[(3 * i)];
629 sc->gfbc->cursor_palette.green[i] = palette[(3 * i) + 1];
630 sc->gfbc->cursor_palette.blue[i] = palette[(3 * i) + 2];
631 }
632
633 /* If we have a RAMDAC-specific counterpart, use it... */
634 if(sc->gfbc->ramdac_load_cursor_palette)
635 error = sc->gfbc->ramdac_load_cursor_palette(adp,
636 &sc->gfbc->cursor_palette);
637 else
638 /* Otherwise, use the built-in functionality... */
639 error = sc->gfbc->builtin_load_cursor_palette(adp,
640 &sc->gfbc->cursor_palette);
641
642 return(error);
643 }
644
645 int
646 gfb_copy(video_adapter_t *adp, vm_offset_t src, vm_offset_t dst, int n)
647 {
648 int error, num_pixels;
649
650 if(n == 0)
651 return(0);
652 num_pixels = adp->va_info.vi_cheight * adp->va_line_width;
653 error = (*vidsw[adp->va_index]->bitblt)(adp, src * num_pixels,
654 dst * num_pixels, n * num_pixels);
655 return(error);
656 }
657
658 int
659 gfb_putp(video_adapter_t *adp, vm_offset_t off, u_int32_t p, u_int32_t a,
660 int size, int bpp, int bit_ltor, int byte_ltor)
661 {
662 int i, j, k, num_shifts;
663 u_int32_t _p, val[32];
664
665 if(bpp < 1)
666 return(-1);
667
668 /*
669 If we don't display bits right-to-left (little-bitian?),
670 then perform a bit-swap on p...
671 */
672 if(bit_ltor) {
673 num_shifts = 8 * size;
674 for(i = 0, _p = 0; i < num_shifts; i++, p >>= 1) {
675 _p <<= 1;
676 _p |= (p & 0x00000001);
677 }
678 } else
679 _p = p;
680
681 switch(bpp) {
682 /* Accelerate the simplest cases... */
683 case 1:
684 if((a & 0x00000001) == 0)
685 val[0] = 0;
686 else if(size <= 0)
687 val[0] = 0;
688 else if(size == 1)
689 val[0] = _p & 0x000000ff;
690 else if(size == 2)
691 val[0] = _p & 0x0000ffff;
692 else if(size == 3)
693 val[0] = _p & 0x00ffffff;
694 else if(size == 4)
695 val[0] = _p & 0xffffffff;
696 break;
697
698 /* Only do the following if we are not a simple case... */
699 case 8:
700 if(size > 0) {
701 a &= 0x000000ff;
702 val[0] = 0;
703 if(_p & 0x00000001) val[0] |= (a);
704 if(_p & 0x00000002) val[0] |= (a << 8);
705 if(_p & 0x00000004) val[0] |= (a << 16);
706 if(_p & 0x00000008) val[0] |= (a << 24);
707 val[1] = 0;
708 if(_p & 0x00000010) val[1] |= (a);
709 if(_p & 0x00000020) val[1] |= (a << 8);
710 if(_p & 0x00000040) val[1] |= (a << 16);
711 if(_p & 0x00000080) val[1] |= (a << 24);
712 }
713 if(size > 1) {
714 val[2] = 0;
715 if(_p & 0x00000100) val[2] |= (a);
716 if(_p & 0x00000200) val[2] |= (a << 8);
717 if(_p & 0x00000400) val[2] |= (a << 16);
718 if(_p & 0x00000800) val[2] |= (a << 24);
719 val[3] = 0;
720 if(_p & 0x00001000) val[3] |= (a);
721 if(_p & 0x00002000) val[3] |= (a << 8);
722 if(_p & 0x00004000) val[3] |= (a << 16);
723 if(_p & 0x00008000) val[3] |= (a << 24);
724 }
725 if(size > 2) {
726 val[4] = 0;
727 if(_p & 0x00010000) val[4] |= (a);
728 if(_p & 0x00020000) val[4] |= (a << 8);
729 if(_p & 0x00040000) val[4] |= (a << 16);
730 if(_p & 0x00080000) val[4] |= (a << 24);
731 val[5] = 0;
732 if(_p & 0x00100000) val[5] |= (a);
733 if(_p & 0x00200000) val[5] |= (a << 8);
734 if(_p & 0x00400000) val[5] |= (a << 16);
735 if(_p & 0x00800080) val[5] |= (a << 24);
736 }
737 if(size > 3) {
738 val[6] = 0;
739 if(_p & 0x01000000) val[6] |= (a);
740 if(_p & 0x02000000) val[6] |= (a << 8);
741 if(_p & 0x04000000) val[6] |= (a << 16);
742 if(_p & 0x08000000) val[6] |= (a << 24);
743 val[7] = 0;
744 if(_p & 0x10000000) val[7] |= (a);
745 if(_p & 0x20000000) val[7] |= (a << 8);
746 if(_p & 0x40000000) val[7] |= (a << 16);
747 if(_p & 0x80000000) val[7] |= (a << 24);
748 }
749 break;
750 case 16:
751 if(size > 0) {
752 a &= 0x0000ffff;
753 if(_p & 0x00000001) val[0] |= (a);
754 if(_p & 0x00000002) val[0] |= (a << 16);
755 if(_p & 0x00000004) val[1] |= (a);
756 if(_p & 0x00000008) val[1] |= (a << 16);
757 if(_p & 0x00000010) val[2] |= (a);
758 if(_p & 0x00000020) val[2] |= (a << 16);
759 if(_p & 0x00000040) val[3] |= (a);
760 if(_p & 0x00000080) val[3] |= (a << 16);
761 }
762 if(size > 1) {
763 if(_p & 0x00000100) val[4] |= (a);
764 if(_p & 0x00000200) val[4] |= (a << 16);
765 if(_p & 0x00000400) val[5] |= (a);
766 if(_p & 0x00000800) val[5] |= (a << 16);
767 if(_p & 0x00001000) val[6] |= (a);
768 if(_p & 0x00002000) val[6] |= (a << 16);
769 if(_p & 0x00004000) val[7] |= (a);
770 if(_p & 0x00008000) val[7] |= (a << 16);
771 }
772 if(size > 2) {
773 if(_p & 0x00010000) val[8] |= (a);
774 if(_p & 0x00020000) val[8] |= (a << 16);
775 if(_p & 0x00040000) val[9] |= (a);
776 if(_p & 0x00080000) val[9] |= (a << 16);
777 if(_p & 0x00100000) val[10] |= (a);
778 if(_p & 0x00200000) val[10] |= (a << 16);
779 if(_p & 0x00400000) val[11] |= (a);
780 if(_p & 0x00800000) val[11] |= (a << 16);
781 }
782 if(size > 3) {
783 if(_p & 0x01000000) val[12] |= (a);
784 if(_p & 0x02000000) val[12] |= (a << 16);
785 if(_p & 0x04000000) val[13] |= (a);
786 if(_p & 0x08000000) val[13] |= (a << 16);
787 if(_p & 0x10000000) val[14] |= (a);
788 if(_p & 0x20000000) val[14] |= (a << 16);
789 if(_p & 0x40000000) val[15] |= (a);
790 if(_p & 0x80000000) val[15] |= (a << 16);
791 }
792 break;
793 case 32:
794 if(size > 0) {
795 a &= 0xffffffff;
796 if(_p & 0x00000001) val[0] = (a);
797 if(_p & 0x00000002) val[1] = (a);
798 if(_p & 0x00000004) val[2] = (a);
799 if(_p & 0x00000008) val[3] = (a);
800 if(_p & 0x00000010) val[4] = (a);
801 if(_p & 0x00000020) val[5] = (a);
802 if(_p & 0x00000040) val[6] = (a);
803 if(_p & 0x00000080) val[7] = (a);
804 }
805 if(size > 1) {
806 if(_p & 0x00000100) val[8] = (a);
807 if(_p & 0x00000200) val[9] = (a);
808 if(_p & 0x00000400) val[10] = (a);
809 if(_p & 0x00000800) val[11] = (a);
810 if(_p & 0x00001000) val[12] = (a);
811 if(_p & 0x00002000) val[13] = (a);
812 if(_p & 0x00004000) val[14] = (a);
813 if(_p & 0x00008000) val[15] = (a);
814 }
815 if(size > 2) {
816 if(_p & 0x00010000) val[16] = (a);
817 if(_p & 0x00020000) val[17] = (a);
818 if(_p & 0x00040000) val[18] = (a);
819 if(_p & 0x00080000) val[19] = (a);
820 if(_p & 0x00100000) val[20] = (a);
821 if(_p & 0x00200000) val[21] = (a);
822 if(_p & 0x00400000) val[22] = (a);
823 if(_p & 0x00800000) val[23] = (a);
824 }
825 if(size > 3) {
826 if(_p & 0x01000000) val[24] = (a);
827 if(_p & 0x02000000) val[25] = (a);
828 if(_p & 0x04000000) val[26] = (a);
829 if(_p & 0x08000000) val[27] = (a);
830 if(_p & 0x10000000) val[28] = (a);
831 if(_p & 0x20000000) val[29] = (a);
832 if(_p & 0x40000000) val[30] = (a);
833 if(_p & 0x80000000) val[31] = (a);
834 }
835 break;
836 default:
837 break;
838 }
839 j = (bpp == 1) ? 1 : bpp * size / sizeof(u_int32_t);
840
841 /*
842 If we don't display bytes right-to-left (little-endian),
843 then perform a byte-swap on p (we don't have to swap if
844 bpp == 1 and val[0] == 0)...
845 */
846 if((byte_ltor) && (j > 1) && (val[j] != 0)) {
847 for(i = 0; i < (j - i); i++) {
848 _p = val[j - i];
849 val[j - i] = val[i];
850 val[i] = _p;
851 }
852 for(i = 0; i < j; i++) {
853 _p = val[i];
854 for(k = 0, val[i] = 0; k < sizeof(u_int32_t);
855 k++, _p >>= 8) {
856 val[i] <<= 8;
857 val[i] |= (_p & 0xff);
858 }
859 }
860 }
861
862 for(i = 0; i < j; i++) {
863 /* Write the pixel-row... */
864 WRITE_GFB_BUFFER(adp, (off + i), val[i]);
865 }
866 return(0);
867 }
868
869 int
870 gfb_putc(video_adapter_t *adp, vm_offset_t off, u_int8_t c, u_int8_t a)
871 {
872 vm_offset_t poff;
873 struct gfb_softc *sc;
874 int i, pixel_size;
875 u_int row, col;
876 u_int8_t *pixel;
877
878 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
879 pixel_size = adp->va_info.vi_depth / 8;
880
881 /* Get the start of the array of pixels rows for this character... */
882 pixel = sc->gfbc->font + (c * adp->va_info.vi_cheight);
883
884 /* Calculate the new cursor position... */
885 row = off / adp->va_info.vi_width;
886 col = off % adp->va_info.vi_width;
887
888 /* Iterate over all the pixel rows for this character... */
889 for(i = 0; i < adp->va_info.vi_cheight; i++) {
890 /* Get the address of the character's pixel-row... */
891 poff = ((col * adp->va_info.vi_cwidth * pixel_size) +
892 (((row * adp->va_info.vi_cheight) + i) *
893 adp->va_line_width)) / sizeof(u_int32_t);
894
895 /* Now display the current pixel row... */
896 (*vidsw[adp->va_index]->putp)(adp, poff, pixel[i], a,
897 sizeof(u_int8_t), 1, 1, 0);
898 }
899 return(0);
900 }
901
902 int
903 gfb_puts(video_adapter_t *adp, vm_offset_t off, u_int16_t *s, int len)
904 {
905 struct gfb_softc *sc;
906 int i;
907
908 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
909
910 /* If the string in empty, just return now... */
911 if(len == 0)
912 return(0);
913
914 for(i = 0; i < len; i++)
915 (*vidsw[adp->va_index]->putc)(adp, off + i, s[i] & 0x00ff,
916 (s[i] & 0xff00) >> 8);
917
918 return(0);
919 }
920
921 int
922 gfb_putm(video_adapter_t *adp, int x, int y, u_int8_t *pixel_image,
923 u_int32_t pixel_mask, int size)
924 {
925 vm_offset_t poff;
926 int i, pixel_size;
927
928 pixel_size = adp->va_info.vi_depth / 8;
929
930 /* Iterate over all the pixel rows for the mouse pointer... */
931 for(i = 0; i < size; i++) {
932 /* Get the address of the mouse pointer's pixel-row... */
933 poff = ((x * pixel_size) + ((y + i) * adp->va_line_width)) /
934 sizeof(u_int32_t);
935 /* Now display the current pixel-row... */
936 (*vidsw[adp->va_index]->putp)(adp, poff, pixel_image[i],
937 pixel_mask, sizeof(u_int8_t), 1, 1, 0);
938 }
939
940 return(0);
941 }
942
943 int
944 gfb_error(void)
945 {
946
947 return(0);
948 }
Cache object: cdcafa578f31adcc21a48d72efd24c63
|