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