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