amidisplaycc.c revision 1.1 1 /*-
2 * Copyright (c) 2000 Jukka Andberg.
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 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 /*
29 * wscons interface to amiga custom chips. Contains the necessary functions
30 * to render text on bitmapped screens. Uses the functions defined in
31 * grfabs_reg.h for display creation/destruction and low level setup.
32 */
33
34 #include "amidisplaycc.h"
35 #include "grfcc.h"
36 #include "view.h"
37
38 #if NAMIDISPLAYCC>0
39
40 #include <sys/param.h>
41 #include <sys/types.h>
42 #include <sys/device.h>
43 #include <sys/malloc.h>
44 #include <sys/systm.h>
45
46 #include <sys/conf.h>
47
48 #include <amiga/dev/grfabs_reg.h>
49 #include <amiga/dev/viewioctl.h>
50 #include <amiga/amiga/device.h>
51 #include <dev/wscons/wsconsio.h>
52 #include <dev/rcons/raster.h>
53 #include <dev/wscons/wscons_raster.h>
54 #include <dev/wscons/wsdisplayvar.h>
55 #include <dev/cons.h>
56
57 struct amidisplaycc_softc
58 {
59 struct device dev;
60 };
61
62
63 /*
64 * Configuration stuff.
65 */
66
67 static int amidisplaycc_match __P((struct device *,
68 struct cfdata *,
69 void *));
70 static void amidisplaycc_attach __P((struct device *,
71 struct device *,
72 void *));
73
74 struct cfattach amidisplaycc_ca = {
75 sizeof(struct amidisplaycc_softc),
76 amidisplaycc_match,
77 amidisplaycc_attach
78 };
79
80 cons_decl(amidisplaycc_);
81
82 /* end of configuration stuff */
83
84 /* These can be lowered if you are sure you dont need that much colors. */
85 #define MAXDEPTH 8
86 #define MAXCOLORS (1<<MAXDEPTH)
87 #define MAXROWS 128
88
89 /* Perform validity checking on parameters on some functions? */
90 #define PARANOIA
91
92 #define ADJUSTCOLORS
93
94 /* emulops for wscons */
95 void amidisplaycc_cursor __P(( void *, int, int, int ));
96 int amidisplaycc_mapchar __P(( void *, int, unsigned int * ));
97 void amidisplaycc_putchar __P(( void *, int, int, u_int, long ));
98 void amidisplaycc_copycols __P(( void *, int, int, int, int ));
99 void amidisplaycc_erasecols __P(( void *, int, int, int, long ));
100 void amidisplaycc_copyrows __P(( void *, int, int, int ));
101 void amidisplaycc_eraserows __P(( void *, int, int, long ));
102 int amidisplaycc_alloc_attr __P(( void *, int, int, int, long * ));
103 /* end of emulops for wscons */
104
105 /* accessops for wscons */
106 int amidisplaycc_ioctl __P(( void *, u_long, caddr_t,
107 int, struct proc * ));
108 paddr_t amidisplaycc_mmap __P(( void *, off_t, int ));
109 int amidisplaycc_alloc_screen __P(( void *,
110 const struct wsscreen_descr *,
111 void **, int *, int *, long * ));
112
113 void amidisplaycc_free_screen __P(( void *, void * ));
114 int amidisplaycc_show_screen __P(( void *, void *, int,
115 void (*) (void *, int, int),
116 void * ));
117 int amidisplaycc_load_font __P(( void *, void *,
118 struct wsdisplay_font * ));
119 /* end of accessops for wscons */
120
121 /*
122 * These structures are passed to wscons, and they contain the
123 * display-specific callback functions.
124 */
125
126 const struct wsdisplay_accessops amidisplaycc_accessops = {
127 amidisplaycc_ioctl,
128 amidisplaycc_mmap,
129 amidisplaycc_alloc_screen,
130 amidisplaycc_free_screen,
131 amidisplaycc_show_screen,
132 amidisplaycc_load_font
133 };
134
135 const struct wsdisplay_emulops amidisplaycc_emulops = {
136 amidisplaycc_cursor,
137 amidisplaycc_mapchar,
138 amidisplaycc_putchar,
139 amidisplaycc_copycols,
140 amidisplaycc_erasecols,
141 amidisplaycc_copyrows,
142 amidisplaycc_eraserows,
143 amidisplaycc_alloc_attr
144 };
145
146 /* add some of our own data to the wsscreen_descr */
147 struct amidisplaycc_screen_descr {
148 struct wsscreen_descr wsdescr;
149 int depth;
150 };
151
152 /*
153 * List of supported screenmodes. Almost anything can be given here.
154 */
155
156 #define ADCC_SCREEN(width,height,depth) { {#width "x" #height "x" #depth, width/8, height/8, &amidisplaycc_emulops, 8, 8, WSSCREEN_WSCOLORS|WSSCREEN_REVERSE|WSSCREEN_HILIT|WSSCREEN_UNDERLINE},depth }
157
158 struct amidisplaycc_screen_descr amidisplaycc_screentab[] = {
159 ADCC_SCREEN(640,400,1),
160 ADCC_SCREEN(640,400,2),
161 ADCC_SCREEN(640,400,3),
162 ADCC_SCREEN(640,400,4),
163
164 ADCC_SCREEN(640,200,1),
165 ADCC_SCREEN(640,200,2),
166 ADCC_SCREEN(640,200,3),
167 ADCC_SCREEN(640,200,4),
168
169 ADCC_SCREEN(640,480,1),
170 ADCC_SCREEN(640,480,2),
171 ADCC_SCREEN(640,480,3),
172 ADCC_SCREEN(640,480,4),
173 };
174
175 #define ADCC_SCREENPTR(index) &amidisplaycc_screentab[index].wsdescr
176 const struct wsscreen_descr *amidisplaycc_screens[] = {
177 ADCC_SCREENPTR(0),
178 ADCC_SCREENPTR(1),
179 ADCC_SCREENPTR(2),
180 ADCC_SCREENPTR(3),
181 ADCC_SCREENPTR(4),
182 ADCC_SCREENPTR(5),
183 ADCC_SCREENPTR(6),
184 ADCC_SCREENPTR(7),
185 ADCC_SCREENPTR(8),
186 ADCC_SCREENPTR(9),
187 ADCC_SCREENPTR(10),
188 ADCC_SCREENPTR(11)
189 };
190
191 /*
192 * This structure also is passed to wscons. It contains pointers
193 * to the available display modes.
194 */
195
196 const struct wsscreen_list amidisplaycc_screenlist = {
197 sizeof(amidisplaycc_screens)/sizeof(amidisplaycc_screens[0]),
198 amidisplaycc_screens
199 };
200
201 /*
202 * Our own screen structure. One will be created for each screen.
203 */
204
205 struct amidisplaycc_screen
206 {
207 int isconsole;
208 int isvisible;
209 view_t *view;
210
211 int ncols;
212 int nrows;
213
214 /*
215 * For each row store which bitplanes contain
216 * data (just optimisation)
217 */
218 int rowmasks[MAXROWS];
219
220 /* Mapping of colors to screen colors. Currently mostly unused. */
221 int colormap[MAXCOLORS];
222
223 int fontheight;
224 };
225
226 typedef struct amidisplaycc_screen adccscr_t;
227
228 /*
229 * Need one statically allocated screen for early init.
230 * The rest are mallocated when needed.
231 */
232 adccscr_t amidisplaycc_consolescreen;
233
234
235 /*
236 * This gets called at console init to determine the priority of
237 * this console device.
238 *
239 * Of course pointers to this and other functions must present
240 * in constab[] in conf.c for this to work.
241 */
242 void
243 amidisplaycc_cnprobe(cd)
244 struct consdev *cd;
245 {
246 cd->cn_pri = CN_INTERNAL;
247
248 /*
249 * Yeah, real nice. But if we win the console then the wscons system
250 * does the proper initialization.
251 */
252 cd->cn_dev = NODEV;
253 }
254
255 /*
256 * This gets called if this device is used as the console.
257 */
258 void
259 amidisplaycc_cninit(cd)
260 struct consdev *cd;
261 {
262 int x,y;
263 void *cookie;
264 long attr;
265
266 /* Yeah, we got the console! */
267
268 /*
269 * This will do the basic stuff we also need.
270 */
271 config_console();
272
273 /*
274 * Call the init function in grfabs.c if we have
275 * no grfcc to do it.
276 * If grfcc is present it will call grfcc_probe()
277 * during config_console() above.
278 */
279 #if NGRFCC==0
280 grfcc_probe();
281 #endif
282
283 #if NVIEW>0
284 viewprobe();
285 #endif
286
287 /*
288 * Set up wscons to handle the details.
289 * It will then call us back when it needs something
290 * display-specific. It will also set up cn_tab properly,
291 * something which we failed to do at amidisplaycc_cnprobe().
292 */
293
294 amidisplaycc_alloc_screen(NULL, &amidisplaycc_screentab[0].wsdescr,
295 &cookie, &x, &y, &attr);
296 wsdisplay_cnattach(&amidisplaycc_screentab[0].wsdescr,
297 cookie, x, y, attr);
298 }
299
300 int
301 amidisplaycc_match(pdp,cfp,auxp)
302 struct device *pdp;
303 struct cfdata *cfp;
304 void *auxp;
305 {
306 char *name = auxp;
307
308 if (matchname("amidisplaycc",name)==0)
309 return (0);
310
311 /* Allow only one of us now. Not sure about that. */
312 if (cfp->cf_unit != 0)
313 return (0);
314
315 return 1;
316 }
317
318 void
319 amidisplaycc_attach(pdp,dp,auxp)
320 struct device *pdp;
321 struct device *dp;
322 void *auxp;
323 {
324 struct wsemuldisplaydev_attach_args waa;
325
326 /*
327 * Attach only at real configuration time. Console init is done at
328 * the amidisplaycc_cninit function above.
329 */
330 if (dp) {
331 printf("\n");
332
333 waa.console = 1;
334 waa.scrdata = &amidisplaycc_screenlist;
335 waa.accessops = &amidisplaycc_accessops;
336 waa.accesscookie = NULL;
337 config_found(dp,&waa,wsemuldisplaydevprint);
338 }
339 }
340
341
342 /*
343 * Color, bgcolor and style are packed into one long attribute.
344 * These macros are used to create/split the attribute
345 */
346
347 #define MAKEATTR(fg, bg, mode) (((fg)<<16) | ((bg)<<8) | (mode))
348 #define ATTRFG(attr) (((attr)>>16) & 255)
349 #define ATTRBG(attr) (((attr)>>8) & 255)
350 #define ATTRMO(attr) ((attr) & 255)
351
352 /*
353 * Called by wscons to draw/clear the cursor.
354 * We do this by xorring the block to the screen.
355 *
356 * This simple implementation will break if the screen is modified
357 * under the cursor before clearing it.
358 */
359 void
360 amidisplaycc_cursor(screen, on, row, col)
361 void *screen;
362 int on;
363 int row;
364 int col;
365 {
366 adccscr_t *scr;
367 u_char *plane;
368 int y;
369 int miny;
370 int maxy;
371
372 scr = screen;
373
374 #ifdef PARANOIA
375 if (row < 0 || col < 0 || row >= scr->nrows || col >= scr->ncols)
376 return;
377 #endif
378
379 miny = row * scr->fontheight;
380 maxy = miny + scr->fontheight;
381
382 for (y = miny ; y < maxy ; y++) {
383 plane = col + VDISPLAY_LINE(scr->view, 0, y);
384 *plane ^= 255;
385 }
386
387 }
388
389 /*
390 * This obviously does something important, don't ask me what.
391 */
392 int
393 amidisplaycc_mapchar(screen, ch, chp)
394 void *screen;
395 int ch;
396 unsigned int *chp;
397 {
398 if (ch > 0 && ch < 256) {
399 *chp = ch;
400 return (5);
401 }
402 *chp = ' ';
403 return (0);
404 }
405
406 extern unsigned char kernel_font_8x8[];
407
408 /* Write a character to screen with color / bgcolor / hilite(bold) /
409 * underline / inverse.
410 * Surely could be made faster but I'm not sure if its worth the
411 * effort as scrolling is at least a magnitude slower.
412 */
413 void
414 amidisplaycc_putchar(screen, row, col, ch, attr)
415 void *screen;
416 int row;
417 int col;
418 u_int ch;
419 long attr;
420 {
421 bmap_t *bitmap;
422 u_char *dst;
423 adccscr_t *scr;
424 u_char *font;
425 u_char f;
426 int j;
427 int fgcolor;
428 int bgcolor;
429 int plane;
430 int depth;
431 int rowsize;
432 int fontoffset;
433 int bmapoffset;
434 int mode;
435 int bold;
436 int underline;
437
438 scr = screen;
439
440 #ifdef PARANOIA
441 if (row < 0 || col < 0 || row >= scr->nrows || col >= scr->ncols)
442 return;
443 #endif
444
445 bitmap = scr->view->bitmap;
446 depth = bitmap->depth;
447 rowsize = bitmap->bytes_per_row + bitmap->row_mod;
448
449 /* Extract the colors from the attribute */
450 fgcolor = ATTRFG(attr);
451 bgcolor = ATTRBG(attr);
452 mode = ATTRMO(attr);
453
454 /* Translate to screen colors */
455 fgcolor = scr->colormap[fgcolor];
456 bgcolor = scr->colormap[bgcolor];
457
458 if(mode & WSATTR_REVERSE) {
459 j = fgcolor;
460 fgcolor = bgcolor;
461 bgcolor = j;
462 }
463
464 if (mode & WSATTR_HILIT)
465 bold = 1;
466 else
467 bold = 0;
468
469
470 if (mode & WSATTR_UNDERLINE)
471 underline = 1;
472 else
473 underline = 0;
474
475
476 if (ch < 32)
477 ch = 32;
478 if (ch > 255)
479 ch = 255;
480
481
482 fontoffset = scr->fontheight * (ch - 32);
483 bmapoffset = row * scr->fontheight * rowsize + col;
484
485 scr->rowmasks[row] |= fgcolor | bgcolor;
486
487 for (plane = 0 ; plane < depth ; plane++) {
488 dst = bitmap->plane[plane] + bmapoffset;
489
490 if (fgcolor & 1) {
491 if (bgcolor & 1) {
492 /* fg=on bg=on (fill) */
493
494 for (j = 0 ; j < scr->fontheight ; j++)
495 {
496 *dst = 255;
497 dst += rowsize;
498 }
499 } else {
500 /* fg=on bg=off (normal) */
501
502 font = &kernel_font_8x8[fontoffset];
503 for (j = 0 ; j < scr->fontheight ; j++)
504 {
505 f = *(font++);
506 f |= f>>bold;
507 *dst = f;
508 dst += rowsize;
509 }
510
511 /* XXX underline does not recognise baseline */
512 if (underline)
513 *(dst-rowsize) = 255;
514 }
515 } else {
516 if (bgcolor & 1) {
517 /* fg=off bg=on (inverted) */
518
519 font = &kernel_font_8x8[fontoffset];
520 for (j = 0 ; j < scr->fontheight ; j++) {
521 f = *(font++);
522 f |= f>>bold;
523 *dst = ~f;
524 dst += rowsize;
525 }
526
527 /* XXX underline does not recognise baseline */
528 if (underline)
529 *(dst-rowsize) = 0;
530 } else {
531 /* fg=off bg=off (clear) */
532
533 for (j = 0 ; j < scr->fontheight ; j++) {
534 *dst = 0;
535 dst += rowsize;
536 }
537 }
538 }
539 fgcolor >>= 1;
540 bgcolor >>= 1;
541 }
542 }
543
544
545 void
546 amidisplaycc_copycols(screen, row, srccol, dstcol, ncols)
547 void *screen;
548 int row;
549 int srccol;
550 int dstcol;
551 int ncols;
552 {
553 bmap_t *bitmap;
554 adccscr_t *scr;
555 int depth;
556 int i;
557 int j;
558 int plane;
559 int rowsize;
560 u_char *buf;
561
562 scr = screen;
563
564 #ifdef PARANOIA
565 if (srccol < 0 || srccol + ncols > scr->ncols ||
566 dstcol < 0 || dstcol + ncols > scr->ncols ||
567 row < 0 || row >= scr->nrows)
568 return;
569 #endif
570
571 bitmap = scr->view->bitmap;
572 depth = bitmap->depth;
573 rowsize = bitmap->bytes_per_row + bitmap->row_mod;
574
575 for (plane = 0 ; plane < depth ; plane++) {
576 buf = bitmap->plane[plane] + row*scr->fontheight*rowsize;
577
578 for (j = 0 ; j < scr->fontheight ; j++) {
579
580 if (srccol < dstcol) {
581
582 for (i = ncols - 1 ; i >= 0 ; i--)
583 buf[dstcol + i] = buf[srccol + i];
584
585 } else {
586
587 for (i = 0 ; i < ncols ; i++)
588 buf[dstcol + i] = buf[srccol + i];
589
590 }
591 buf += rowsize;
592 }
593 }
594 }
595
596 void
597 amidisplaycc_erasecols(screen, row, startcol, ncols, attr)
598 void *screen;
599 int row;
600 int startcol;
601 int ncols;
602 long attr;
603 {
604 bmap_t *bitmap;
605 adccscr_t *scr;
606 u_char *buf;
607 int depth;
608 int j;
609 int plane;
610 int rowsize;
611 int fill;
612 int bgcolor;
613
614 scr = screen;
615
616 #ifdef PARANOIA
617 if (row < 0 || row >= scr->nrows ||
618 startcol < 0 || startcol + ncols > scr->ncols)
619 return;
620 #endif
621
622 bitmap = scr->view->bitmap;
623 depth = bitmap->depth;
624 rowsize = bitmap->bytes_per_row + bitmap->row_mod;
625
626 bgcolor = ATTRBG(attr);
627 bgcolor = scr->colormap[bgcolor];
628
629 for(plane = 0 ; plane < depth ; plane++) {
630
631 fill = (bgcolor & 1) ? 255 : 0;
632
633 buf = bitmap->plane[plane];
634 buf += row * scr->fontheight * rowsize;
635 buf += startcol;
636
637 for (j = 0 ; j < scr->fontheight ; j++)
638 {
639 memset(buf, fill, ncols);
640 buf += rowsize;
641 }
642 }
643 }
644
645 void
646 amidisplaycc_copyrows(screen, srcrow, dstrow, nrows)
647 void *screen;
648 int srcrow;
649 int dstrow;
650 int nrows;
651 {
652 bmap_t *bitmap;
653 adccscr_t *scr;
654 u_char *src;
655 u_char *dst;
656
657 int depth;
658 int plane;
659 int i;
660 int j;
661 int rowmod;
662 int bytesperrow;
663 int rowsize;
664 int srcmask;
665 int dstmask;
666 int srcbmapoffset;
667 int dstbmapoffset;
668 int copysize;
669 int bmdelta;
670 int rowdelta;
671 int bmwidth;
672
673 scr = screen;
674
675 #ifdef PARANOIA
676 if (srcrow < 0 || srcrow + nrows > scr->nrows ||
677 dstrow < 0 || dstrow + nrows > scr->nrows)
678 return;
679 #endif
680
681 bitmap = scr->view->bitmap;
682 depth = bitmap->depth;
683 rowmod = bitmap->row_mod;
684 bytesperrow = bitmap->bytes_per_row;
685 bmwidth = bytesperrow+rowmod;
686 rowsize = bmwidth*scr->fontheight;
687
688 srcbmapoffset = rowsize*srcrow;
689 dstbmapoffset = rowsize*dstrow;
690
691 if (srcrow < dstrow) {
692 /* Move data downwards, need to copy from down to up */
693 bmdelta = -rowsize;
694 rowdelta = -1;
695
696 srcbmapoffset += rowsize * (nrows - 1);
697 srcrow += nrows - 1;
698
699 dstbmapoffset += rowsize * (nrows - 1);
700 dstrow += nrows - 1;
701 } else {
702 /* Move data upwards, copy up to down */
703 bmdelta = rowsize;
704 rowdelta = 1;
705 }
706
707 if (rowmod == 0)
708 copysize = rowsize;
709 else
710 copysize = 0;
711
712 for (j = 0 ; j < nrows ; j++) {
713 /* Need to copy only planes that have data on src or dst */
714 srcmask = scr->rowmasks[srcrow];
715 dstmask = scr->rowmasks[dstrow];
716 scr->rowmasks[dstrow] = srcmask;
717
718 for (plane = 0 ; plane < depth ; plane++) {
719
720 if (srcmask & 1) {
721 /*
722 * Source row has data on this
723 * plane, copy it
724 */
725
726 src = bitmap->plane[plane] + srcbmapoffset;
727 dst = bitmap->plane[plane] + dstbmapoffset;
728
729 if (copysize > 0) {
730
731 /* Do it all */
732 memcpy(dst,src,copysize);
733
734 } else {
735
736 /*
737 * Data not continuous,
738 * must do in pieces
739 */
740 for (i=0 ; i < scr->fontheight ; i++) {
741 memcpy(dst, src, bytesperrow);
742
743 src += bmwidth;
744 dst += bmwidth;
745 }
746 }
747 } else if (dstmask & 1) {
748 /*
749 * Source plane is empty, but dest is not.
750 * so all we need to is clear it.
751 */
752
753 dst = bitmap->plane[plane] + dstbmapoffset;
754
755 if (copysize > 0) {
756 /* Do it all */
757 bzero(dst, copysize);
758 } else {
759 for (i = 0 ;
760 i < scr->fontheight ; i++) {
761 bzero(dst, bytesperrow);
762 dst += bmwidth;
763 }
764 }
765 }
766
767 srcmask >>= 1;
768 dstmask >>= 1;
769 }
770 srcbmapoffset += bmdelta;
771 dstbmapoffset += bmdelta;
772
773 srcrow += rowdelta;
774 dstrow += rowdelta;
775 }
776 }
777
778 void
779 amidisplaycc_eraserows(screen, row, nrows, attr)
780 void *screen;
781 int row;
782 int nrows;
783 long attr;
784 {
785 bmap_t *bitmap;
786 adccscr_t *scr;
787 int depth;
788 int plane;
789 int j;
790 int bytesperrow;
791 int rowmod;
792 int rowsize;
793 int bmwidth;
794 int bgcolor;
795 int fill;
796 int bmapoffset;
797 int fillsize;
798 u_char *dst;
799
800 scr = screen;
801
802 #ifdef PARANOIA
803 if (row < 0 || row + nrows > scr->nrows)
804 return;
805 #endif
806
807 bitmap = scr->view->bitmap;
808 depth = bitmap->depth;
809 bytesperrow = bitmap->bytes_per_row;
810 rowmod = bitmap->row_mod;
811 bmwidth = bytesperrow + rowmod;
812 rowsize = bmwidth * scr->fontheight;
813 bmapoffset = row * rowsize;
814
815 if (rowmod == 0)
816 fillsize = rowsize * nrows;
817 else
818 fillsize = 0;
819
820 bgcolor = ATTRBG(attr);
821 bgcolor = scr->colormap[bgcolor];
822
823 for (j = 0 ; j < nrows ; j++)
824 scr->rowmasks[row+j] = bgcolor;
825
826 for (plane = 0 ; plane < depth ; plane++) {
827 dst = bitmap->plane[plane] + bmapoffset;
828 fill = (bgcolor & 1) ? 255 : 0;
829
830 if (fillsize > 0) {
831 /* If the rows are continuous, write them all. */
832 memset(dst, fill, fillsize);
833 } else {
834 for (j = 0 ; j < scr->fontheight * nrows ; j++) {
835 memset(dst, fill, bytesperrow);
836 dst += bmwidth;
837 }
838 }
839 bgcolor >>= 1;
840 }
841 }
842
843 int
844 amidisplaycc_alloc_attr(screen, fg, bg, flags, attrp)
845 void *screen;
846 int fg;
847 int bg;
848 int flags;
849 long *attrp;
850 {
851 adccscr_t *scr;
852 int maxcolor;
853 int newfg;
854 int newbg;
855
856 scr = screen;
857 maxcolor = (1 << scr->view->bitmap->depth) - 1;
858
859 /* Ensure the colors are displayable. */
860 newfg = fg & maxcolor;
861 newbg = bg & maxcolor;
862
863 #ifdef ADJUSTCOLORS
864 /*
865 * Hack for low-color screens, if background color is nonzero
866 * but would be displayed as one, adjust it.
867 */
868 if (bg > 0 && newbg == 0)
869 newbg = maxcolor;
870
871 /*
872 * If foreground and background colors are different but would
873 * display the same fix them by modifying the foreground.
874 */
875 if (fg != bg && newfg == newbg) {
876 if (newbg > 0)
877 newfg = 0;
878 else
879 newfg = maxcolor;
880 }
881 #endif
882 *attrp = MAKEATTR(newfg, newbg, flags);
883
884 return (0);
885 }
886
887 int
888 amidisplaycc_ioctl(dp, cmd, data, flag, p)
889 void *dp;
890 u_long cmd;
891 caddr_t data;
892 int flag;
893 struct proc *p;
894 {
895 switch (cmd)
896 {
897 case WSDISPLAYIO_GTYPE:
898 *(u_int*)data = WSDISPLAY_TYPE_EGA; /* XXX */
899 return (0);
900 }
901
902 printf("amidisplaycc_ioctl %lx (grp:'%c' num:%d)\n",
903 (long)cmd,
904 (char)((cmd&0xff00)>>8),
905 (int)(cmd&0xff));
906
907 /* Yes, think should return -1 if didnt understand. */
908 return (-1);
909 }
910
911 paddr_t
912 amidisplaycc_mmap(dp, off, prot)
913 void *dp;
914 off_t off;
915 int prot;
916 {
917 return (-1);
918 }
919
920 int
921 amidisplaycc_alloc_screen(dp, screenp, cookiep, curxp, curyp, defattrp)
922 void *dp;
923 const struct wsscreen_descr *screenp;
924 void **cookiep;
925 int *curxp;
926 int *curyp;
927 long *defattrp;
928 {
929 dimen_t dimension;
930 adccscr_t *scr;
931 view_t *view;
932 struct amidisplaycc_screen_descr *adccscreenp;
933 int depth;
934 int maxcolor;
935 int i;
936 int j;
937
938 adccscreenp = (struct amidisplaycc_screen_descr*)screenp;
939 depth = adccscreenp->depth;
940
941 maxcolor = (1 << depth) - 1;
942
943 /* Sanity checks because of fixed buffers */
944 if (depth > MAXDEPTH || maxcolor >= MAXCOLORS)
945 return (ENOMEM);
946 if (screenp->nrows > MAXROWS)
947 return (ENOMEM);
948
949 dimension.width = screenp->ncols * 8;
950 dimension.height = screenp->nrows * 8;
951
952 view = grf_alloc_view(NULL, &dimension, depth);
953 if (view == NULL)
954 return (ENOMEM);
955
956 /*
957 * First screen gets the statically allocated console screen.
958 * Others are allocated dynamically.
959 */
960 if (amidisplaycc_consolescreen.isconsole == 0) {
961 scr = &amidisplaycc_consolescreen;
962 scr->isconsole = 1;
963 } else {
964 scr = malloc(sizeof(adccscr_t), M_DEVBUF, M_WAITOK);
965 bzero(scr, sizeof(adccscr_t));
966 }
967
968 scr->view = view;
969 scr->fontheight = 8;
970
971 scr->ncols = screenp->ncols;
972 scr->nrows = screenp->nrows;
973
974 for (i = 0 ; i < MAXROWS ; i++)
975 scr->rowmasks[i] = 0;
976
977 /* Simple one-to-one mapping for most colors */
978 for (i = 0 ; i < MAXCOLORS ; i++)
979 scr->colormap[i] = i;
980
981 /*
982 * Arrange the most used pens to quickest colors.
983 * The default color for given depth is (1<<depth)-1.
984 * It is assumed it is used most and it is mapped to
985 * color that can be drawn by writing data to one bitplane
986 * only.
987 * So map colors 3->2, 7->4, 15->8 and so on.
988 * This of course should be reflected on the palette
989 * but currently we don't do any palette management.
990 */
991 for (i = 2 ; i < MAXCOLORS ; i *= 2) {
992 j = i * 2 - 1;
993
994 if (j < MAXCOLORS) {
995 scr->colormap[i] = j;
996 scr->colormap[j] = i;
997 }
998 }
999
1000 *cookiep = scr;
1001
1002 *curxp = 0;
1003 *curyp = 0;
1004 amidisplaycc_cursor(scr, 1, *curxp, *curyp);
1005
1006 *defattrp = MAKEATTR(maxcolor, 0, 0);
1007
1008 /* Show the console automatically */
1009 if (scr->isconsole)
1010 grf_display_view(scr->view);
1011
1012 return (0);
1013 }
1014
1015 void
1016 amidisplaycc_free_screen(dp, screen)
1017 void *dp;
1018 void *screen;
1019 {
1020 adccscr_t *scr;
1021
1022 scr = screen;
1023
1024 if (scr == NULL)
1025 return;
1026
1027 if (scr->view)
1028 grf_free_view(scr->view);
1029 scr->view = NULL;
1030
1031 /* Take care not to free the statically allocated console screen */
1032 if (scr != &amidisplaycc_consolescreen) {
1033 free(scr, M_DEVBUF);
1034 }
1035 }
1036
1037 int
1038 amidisplaycc_show_screen(dp, screen, waitok, cb, cbarg)
1039 void *dp;
1040 void *screen;
1041 int waitok;
1042 void (*cb) (void *, int, int);
1043 void *cbarg;
1044 {
1045 adccscr_t *scr;
1046
1047 scr = screen;
1048 grf_display_view(scr->view);
1049
1050 return (0);
1051 }
1052
1053 /*
1054 * Load a font. Not supported yet.
1055 */
1056 int
1057 amidisplaycc_load_font(dp, cookie, fontp)
1058 void *dp;
1059 void *cookie;
1060 struct wsdisplay_font *fontp;
1061 {
1062 return (-1);
1063 }
1064
1065 /*
1066 * These dummy functions are here just so that we can compete of
1067 * the console at init.
1068 * If we win the console then the wscons system will provide the
1069 * real ones which in turn will call the apropriate wskbd device.
1070 * These should never be called.
1071 */
1072
1073 void
1074 amidisplaycc_cnputc(cd,ch)
1075 dev_t cd;
1076 int ch;
1077 {
1078 }
1079
1080 int
1081 amidisplaycc_cngetc(cd)
1082 dev_t cd;
1083 {
1084 return (0);
1085 }
1086
1087 void
1088 amidisplaycc_cnpollc(cd,on)
1089 dev_t cd;
1090 int on;
1091 {
1092 }
1093
1094 #endif /* AMIDISPLAYCC */
1095
1096
1097
1098
1099