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: releng/5.0/sys/dev/fb/gfb.c 94617 2002-04-13 22:34:16Z obrien $");
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 {
545 int off;
546
547 #if 0
548 if(n == 0)
549 return(0);
550 #endif
551
552 /*
553 Just traverse the buffer, one 2K-pixel span at a time, clearing
554 each pixel...
555 */
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);
560
561 return(0);
562 }
563
564 int
565 gfb_diag(video_adapter_t *adp, int level)
566 {
567 video_info_t info;
568 struct gfb_softc *sc;
569 int error;
570
571 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
572
573 /* Just dump everything we know about the adapter to the screen... */
574 fb_dump_adp_info(sc->driver_name, adp, level);
575
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)))
579 /*
580 Just dump everything we know about the adapter's mode
581 to the screen...
582 */
583 fb_dump_mode_info(sc->driver_name, adp, &info, level);
584
585 return(error);
586 }
587
588 int
589 gfb_save_cursor_palette(video_adapter_t *adp, u_char *palette)
590 {
591 struct gfb_softc *sc;
592 int error, i;
593
594 error = 0;
595 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
596
597 #if 0
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);
602
603 else
604 /* Otherwise, use the built-in functionality... */
605 error = sc->gfbc->builtin_save_cursor_palette(adp,
606 &sc->gfbc->cursor_palette);
607 #endif
608
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];
613 }
614 return(error);
615 }
616
617 int
618 gfb_load_cursor_palette(video_adapter_t *adp, u_char *palette)
619 {
620 struct gfb_softc *sc;
621 int error, i;
622
623 error = 0;
624 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
625
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];
630 }
631
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);
636 else
637 /* Otherwise, use the built-in functionality... */
638 error = sc->gfbc->builtin_load_cursor_palette(adp,
639 &sc->gfbc->cursor_palette);
640
641 return(error);
642 }
643
644 int
645 gfb_copy(video_adapter_t *adp, vm_offset_t src, vm_offset_t dst, int n)
646 {
647 int error, num_pixels;
648
649 if(n == 0)
650 return(0);
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);
654 return(error);
655 }
656
657 int
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)
660 {
661 int i, j, k, num_shifts;
662 u_int32_t _p, val[32];
663
664 if(bpp < 1)
665 return(-1);
666
667 /*
668 If we don't display bits right-to-left (little-bitian?),
669 then perform a bit-swap on p...
670 */
671 if(bit_ltor) {
672 num_shifts = 8 * size;
673 for(i = 0, _p = 0; i < num_shifts; i++, p >>= 1) {
674 _p <<= 1;
675 _p |= (p & 0x00000001);
676 }
677 } else
678 _p = p;
679
680 switch(bpp) {
681 /* Accelerate the simplest cases... */
682 case 1:
683 if((a & 0x00000001) == 0)
684 val[0] = 0;
685 else if(size <= 0)
686 val[0] = 0;
687 else if(size == 1)
688 val[0] = _p & 0x000000ff;
689 else if(size == 2)
690 val[0] = _p & 0x0000ffff;
691 else if(size == 3)
692 val[0] = _p & 0x00ffffff;
693 else if(size == 4)
694 val[0] = _p & 0xffffffff;
695 break;
696
697 /* Only do the following if we are not a simple case... */
698 case 8:
699 if(size > 0) {
700 a &= 0x000000ff;
701 val[0] = 0;
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);
706 val[1] = 0;
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);
711 }
712 if(size > 1) {
713 val[2] = 0;
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);
718 val[3] = 0;
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);
723 }
724 if(size > 2) {
725 val[4] = 0;
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);
730 val[5] = 0;
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);
735 }
736 if(size > 3) {
737 val[6] = 0;
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);
742 val[7] = 0;
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);
747 }
748 break;
749 case 16:
750 if(size > 0) {
751 a &= 0x0000ffff;
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);
760 }
761 if(size > 1) {
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);
770 }
771 if(size > 2) {
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);
780 }
781 if(size > 3) {
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);
790 }
791 break;
792 case 32:
793 if(size > 0) {
794 a &= 0xffffffff;
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);
803 }
804 if(size > 1) {
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);
813 }
814 if(size > 2) {
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);
823 }
824 if(size > 3) {
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);
833 }
834 break;
835 default:
836 break;
837 }
838 j = (bpp == 1) ? 1 : bpp * size / sizeof(u_int32_t);
839
840 /*
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)...
844 */
845 if((byte_ltor) && (j > 1) && (val[j] != 0)) {
846 for(i = 0; i < (j - i); i++) {
847 _p = val[j - i];
848 val[j - i] = val[i];
849 val[i] = _p;
850 }
851 for(i = 0; i < j; i++) {
852 _p = val[i];
853 for(k = 0, val[i] = 0; k < sizeof(u_int32_t);
854 k++, _p >>= 8) {
855 val[i] <<= 8;
856 val[i] |= (_p & 0xff);
857 }
858 }
859 }
860
861 for(i = 0; i < j; i++) {
862 /* Write the pixel-row... */
863 WRITE_GFB_BUFFER(adp, (off + i), val[i]);
864 }
865 return(0);
866 }
867
868 int
869 gfb_putc(video_adapter_t *adp, vm_offset_t off, u_int8_t c, u_int8_t a)
870 {
871 vm_offset_t poff;
872 struct gfb_softc *sc;
873 int i, pixel_size;
874 u_int row, col;
875 u_int8_t *pixel;
876
877 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
878 pixel_size = adp->va_info.vi_depth / 8;
879
880 /* Get the start of the array of pixels rows for this character... */
881 pixel = sc->gfbc->font + (c * adp->va_info.vi_cheight);
882
883 /* Calculate the new cursor position... */
884 row = off / adp->va_info.vi_width;
885 col = off % adp->va_info.vi_width;
886
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);
893
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);
897 }
898 return(0);
899 }
900
901 int
902 gfb_puts(video_adapter_t *adp, vm_offset_t off, u_int16_t *s, int len)
903 {
904 struct gfb_softc *sc;
905 int i;
906
907 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
908
909 /* If the string in empty, just return now... */
910 if(len == 0)
911 return(0);
912
913 for(i = 0; i < len; i++)
914 (*vidsw[adp->va_index]->putc)(adp, off + i, s[i] & 0x00ff,
915 (s[i] & 0xff00) >> 8);
916
917 return(0);
918 }
919
920 int
921 gfb_putm(video_adapter_t *adp, int x, int y, u_int8_t *pixel_image,
922 u_int32_t pixel_mask, int size)
923 {
924 vm_offset_t poff;
925 int i, pixel_size;
926
927 pixel_size = adp->va_info.vi_depth / 8;
928
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)) /
933 sizeof(u_int32_t);
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);
937 }
938
939 return(0);
940 }
941
942 int
943 gfb_error(void)
944 {
945
946 return(0);
947 }
Cache object: 624e09212d12d9abf6745434c859da92
|