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