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