ite_cc.c revision 1.26 1 /* $NetBSD: ite_cc.c,v 1.26 1999/03/25 21:55:17 is Exp $ */
2
3 /*
4 * Copyright (c) 1994 Christian E. Hopps
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Christian E. Hopps.
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 #include "opt_amigaccgrf.h"
34
35 #include "grfcc.h"
36 #if NGRFCC > 0
37
38 #include <sys/param.h>
39 #include <sys/conf.h>
40 #include <sys/proc.h>
41 #include <sys/device.h>
42 #include <sys/ioctl.h>
43 #include <sys/tty.h>
44 #include <sys/systm.h>
45 #include <sys/queue.h>
46 #include <sys/termios.h>
47 #include <dev/cons.h>
48 #include <machine/cpu.h>
49 #include <amiga/dev/itevar.h>
50 #include <amiga/dev/iteioctl.h>
51 #include <amiga/amiga/cc.h>
52 #include <amiga/amiga/device.h>
53 #include <amiga/dev/grfabs_reg.h>
54 #include <amiga/dev/grfioctl.h>
55 #include <amiga/dev/grfvar.h>
56 #include <amiga/dev/grf_ccreg.h>
57 #include <amiga/dev/viewioctl.h>
58 #include <amiga/dev/viewvar.h>
59
60 #ifndef KFONT_CUSTOM
61 #ifdef KFONT_8X11
62 #define kernel_font_width kernel_font_width_8x11
63 #define kernel_font_height kernel_font_height_8x11
64 #define kernel_font_baseline kernel_font_baseline_8x11
65 #define kernel_font_boldsmear kernel_font_boldsmear_8x11
66 #define kernel_font_lo kernel_font_lo_8x11
67 #define kernel_font_hi kernel_font_hi_8x11
68 #define kernel_font kernel_font_8x11
69 #define kernel_cursor kernel_cursor_8x11
70 #else
71 #define kernel_font_width kernel_font_width_8x8
72 #define kernel_font_height kernel_font_height_8x8
73 #define kernel_font_baseline kernel_font_baseline_8x8
74 #define kernel_font_boldsmear kernel_font_boldsmear_8x8
75 #define kernel_font_lo kernel_font_lo_8x8
76 #define kernel_font_hi kernel_font_hi_8x8
77 #define kernel_font kernel_font_8x8
78 #define kernel_cursor kernel_cursor_8x8
79 #endif
80 #endif
81
82 extern u_char kernel_font_width, kernel_font_height, kernel_font_baseline;
83 extern short kernel_font_boldsmear;
84 extern u_char kernel_font_lo, kernel_font_hi;
85 extern u_char kernel_font[], kernel_cursor[];
86
87 /*
88 * This is what ip->priv points to;
89 * it contains local variables for custom-chip ites.
90 */
91 struct ite_priv {
92 view_t *view; /* the view for this ite. */
93 u_char **row_ptr; /* array of pointers into the bitmap */
94 u_long row_bytes;
95 u_long cursor_opt;
96 u_int *column_offset; /* array of offsets for columns */
97 u_int row_offset; /* the row offset */
98 u_short width; /* the bitmap width */
99 u_short underline; /* where the underline goes */
100 u_short ft_x; /* the font width */
101 u_short ft_y; /* the font height */
102 u_char *font_cell[256]; /* the font pointer */
103 };
104 typedef struct ite_priv ipriv_t;
105
106 void view_deinit __P((struct ite_softc *));
107 void view_init __P((struct ite_softc *));
108
109 static void putc8 __P((struct ite_softc *, int, int, int, int));
110 static void clear8 __P((struct ite_softc *, int, int, int, int));
111 static void scroll8 __P((struct ite_softc *, int, int, int, int));
112 static void cursor32 __P((struct ite_softc *, int));
113 static void scrollbmap __P((bmap_t *, u_short, u_short, u_short, u_short,
114 short, short, u_char));
115
116 /* patchable */
117 int ite_default_x = 0; /* def leftedge offset */
118 int ite_default_y = 0; /* def topedge offset */
119 int ite_default_width = 640; /* def width */
120 int ite_default_depth = 2; /* def depth */
121 #if defined (GRF_NTSC)
122 int ite_default_height = 400; /* def NTSC height */
123 #elif defined (GRF_PAL)
124 int ite_default_height = 512; /* def PAL height */
125 #else
126 int ite_default_height = 400; /* def NON-PAL/NTSC height (?) */
127 #endif
128
129 int ite_newsize __P((struct ite_softc *, struct itewinsize *));
130 static void putc_nm __P((ipriv_t *, u_char *, u_char *, u_int, u_int,
131 u_int, u_int));
132 static void putc_in __P((ipriv_t *, u_char *, u_char *, u_int, u_int,
133 u_int, u_int));
134 static void putc_ul __P((ipriv_t *, u_char *, u_char *, u_int, u_int,
135 u_int, u_int));
136 static void putc_ul_in __P((ipriv_t *, u_char *, u_char *, u_int, u_int,
137 u_int, u_int));
138 static void putc_bd __P((ipriv_t *, u_char *, u_char *, u_int, u_int,
139 u_int, u_int));
140 static void putc_bd_in __P((ipriv_t *, u_char *, u_char *, u_int, u_int,
141 u_int, u_int));
142 static void putc_bd_ul __P((ipriv_t *, u_char *, u_char *, u_int, u_int,
143 u_int, u_int));
144 static void putc_bd_ul_in __P((ipriv_t *, u_char *, u_char *, u_int, u_int,
145 u_int, u_int));
146
147 /*
148 * called from grf_cc to return console priority
149 */
150 int
151 grfcc_cnprobe()
152 {
153 return(CN_INTERNAL);
154 }
155
156 /*
157 * called from grf_cc to init ite portion of
158 * grf_softc struct
159 */
160 void
161 grfcc_iteinit(gp)
162 struct grf_softc *gp;
163 {
164 gp->g_itecursor = cursor32;
165 gp->g_iteputc = putc8;
166 gp->g_iteclear = clear8;
167 gp->g_itescroll = scroll8;
168 gp->g_iteinit = view_init;
169 gp->g_itedeinit = view_deinit;
170 }
171
172 int
173 ite_newsize(ip, winsz)
174 struct ite_softc *ip;
175 struct itewinsize *winsz;
176 {
177 extern struct view_softc views[];
178 struct view_size vs;
179 ipriv_t *cci = ip->priv;
180 u_long i;
181 int error;
182
183 vs.x = winsz->x;
184 vs.y = winsz->y;
185 vs.width = winsz->width;
186 vs.height = winsz->height;
187 vs.depth = winsz->depth;
188 error = viewioctl(0, VIOCSSIZE, (caddr_t)&vs, -1, NULL); /* XXX type of vs ? */
189
190 /*
191 * Reinitialize our structs
192 */
193 cci->view = views[0].view;
194
195 /* -1 for bold. */
196 ip->cols = (cci->view->display.width - 1) / ip->ftwidth;
197 ip->rows = cci->view->display.height / ip->ftheight;
198
199 /*
200 * save new values so that future opens use them
201 * this may not be correct when we implement Virtual Consoles
202 */
203 ite_default_height = cci->view->display.height;
204 ite_default_width = cci->view->display.width;
205 ite_default_x = cci->view->display.x;
206 ite_default_y = cci->view->display.y;
207 ite_default_depth = cci->view->bitmap->depth;
208
209 if (cci->row_ptr)
210 free_chipmem(cci->row_ptr);
211 if (cci->column_offset)
212 free_chipmem(cci->column_offset);
213
214 cci->row_ptr = alloc_chipmem(sizeof(u_char *) * ip->rows);
215 cci->column_offset = alloc_chipmem(sizeof(u_int) * ip->cols);
216
217 if (cci->row_ptr == NULL || cci->column_offset == NULL)
218 panic("no chipmem for itecc data");
219
220
221 cci->width = cci->view->bitmap->bytes_per_row << 3;
222 cci->underline = ip->ftbaseline + 1;
223 cci->row_offset = cci->view->bitmap->bytes_per_row
224 + cci->view->bitmap->row_mod;
225 cci->ft_x = ip->ftwidth;
226 cci->ft_y = ip->ftheight;
227
228 cci->row_bytes = cci->row_offset * ip->ftheight;
229
230 cci->row_ptr[0] = VDISPLAY_LINE (cci->view, 0, 0);
231 for (i = 1; i < ip->rows; i++)
232 cci->row_ptr[i] = cci->row_ptr[i-1] + cci->row_bytes;
233
234 /* initialize the column offsets */
235 cci->column_offset[0] = 0;
236 for (i = 1; i < ip->cols; i++)
237 cci->column_offset[i] = cci->column_offset[i - 1] + cci->ft_x;
238
239 /* initialize the font cell pointers */
240 cci->font_cell[ip->font_lo] = ip->font;
241 for (i=ip->font_lo+1; i<=ip->font_hi; i++)
242 cci->font_cell[i] = cci->font_cell[i-1] + ip->ftheight;
243
244 return (error);
245 }
246
247 void
248 view_init(ip)
249 register struct ite_softc *ip;
250 {
251 struct itewinsize wsz;
252 ipriv_t *cci;
253
254 cci = ip->priv;
255
256 if (cci)
257 return;
258
259 ip->font = kernel_font;
260 ip->font_lo = kernel_font_lo;
261 ip->font_hi = kernel_font_hi;
262 ip->ftwidth = kernel_font_width;
263 ip->ftheight = kernel_font_height;
264 ip->ftbaseline = kernel_font_baseline;
265 ip->ftboldsmear = kernel_font_boldsmear;
266
267 /* Find the correct set of rendering routines for this font. */
268 if (ip->ftwidth > 8)
269 panic("kernel font size not supported");
270 cci = alloc_chipmem(sizeof (*cci));
271 if (cci == NULL)
272 panic("no memory for console device.");
273
274 ip->priv = cci;
275 cci->cursor_opt = 0;
276 cci->view = NULL;
277 cci->row_ptr = NULL;
278 cci->column_offset = NULL;
279
280 wsz.x = ite_default_x;
281 wsz.y = ite_default_y;
282 wsz.width = ite_default_width;
283 wsz.height = ite_default_height;
284 wsz.depth = ite_default_depth;
285
286 ite_newsize (ip, &wsz);
287 cc_mode(ip->grf, GM_GRFON, NULL, 0, 0);
288 }
289
290 int
291 ite_grf_ioctl (ip, cmd, addr, flag, p)
292 struct ite_softc *ip;
293 u_long cmd;
294 caddr_t addr;
295 int flag;
296 struct proc *p;
297 {
298 struct winsize ws;
299 struct itewinsize *is;
300 ipriv_t *cci;
301 int error;
302
303 cci = ip->priv;
304 error = 0;
305
306 switch (cmd) {
307 case ITEIOCGWINSZ:
308 is = (struct itewinsize *)addr;
309 is->x = cci->view->display.x;
310 is->y = cci->view->display.y;
311 is->width = cci->view->display.width;
312 is->height = cci->view->display.height;
313 is->depth = cci->view->bitmap->depth;
314 break;
315 case ITEIOCSWINSZ:
316 is = (struct itewinsize *)addr;
317
318 if (ite_newsize(ip, is))
319 error = ENOMEM;
320 else {
321 ws.ws_row = ip->rows;
322 ws.ws_col = ip->cols;
323 ws.ws_xpixel = cci->view->display.width;
324 ws.ws_ypixel = cci->view->display.height;
325 ite_reset (ip);
326 /*
327 * XXX tell tty about the change
328 * XXX this is messy, but works
329 */
330 iteioctl(0, TIOCSWINSZ, (caddr_t)&ws, 0, p);
331 }
332 break;
333 case ITEIOCDSPWIN:
334 cc_mode(ip->grf, GM_GRFON, NULL, 0, 0);
335 break;
336 case ITEIOCREMWIN:
337 cc_mode(ip->grf, GM_GRFOFF, NULL, 0, 0);
338 break;
339 case VIOCSCMAP:
340 case VIOCGCMAP:
341 /*
342 * XXX needs to be fixed when multiple console implemented
343 * XXX watchout for that -1 its not really the kernel talking
344 * XXX these two commands don't use the proc pointer though
345 */
346 error = viewioctl(0, cmd, addr, -1, p);
347 break;
348 default:
349 error = -1;
350 break;
351 }
352 return (error);
353 }
354
355 void
356 view_deinit(ip)
357 struct ite_softc *ip;
358 {
359 ip->flags &= ~ITE_INITED;
360 }
361
362 /*** (M<8)-by-N routines ***/
363
364 static void
365 cursor32(struct ite_softc *ip, int flag)
366 {
367 int cend, ofs, h, cstart, dr_plane;
368 u_char *pl;
369 ipriv_t *cci;
370 bmap_t *bm;
371 view_t *v;
372
373 cci = ip->priv;
374 v = cci->view;
375 bm = v->bitmap;
376 dr_plane = (bm->depth > 1 ? bm->depth-1 : 0);
377
378 if (flag == END_CURSOROPT)
379 cci->cursor_opt--;
380 else if (flag == START_CURSOROPT) {
381 if (!cci->cursor_opt)
382 cursor32 (ip, ERASE_CURSOR);
383 cci->cursor_opt++;
384 return; /* if we are already opted. */
385 }
386
387 if (cci->cursor_opt)
388 return; /* if we are still nested. */
389 /* else we draw the cursor. */
390 cstart = 0;
391 cend = ip->ftheight-1;
392 pl = VDISPLAY_LINE(v, dr_plane, (ip->cursory * ip->ftheight + cstart));
393 ofs = (ip->cursorx * ip->ftwidth);
394
395 if (flag != DRAW_CURSOR && flag != END_CURSOROPT) {
396 /*
397 * erase the cursor
398 */
399 int h;
400
401 if (dr_plane) {
402 for (h = cend; h >= 0; h--) {
403 asm("bfclr %0@{%1:%2}" : : "a" (pl),
404 "d" (ofs), "d" (ip->ftwidth));
405 pl += cci->row_offset;
406 }
407 } else {
408 for (h = cend; h >= 0; h--) {
409 asm("bfchg %0@{%1:%2}" : : "a" (pl),
410 "d" (ofs), "d" (ip->ftwidth));
411 pl += cci->row_offset;
412 }
413 }
414 }
415
416 if (flag != DRAW_CURSOR && flag != MOVE_CURSOR &&
417 flag != END_CURSOROPT)
418 return;
419
420 /*
421 * draw the cursor
422 */
423
424 ip->cursorx = min(ip->curx, ip->cols-1);
425 ip->cursory = ip->cury;
426 cstart = 0;
427 cend = ip->ftheight-1;
428 pl = VDISPLAY_LINE(v, dr_plane, ip->cursory * ip->ftheight + cstart);
429 ofs = ip->cursorx * ip->ftwidth;
430
431 if (dr_plane) {
432 for (h = cend; h >= 0; h--) {
433 asm("bfset %0@{%1:%2}" : : "a" (pl),
434 "d" (ofs), "d" (ip->ftwidth));
435 pl += cci->row_offset;
436 }
437 } else {
438 for (h = cend; h >= 0; h--) {
439 asm("bfchg %0@{%1:%2}" : : "a" (pl),
440 "d" (ofs), "d" (ip->ftwidth));
441 pl += cci->row_offset;
442 }
443 }
444 }
445
446
447 static inline
448 int expbits (int data)
449 {
450 int i, nd = 0;
451
452 if (data & 1)
453 nd |= 0x02;
454 for (i=1; i < 32; i++) {
455 if (data & (1 << i))
456 nd |= 0x5 << (i-1);
457 }
458 nd &= ~data;
459 return(~nd);
460 }
461
462
463 /* Notes: optimizations given the kernel_font_(width|height) #define'd.
464 * the dbra loops could be elminated and unrolled using height,
465 * the :width in the bfxxx instruction could be made immediate instead
466 * of a data register as it now is.
467 * the underline could be added when the loop is unrolled
468 *
469 * It would look like hell but be very fast.*/
470
471 static void
472 putc_nm (cci,p,f,co,ro,fw,fh)
473 register ipriv_t *cci;
474 register u_char *p;
475 register u_char *f;
476 register u_int co;
477 register u_int ro;
478 register u_int fw;
479 register u_int fh;
480 {
481 while (fh--) {
482 asm ("bfins %0,%1@{%2:%3}" : /* no output */ :
483 "d" (*f++), "a" (p), "d" (co), "d" (fw));
484 p += ro;
485 }
486 }
487
488 static void
489 putc_in (cci,p,f,co,ro,fw,fh)
490 register ipriv_t *cci;
491 register u_char *p;
492 register u_char *f;
493 register u_int co;
494 register u_int ro;
495 register u_int fw;
496 register u_int fh;
497 {
498 while (fh--) {
499 asm ("bfins %0,%1@{%2:%3}" : /* no output */ :
500 "d" (~(*f++)), "a" (p), "d" (co), "d" (fw));
501 p += ro;
502 }
503 }
504
505
506 static void
507 putc_ul (cci,p,f,co,ro,fw,fh)
508 register ipriv_t *cci;
509 register u_char *p;
510 register u_char *f;
511 register u_int co;
512 register u_int ro;
513 register u_int fw;
514 register u_int fh;
515 {
516 int underline = cci->underline;
517 while (underline--) {
518 asm ("bfins %0,%1@{%2:%3}" : /* no output */ :
519 "d" (*f++), "a" (p), "d" (co), "d" (fw));
520 p += ro;
521 }
522
523 asm ("bfins %0,%1@{%2:%3}" : /* no output */ :
524 "d" (expbits(*f++)), "a" (p), "d" (co), "d" (fw));
525 p += ro;
526
527 underline = fh - cci->underline - 1;
528 while (underline--) {
529 asm ("bfins %0,%1@{%2:%3}" : /* no output */ :
530 "d" (*f++), "a" (p), "d" (co), "d" (fw));
531 p += ro;
532 }
533 }
534
535
536 static void
537 putc_ul_in (cci,p,f,co,ro,fw,fh)
538 register ipriv_t *cci;
539 register u_char *p;
540 register u_char *f;
541 register u_int co;
542 register u_int ro;
543 register u_int fw;
544 register u_int fh;
545 {
546 int underline = cci->underline;
547 while (underline--) {
548 asm ("bfins %0,%1@{%2:%3}" : /* no output */ :
549 "d" (~(*f++)), "a" (p), "d" (co), "d" (fw));
550 p += ro;
551 }
552
553 asm ("bfins %0,%1@{%2:%3}" : /* no output */ :
554 "d" (~expbits(*f++)), "a" (p), "d" (co), "d" (fw));
555 p += ro;
556
557 underline = fh - cci->underline - 1;
558 while (underline--) {
559 asm ("bfins %0,%1@{%2:%3}" : /* no output */ :
560 "d" (~(*f++)), "a" (p), "d" (co), "d" (fw));
561 p += ro;
562 }
563 }
564
565 /* bold */
566 static void
567 putc_bd (cci,p,f,co,ro,fw,fh)
568 register ipriv_t *cci;
569 register u_char *p;
570 register u_char *f;
571 register u_int co;
572 register u_int ro;
573 register u_int fw;
574 register u_int fh;
575 {
576 u_short ch;
577
578 while (fh--) {
579 ch = *f++;
580 ch |= ch << 1;
581 asm ("bfins %0,%1@{%2:%3}" : /* no output */ :
582 "d" (ch), "a" (p), "d" (co), "d" (fw+1));
583 p += ro;
584 }
585 }
586
587 static void
588 putc_bd_in (cci,p,f,co,ro,fw,fh)
589 register ipriv_t *cci;
590 register u_char *p;
591 register u_char *f;
592 register u_int co;
593 register u_int ro;
594 register u_int fw;
595 register u_int fh;
596 {
597 u_short ch;
598
599 while (fh--) {
600 ch = *f++;
601 ch |= ch << 1;
602 asm ("bfins %0,%1@{%2:%3}" : /* no output */ :
603 "d" (~(ch)), "a" (p), "d" (co), "d" (fw+1));
604 p += ro;
605 }
606 }
607
608
609 static void
610 putc_bd_ul (cci,p,f,co,ro,fw,fh)
611 register ipriv_t *cci;
612 register u_char *p;
613 register u_char *f;
614 register u_int co;
615 register u_int ro;
616 register u_int fw;
617 register u_int fh;
618 {
619 int underline = cci->underline;
620 u_short ch;
621
622 while (underline--) {
623 ch = *f++;
624 ch |= ch << 1;
625 asm ("bfins %0,%1@{%2:%3}" : /* no output */ :
626 "d" (ch), "a" (p), "d" (co), "d" (fw+1));
627 p += ro;
628 }
629
630 ch = *f++;
631 ch |= ch << 1;
632 asm ("bfins %0,%1@{%2:%3}" : /* no output */ :
633 "d" (expbits(ch)), "a" (p), "d" (co), "d" (fw+1));
634 p += ro;
635
636 underline = fh - cci->underline - 1;
637 while (underline--) {
638 ch = *f++;
639 ch |= ch << 1;
640 asm ("bfins %0,%1@{%2:%3}" : /* no output */ :
641 "d" (ch), "a" (p), "d" (co), "d" (fw+1));
642 p += ro;
643 }
644 }
645
646
647 static void
648 putc_bd_ul_in (cci,p,f,co,ro,fw,fh)
649 register ipriv_t *cci;
650 register u_char *p;
651 register u_char *f;
652 register u_int co;
653 register u_int ro;
654 register u_int fw;
655 register u_int fh;
656 {
657 int underline = cci->underline;
658 u_short ch;
659
660 while (underline--) {
661 ch = *f++;
662 ch |= ch << 1;
663 asm ("bfins %0,%1@{%2:%3}" : /* no output */ :
664 "d" (~(ch)), "a" (p), "d" (co), "d" (fw+1));
665 p += ro;
666 }
667
668 ch = *f++;
669 ch |= ch << 1;
670 asm ("bfins %0,%1@{%2:%3}" : /* no output */ :
671 "d" (~expbits(ch)), "a" (p), "d" (co), "d" (fw+1));
672 p += ro;
673
674 underline = fh - cci->underline - 1;
675 while (underline--) {
676 ch = *f++;
677 ch |= ch << 1;
678 asm ("bfins %0,%1@{%2:%3}" : /* no output */ :
679 "d" (~(ch)), "a" (p), "d" (co), "d" (fw+1));
680 p += ro;
681 }
682 }
683
684
685 typedef void cc_putc_func __P((ipriv_t *, u_char *, u_char *, u_int, u_int,
686 u_int, u_int));
687
688 cc_putc_func *put_func[ATTR_ALL+1] = {
689 putc_nm,
690 putc_in,
691 putc_ul,
692 putc_ul_in,
693 putc_bd,
694 putc_bd_in,
695 putc_bd_ul,
696 putc_bd_ul_in,
697 /* no support for blink */
698 putc_nm,
699 putc_in,
700 putc_ul,
701 putc_ul_in,
702 putc_bd,
703 putc_bd_in,
704 putc_bd_ul,
705 putc_bd_ul_in
706 };
707
708
709 /* FIX: shouldn't this advance the cursor even if the character to
710 be output is not available in the font? -ch */
711
712 static void
713 putc8(ip, c, dy, dx, mode)
714 struct ite_softc *ip;
715 int c, dy, dx, mode;
716 {
717 ipriv_t *cci = (ipriv_t *) ip->priv;
718 /*
719 * if character is higher than font has glyphs, substitute
720 * highest glyph.
721 */
722 c = (u_char)c;
723 if (c < ip->font_lo || c > ip->font_hi)
724 c = ip->font_hi;
725 put_func[mode](cci, cci->row_ptr[dy], cci->font_cell[c],
726 cci->column_offset[dx], cci->row_offset, cci->ft_x, cci->ft_y);
727 }
728
729 static void
730 clear8(struct ite_softc *ip, int sy, int sx, int h, int w)
731 {
732 ipriv_t *cci = (ipriv_t *) ip->priv;
733 bmap_t *bm = cci->view->bitmap;
734
735 if ((sx == 0) && (w == ip->cols))
736 {
737 /* common case: clearing whole lines */
738 while (h--)
739 {
740 int i;
741 u_char *ptr = cci->row_ptr[sy];
742 for (i=0; i < ip->ftheight; i++) {
743 bzero(ptr, bm->bytes_per_row);
744 ptr += bm->bytes_per_row + bm->row_mod; /* don't get any smart
745 ideas, becuase this is for
746 interleaved bitmaps */
747 }
748 sy++;
749 }
750 }
751 else
752 {
753 /* clearing only part of a line */
754 /* XXX could be optimized MUCH better, but is it worth the trouble? */
755 while (h--)
756 {
757 u_char *pl = cci->row_ptr[sy];
758 int ofs = sx * ip->ftwidth;
759 int i, j;
760 for (i = w-1; i >= 0; i--)
761 {
762 u_char *ppl = pl;
763 for (j = ip->ftheight-1; j >= 0; j--)
764 {
765 asm("bfclr %0@{%1:%2}"
766 : : "a" (ppl), "d" (ofs), "d" (ip->ftwidth));
767 ppl += bm->row_mod + bm->bytes_per_row;
768 }
769 ofs += ip->ftwidth;
770 }
771 sy++;
772 }
773 }
774 }
775
776 /* Note: sx is only relevant for SCROLL_LEFT or SCROLL_RIGHT. */
777 static void
778 scroll8(ip, sy, sx, count, dir)
779 register struct ite_softc *ip;
780 register int sy;
781 int dir, sx, count;
782 {
783 bmap_t *bm = ((ipriv_t *)ip->priv)->view->bitmap;
784 u_char *pl = ((ipriv_t *)ip->priv)->row_ptr[sy];
785
786 if (dir == SCROLL_UP)
787 {
788 int dy = sy - count;
789
790 /*FIX: add scroll bitmap call */
791 cursor32(ip, ERASE_CURSOR);
792 scrollbmap (bm, 0, dy*ip->ftheight,
793 bm->bytes_per_row >> 3, (ip->bottom_margin-dy+1)*ip->ftheight,
794 0, -(count*ip->ftheight), 0x1);
795 /* if (ip->cursory <= bot || ip->cursory >= dy) {
796 ip->cursory -= count;
797 } */
798 }
799 else if (dir == SCROLL_DOWN)
800 {
801
802 /* FIX: add scroll bitmap call */
803 cursor32(ip, ERASE_CURSOR);
804 scrollbmap (bm, 0, sy*ip->ftheight,
805 bm->bytes_per_row >> 3, (ip->bottom_margin-sy+1)*ip->ftheight,
806 0, count*ip->ftheight, 0x1);
807 /* if (ip->cursory <= bot || ip->cursory >= sy) {
808 ip->cursory += count;
809 } */
810 }
811 else if (dir == SCROLL_RIGHT)
812 {
813 int sofs = (ip->cols - count) * ip->ftwidth;
814 int dofs = (ip->cols) * ip->ftwidth;
815 int i, j;
816
817 cursor32(ip, ERASE_CURSOR);
818 for (j = ip->ftheight-1; j >= 0; j--)
819 {
820 int sofs2 = sofs, dofs2 = dofs;
821 for (i = (ip->cols - (sx + count))-1; i >= 0; i--)
822 {
823 int t;
824 sofs2 -= ip->ftwidth;
825 dofs2 -= ip->ftwidth;
826 asm("bfextu %1@{%2:%3},%0"
827 : "=d" (t)
828 : "a" (pl), "d" (sofs2), "d" (ip->ftwidth));
829 asm("bfins %3,%0@{%1:%2}"
830 : : "a" (pl), "d" (dofs2), "d" (ip->ftwidth), "d" (t));
831 }
832 pl += bm->row_mod + bm->bytes_per_row;
833 }
834 }
835 else /* SCROLL_LEFT */
836 {
837 int sofs = (sx) * ip->ftwidth;
838 int dofs = (sx - count) * ip->ftwidth;
839 int i, j;
840
841 cursor32(ip, ERASE_CURSOR);
842 for (j = ip->ftheight-1; j >= 0; j--)
843 {
844 int sofs2 = sofs, dofs2 = dofs;
845 for (i = (ip->cols - sx)-1; i >= 0; i--)
846 {
847 int t;
848 asm("bfextu %1@{%2:%3},%0"
849 : "=d" (t)
850 : "a" (pl), "d" (sofs2), "d" (ip->ftwidth));
851 asm("bfins %3,%0@{%1:%2}"
852 : : "a" (pl), "d" (dofs2), "d" (ip->ftwidth), "d" (t));
853 sofs2 += ip->ftwidth;
854 dofs2 += ip->ftwidth;
855 }
856 pl += bm->row_mod + bm->bytes_per_row;
857 }
858 }
859 }
860
861 void
862 scrollbmap (bmap_t *bm, u_short x, u_short y, u_short width, u_short height, short dx, short dy, u_char mask)
863 {
864 u_short depth = bm->depth;
865 u_short lwpr = bm->bytes_per_row >> 2;
866 if (dx) {
867 /* FIX: */ panic ("delta x not supported in scroll bitmap yet.");
868 }
869 if (bm->flags & BMF_INTERLEAVED) {
870 height *= depth;
871 depth = 1;
872 }
873 if (dy == 0) {
874 return;
875 }
876 if (dy > 0) {
877 int i;
878 for (i=0; i < depth && mask; i++, mask >>= 1) {
879 if (0x1 & mask) {
880 u_long *pl = (u_long *)bm->plane[i];
881 u_long *src_y = pl + (lwpr*y);
882 u_long *dest_y = pl + (lwpr*(y+dy));
883 u_long count = lwpr*(height-dy);
884 u_long *clr_y = src_y;
885 u_long clr_count = dest_y - src_y;
886 u_long bc, cbc;
887
888 src_y += count - 1;
889 dest_y += count - 1;
890
891 bc = count >> 4;
892 count &= 0xf;
893
894 while (bc--) {
895 *dest_y-- = *src_y--; *dest_y-- = *src_y--;
896 *dest_y-- = *src_y--; *dest_y-- = *src_y--;
897 *dest_y-- = *src_y--; *dest_y-- = *src_y--;
898 *dest_y-- = *src_y--; *dest_y-- = *src_y--;
899 *dest_y-- = *src_y--; *dest_y-- = *src_y--;
900 *dest_y-- = *src_y--; *dest_y-- = *src_y--;
901 *dest_y-- = *src_y--; *dest_y-- = *src_y--;
902 *dest_y-- = *src_y--; *dest_y-- = *src_y--;
903 }
904 while (count--) {
905 *dest_y-- = *src_y--;
906 }
907
908 cbc = clr_count >> 4;
909 clr_count &= 0xf;
910
911 while (cbc--) {
912 *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0;
913 *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0;
914 *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0;
915 *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0;
916 }
917 while (clr_count--) {
918 *clr_y++ = 0;
919 }
920 }
921 }
922 } else if (dy < 0) {
923 int i;
924 for (i=0; i < depth && mask; i++, mask >>= 1) {
925 if (0x1 & mask) {
926 u_long *pl = (u_long *)bm->plane[i];
927 u_long *src_y = pl + (lwpr*(y-dy));
928 u_long *dest_y = pl + (lwpr*y);
929 long count = lwpr*(height + dy);
930 u_long *clr_y = dest_y + count;
931 u_long clr_count = src_y - dest_y;
932 u_long bc, cbc;
933
934 bc = count >> 4;
935 count &= 0xf;
936
937 while (bc--) {
938 *dest_y++ = *src_y++; *dest_y++ = *src_y++;
939 *dest_y++ = *src_y++; *dest_y++ = *src_y++;
940 *dest_y++ = *src_y++; *dest_y++ = *src_y++;
941 *dest_y++ = *src_y++; *dest_y++ = *src_y++;
942 *dest_y++ = *src_y++; *dest_y++ = *src_y++;
943 *dest_y++ = *src_y++; *dest_y++ = *src_y++;
944 *dest_y++ = *src_y++; *dest_y++ = *src_y++;
945 *dest_y++ = *src_y++; *dest_y++ = *src_y++;
946 }
947 while (count--) {
948 *dest_y++ = *src_y++;
949 }
950
951 cbc = clr_count >> 4;
952 clr_count &= 0xf;
953
954 while (cbc--) {
955 *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0;
956 *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0;
957 *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0;
958 *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0;
959 }
960 while (clr_count--) {
961 *clr_y++ = 0;
962 }
963 }
964 }
965 }
966 }
967
968 #endif /* NGRFCC */
969