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