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