Home | History | Annotate | Line # | Download | only in dev
ite_cc.c revision 1.7
      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)
    238   struct ite_softc *ip;
    239   caddr_t addr;
    240 {
    241     int error = 0;
    242     struct ite_window_size *is;
    243     struct ite_bell_values *ib;
    244     ipriv_t *cci = ip->priv;
    245 
    246     switch (cmd) {
    247       case ITE_GET_WINDOW_SIZE:
    248 	is = (struct ite_window_size *)addr;
    249         is->x = cci->view->display.x;
    250 	is->y = cci->view->display.y;
    251 	is->width = cci->view->display.width;
    252  	is->height = cci->view->display.height;
    253  	is->depth = cci->view->bitmap->depth;
    254         break;
    255 
    256       case ITE_SET_WINDOW_SIZE:
    257         is = (struct ite_window_size *)addr;
    258 
    259         if (ite_new_size (ip, is)) {
    260             error = ENOMEM;
    261         } else {
    262 	    struct winsize ws;
    263 	    ws.ws_row = ip->rows;
    264 	    ws.ws_col = ip->cols;
    265 	    ws.ws_xpixel = cci->view->display.width;
    266 	    ws.ws_ypixel = cci->view->display.height;
    267 	    ite_reset (ip);
    268 	    /* XXX tell tty about the change *and* the process group should */
    269 	    /* XXX be signalled---this is messy, but works nice :^) */
    270 	    iteioctl (0, TIOCSWINSZ, &ws, 0);
    271         }
    272         break;
    273 
    274       case ITE_DISPLAY_WINDOW:
    275 	XXX_grf_cc_on (IPUNIT (ip));
    276 	/* viewioctl (IPUNIT(ip), VIEW_DISPLAY, NULL, 0, -1); */
    277 	break;
    278 
    279       case ITE_REMOVE_WINDOW:
    280 	XXX_grf_cc_off (IPUNIT (ip));
    281         /* viewioctl (IPUNIT(ip), VIEW_REMOVE, NULL, 0, -1); */
    282         break;
    283 
    284       case ITE_GET_BELL_VALUES:
    285       	ib = (struct ite_bell_values *)addr;
    286 	bcopy (&bell_vals, ib, sizeof (struct ite_bell_values));
    287 	break;
    288 
    289       case ITE_SET_BELL_VALUES:
    290       	ib = (struct ite_bell_values *)addr;
    291 	bcopy (ib, &bell_vals, sizeof (struct ite_bell_values));
    292 	break;
    293       case VIEW_USECOLORMAP:
    294       case VIEW_GETCOLORMAP:
    295 	/* XXX needs to be fixed when multiple console implemented. */
    296 	/* XXX watchout for that -1 its not really the kernel talking. */
    297 	/* XXX these two commands don't use the proc pointer though. */
    298 	error = viewioctl (0, cmd, addr, flag, -1);
    299 	break;
    300       default:
    301         error = -1;
    302         break;
    303     }
    304     return (error);
    305 }
    306 
    307 ite_view_deinit(ip)
    308 	struct ite_softc *ip;
    309 {
    310   ip->flags &= ~ITE_INITED;
    311   /* FIX: free our stuff. */
    312   if (ip->priv) {
    313     ipriv_t *cci = ip->priv;
    314 
    315 #if 0
    316     /* view stays open permanently */
    317     if (cci->view) {
    318         viewclose (IPUNIT(ip));
    319     }
    320 #endif
    321 
    322     /* well at least turn it off. */
    323     XXX_grf_cc_off (IPUNIT (ip));
    324     /* viewioctl (IPUNIT(ip), VIEW_REMOVE, NULL, 0, -1); */
    325 
    326     if (cci->row_ptr)
    327    	free_chipmem (cci->row_ptr);
    328     if (cci->column_offset)
    329 	free_chipmem (cci->column_offset);
    330 
    331     free_chipmem (cci);
    332     ip->priv = NULL;
    333   }
    334 }
    335 
    336 /*** (M<8)-by-N routines ***/
    337 
    338 static void
    339 view_le32n_cursor(struct ite_softc *ip, int flag)
    340 {
    341     ipriv_t  *cci = (ipriv_t *) ip->priv;
    342     view_t *v = cci->view;
    343     bmap_t *bm = v->bitmap;
    344     int dr_plane = (bm->depth > 1 ? bm->depth-1 : 0);
    345     int cend, ofs, h, cstart;
    346     unsigned char opclr, opset;
    347     u_char *pl;
    348 
    349     if (flag == START_CURSOROPT) {
    350 	if (!cci->cursor_opt) {
    351 	    view_le32n_cursor (ip, ERASE_CURSOR);
    352 	}
    353 	cci->cursor_opt++;
    354 	return;				  /* if we are already opted. */
    355     } else if (flag == END_CURSOROPT) {
    356 	cci->cursor_opt--;
    357 
    358     }
    359 
    360     if (cci->cursor_opt)
    361 	return;					  /* if we are still nested. */
    362 						  /* else we draw the cursor. */
    363 
    364     cstart = 0;
    365     cend = ip->ftheight-1;
    366     pl = VDISPLAY_LINE (v, dr_plane, (ip->cursory*ip->ftheight+cstart));
    367     ofs = (ip->cursorx * ip->ftwidth);
    368 
    369     /* erase cursor */
    370     if (flag != DRAW_CURSOR && flag != END_CURSOROPT) {
    371 	/* erase the cursor */
    372 	int h;
    373 	if (dr_plane) {
    374 	    for (h = cend; h >= 0; h--) {
    375 		asm("bfclr %0@{%1:%2}"
    376 		    : : "a" (pl), "d" (ofs), "d" (ip->ftwidth));
    377 		pl += cci->row_offset;
    378 	    }
    379 	} else {
    380 	    for (h = cend; h >= 0; h--) {
    381 		asm("bfchg %0@{%1:%2}"
    382 		    : : "a" (pl), "d" (ofs), "d" (ip->ftwidth));
    383 		pl += cci->row_offset;
    384 	    }
    385 	}
    386     }
    387 
    388     if ((flag == DRAW_CURSOR || flag == MOVE_CURSOR || flag == END_CURSOROPT)) {
    389 
    390 	ip->cursorx = MIN(ip->curx, ip->cols-1);
    391 	ip->cursory = ip->cury;
    392 	cstart = 0;
    393 	cend = ip->ftheight-1;
    394 	pl = VDISPLAY_LINE (v, dr_plane, (ip->cursory*ip->ftheight+cstart));
    395 	ofs = (ip->cursorx * ip->ftwidth);
    396 
    397 	/* draw the cursor */
    398 	if (dr_plane) {
    399 	    for (h = cend; h >= 0; h--) {
    400 		asm("bfset %0@{%1:%2}"
    401 		    : : "a" (pl), "d" (ofs), "d" (ip->ftwidth));
    402 		pl += cci->row_offset;
    403 	    }
    404 	} else {
    405 	    for (h = cend; h >= 0; h--) {
    406 		asm("bfchg %0@{%1:%2}"
    407 		    : : "a" (pl), "d" (ofs), "d" (ip->ftwidth));
    408 		pl += cci->row_offset;
    409 	    }
    410 	}
    411     }
    412 }
    413 
    414 
    415 static inline
    416 int expbits (int data)
    417 {
    418     int i, nd = 0;
    419     if (data & 1) {
    420     	nd |= 0x02;
    421     }
    422     for (i=1; i < 32; i++) {
    423 	if (data & (1 << i)) {
    424 	   nd |= 0x5 << (i-1);
    425 	}
    426     }
    427     nd &= ~data;
    428     return (~nd);
    429 }
    430 
    431 
    432 /* Notes: optimizations given the kernel_font_(width|height) #define'd.
    433  *        the dbra loops could be elminated and unrolled using height,
    434  *        the :width in the bfxxx instruction could be made immediate instead
    435  *        of a data register as it now is.
    436  *        the underline could be added when the loop is unrolled
    437  *
    438  *        It would look like hell but be very fast.*/
    439 
    440 static void
    441 putc_nm (cci,p,f,co,ro,fw,fh)
    442     register ipriv_t *cci;
    443     register u_char  *p;
    444     register u_char  *f;
    445     register u_int    co;
    446     register u_int    ro;
    447     register u_int    fw;
    448     register u_int    fh;
    449 {
    450     while (fh--) {
    451 	asm ("bfins %0,%1@{%2:%3}" : /* no output */ :
    452 	     "d" (*f++), "a" (p), "d" (co), "d" (fw));
    453 	p += ro;
    454     }
    455 }
    456 
    457 static void
    458 putc_in (cci,p,f,co,ro,fw,fh)
    459     register ipriv_t *cci;
    460     register u_char  *p;
    461     register u_char  *f;
    462     register u_int    co;
    463     register u_int    ro;
    464     register u_int    fw;
    465     register u_int    fh;
    466 {
    467     while (fh--) {
    468 	asm ("bfins %0,%1@{%2:%3}" : /* no output */ :
    469 	     "d" (~(*f++)), "a" (p), "d" (co), "d" (fw));
    470 	p += ro;
    471     }
    472 }
    473 
    474 
    475 static void
    476 putc_ul (cci,p,f,co,ro,fw,fh)
    477     register ipriv_t *cci;
    478     register u_char  *p;
    479     register u_char  *f;
    480     register u_int    co;
    481     register u_int    ro;
    482     register u_int    fw;
    483     register u_int    fh;
    484 {
    485     int underline = cci->underline;
    486     while (underline--) {
    487 	asm ("bfins %0,%1@{%2:%3}" : /* no output */ :
    488 	     "d" (*f++), "a" (p), "d" (co), "d" (fw));
    489 	p += ro;
    490     }
    491 
    492     asm ("bfins %0,%1@{%2:%3}" : /* no output */ :
    493 	 "d" (expbits(*f++)), "a" (p), "d" (co), "d" (fw));
    494     p += ro;
    495 
    496     underline = fh - cci->underline - 1;
    497     while (underline--) {
    498 	asm ("bfins %0,%1@{%2:%3}" : /* no output */ :
    499 	     "d" (*f++), "a" (p), "d" (co), "d" (fw));
    500 	p += ro;
    501     }
    502 }
    503 
    504 
    505 static void
    506 putc_ul_in (cci,p,f,co,ro,fw,fh)
    507     register ipriv_t *cci;
    508     register u_char  *p;
    509     register u_char  *f;
    510     register u_int    co;
    511     register u_int    ro;
    512     register u_int    fw;
    513     register u_int    fh;
    514 {
    515     int underline = cci->underline;
    516     while (underline--) {
    517 	asm ("bfins %0,%1@{%2:%3}" : /* no output */ :
    518 	     "d" (~(*f++)), "a" (p), "d" (co), "d" (fw));
    519 	p += ro;
    520     }
    521 
    522     asm ("bfins %0,%1@{%2:%3}" : /* no output */ :
    523 	 "d" (~expbits(*f++)), "a" (p), "d" (co), "d" (fw));
    524     p += ro;
    525 
    526     underline = fh - cci->underline - 1;
    527     while (underline--) {
    528 	asm ("bfins %0,%1@{%2:%3}" : /* no output */ :
    529 	     "d" (~(*f++)), "a" (p), "d" (co), "d" (fw));
    530 	p += ro;
    531     }
    532 }
    533 
    534 /* bold */
    535 static void
    536 putc_bd (cci,p,f,co,ro,fw,fh)
    537     register ipriv_t *cci;
    538     register u_char  *p;
    539     register u_char  *f;
    540     register u_int    co;
    541     register u_int    ro;
    542     register u_int    fw;
    543     register u_int    fh;
    544 {
    545     u_word ch;
    546 
    547     while (fh--) {
    548 	ch = *f++;
    549 	ch |= ch << 1;
    550 	asm ("bfins %0,%1@{%2:%3}" : /* no output */ :
    551 	     "d" (ch), "a" (p), "d" (co), "d" (fw+1));
    552 	p += ro;
    553     }
    554 }
    555 
    556 static void
    557 putc_bd_in (cci,p,f,co,ro,fw,fh)
    558     register ipriv_t *cci;
    559     register u_char  *p;
    560     register u_char  *f;
    561     register u_int    co;
    562     register u_int    ro;
    563     register u_int    fw;
    564     register u_int    fh;
    565 {
    566     u_word ch;
    567 
    568     while (fh--) {
    569 	ch = *f++;
    570 	ch |= ch << 1;
    571 	asm ("bfins %0,%1@{%2:%3}" : /* no output */ :
    572 	     "d" (~(ch)), "a" (p), "d" (co), "d" (fw+1));
    573 	p += ro;
    574     }
    575 }
    576 
    577 
    578 static void
    579 putc_bd_ul (cci,p,f,co,ro,fw,fh)
    580     register ipriv_t *cci;
    581     register u_char  *p;
    582     register u_char  *f;
    583     register u_int    co;
    584     register u_int    ro;
    585     register u_int    fw;
    586     register u_int    fh;
    587 {
    588     int underline = cci->underline;
    589     u_word ch;
    590 
    591     while (underline--) {
    592 	ch = *f++;
    593 	ch |= ch << 1;
    594 	asm ("bfins %0,%1@{%2:%3}" : /* no output */ :
    595 	     "d" (ch), "a" (p), "d" (co), "d" (fw+1));
    596 	p += ro;
    597     }
    598 
    599     ch = *f++;
    600     ch |= ch << 1;
    601     asm ("bfins %0,%1@{%2:%3}" : /* no output */ :
    602 	 "d" (expbits(ch)), "a" (p), "d" (co), "d" (fw+1));
    603     p += ro;
    604 
    605     underline = fh - cci->underline - 1;
    606     while (underline--) {
    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 
    616 static void
    617 putc_bd_ul_in (cci,p,f,co,ro,fw,fh)
    618     register ipriv_t *cci;
    619     register u_char  *p;
    620     register u_char  *f;
    621     register u_int    co;
    622     register u_int    ro;
    623     register u_int    fw;
    624     register u_int    fh;
    625 {
    626     int underline = cci->underline;
    627     u_word ch;
    628 
    629     while (underline--) {
    630 	ch = *f++;
    631 	ch |= ch << 1;
    632 	asm ("bfins %0,%1@{%2:%3}" : /* no output */ :
    633 	     "d" (~(ch)), "a" (p), "d" (co), "d" (fw+1));
    634 	p += ro;
    635     }
    636 
    637     ch = *f++;
    638     ch |= ch << 1;
    639     asm ("bfins %0,%1@{%2:%3}" : /* no output */ :
    640 	 "d" (~expbits(ch)), "a" (p), "d" (co), "d" (fw+1));
    641     p += ro;
    642 
    643     underline = fh - cci->underline - 1;
    644     while (underline--) {
    645 	ch = *f++;
    646 	ch |= ch << 1;
    647 	asm ("bfins %0,%1@{%2:%3}" : /* no output */ :
    648 	     "d" (~(ch)), "a" (p), "d" (co), "d" (fw+1));
    649 	p += ro;
    650     }
    651 }
    652 
    653 
    654 typedef void cc_putc_func ();
    655 
    656 cc_putc_func *put_func[ATTR_ALL+1] = {
    657     putc_nm,
    658     putc_in,
    659     putc_ul,
    660     putc_ul_in,
    661     putc_bd,
    662     putc_bd_in,
    663     putc_bd_ul,
    664     putc_bd_ul_in,
    665 /* no support for blink */
    666     putc_nm,
    667     putc_in,
    668     putc_ul,
    669     putc_ul_in,
    670     putc_bd,
    671     putc_bd_in,
    672     putc_bd_ul,
    673     putc_bd_ul_in
    674 };
    675 
    676 
    677 /* FIX: shouldn't this advance the cursor even if the character to
    678         be output is not available in the font? -ch */
    679 
    680 static void
    681 view_le8n_putc(struct ite_softc *ip, int c, int dy, int dx, int mode)
    682 {
    683     register ipriv_t *cci = (ipriv_t *) ip->priv;
    684     if (c < ip->font_lo || c > ip->font_hi)
    685 	return;
    686 
    687     put_func[mode](cci,
    688 		   cci->row_ptr[dy],
    689 		   cci->font_cell[c],
    690 		   cci->column_offset[dx],
    691 		   cci->row_offset,
    692 		   cci->ft_x,
    693 		   cci->ft_y);
    694 }
    695 
    696 static void
    697 view_le8n_clear(struct ite_softc *ip, int sy, int sx, int h, int w)
    698 {
    699   ipriv_t *cci = (ipriv_t *) ip->priv;
    700   view_t *v = cci->view;
    701   bmap_t *bm = cci->view->bitmap;
    702 
    703   if ((sx == 0) && (w == ip->cols))
    704     {
    705       /* common case: clearing whole lines */
    706       while (h--)
    707 	{
    708 	  int i;
    709 	  u_char *ptr = cci->row_ptr[sy];
    710 	  for (i=0; i < ip->ftheight; i++) {
    711             bzero(ptr, bm->bytes_per_row);
    712             ptr += bm->bytes_per_row + bm->row_mod;			/* don't get any smart
    713                                                    ideas, becuase this is for
    714                                                    interleaved bitmaps */
    715           }
    716 	  sy++;
    717 	}
    718     }
    719   else
    720     {
    721       /* clearing only part of a line */
    722       /* XXX could be optimized MUCH better, but is it worth the trouble? */
    723       while (h--)
    724 	{
    725 	  u_char *pl = cci->row_ptr[sy];
    726           int ofs = sx * ip->ftwidth;
    727 	  int i, j;
    728 	  for (i = w-1; i >= 0; i--)
    729 	    {
    730 	      u_char *ppl = pl;
    731               for (j = ip->ftheight-1; j >= 0; j--)
    732 	        {
    733 	          asm("bfclr %0@{%1:%2}"
    734 	              : : "a" (ppl), "d" (ofs), "d" (ip->ftwidth));
    735 	          ppl += bm->row_mod + bm->bytes_per_row;
    736 	        }
    737 	      ofs += ip->ftwidth;
    738 	    }
    739 	  sy++;
    740 	}
    741     }
    742 }
    743 
    744 /* Note: sx is only relevant for SCROLL_LEFT or SCROLL_RIGHT.  */
    745 static void
    746 view_le8n_scroll(ip, sy, sx, count, dir)
    747         register struct ite_softc *ip;
    748         register int sy;
    749         int dir, sx, count;
    750 {
    751   bmap_t *bm = ((ipriv_t *)ip->priv)->view->bitmap;
    752   u_char *pl = ((ipriv_t *)ip->priv)->row_ptr[sy];
    753 
    754   if (dir == SCROLL_UP)
    755     {
    756       int dy = sy - count;
    757       int height = ip->bottom_margin - sy + 1;
    758       int i;
    759 
    760       /*FIX: add scroll bitmap call */
    761         view_le32n_cursor(ip, ERASE_CURSOR);
    762 	scroll_bitmap (bm, 0, dy*ip->ftheight,
    763 		       bm->bytes_per_row >> 3, (ip->bottom_margin-dy+1)*ip->ftheight,
    764 		       0, -(count*ip->ftheight), 0x1);
    765 /*	if (ip->cursory <= bot || ip->cursory >= dy) {
    766 	    ip->cursory -= count;
    767 	} */
    768     }
    769   else if (dir == SCROLL_DOWN)
    770     {
    771       int dy = sy + count;
    772       int height = ip->bottom_margin - dy + 1;
    773       int i;
    774 
    775       /* FIX: add scroll bitmap call */
    776         view_le32n_cursor(ip, ERASE_CURSOR);
    777 	scroll_bitmap (bm, 0, sy*ip->ftheight,
    778 		       bm->bytes_per_row >> 3, (ip->bottom_margin-sy+1)*ip->ftheight,
    779 		       0, count*ip->ftheight, 0x1);
    780 /*	if (ip->cursory <= bot || ip->cursory >= sy) {
    781 	    ip->cursory += count;
    782 	} */
    783     }
    784   else if (dir == SCROLL_RIGHT)
    785     {
    786       int sofs = (ip->cols - count) * ip->ftwidth;
    787       int dofs = (ip->cols) * ip->ftwidth;
    788       int i, j;
    789 
    790       view_le32n_cursor(ip, ERASE_CURSOR);
    791       for (j = ip->ftheight-1; j >= 0; j--)
    792 	{
    793 	  int sofs2 = sofs, dofs2 = dofs;
    794 	  for (i = (ip->cols - (sx + count))-1; i >= 0; i--)
    795 	    {
    796 	      int t;
    797 	      sofs2 -= ip->ftwidth;
    798 	      dofs2 -= ip->ftwidth;
    799 	      asm("bfextu %1@{%2:%3},%0"
    800 	          : "=d" (t)
    801 		  : "a" (pl), "d" (sofs2), "d" (ip->ftwidth));
    802 	      asm("bfins %3,%0@{%1:%2}"
    803 	          : : "a" (pl), "d" (dofs2), "d" (ip->ftwidth), "d" (t));
    804 	    }
    805 	  pl += bm->row_mod + bm->bytes_per_row;
    806 	}
    807     }
    808   else /* SCROLL_LEFT */
    809     {
    810       int sofs = (sx) * ip->ftwidth;
    811       int dofs = (sx - count) * ip->ftwidth;
    812       int i, j;
    813 
    814       view_le32n_cursor(ip, ERASE_CURSOR);
    815       for (j = ip->ftheight-1; j >= 0; j--)
    816 	{
    817 	  int sofs2 = sofs, dofs2 = dofs;
    818 	  for (i = (ip->cols - sx)-1; i >= 0; i--)
    819 	    {
    820 	      int t;
    821 	      asm("bfextu %1@{%2:%3},%0"
    822 	          : "=d" (t)
    823 		  : "a" (pl), "d" (sofs2), "d" (ip->ftwidth));
    824 	      asm("bfins %3,%0@{%1:%2}"
    825 	          : : "a" (pl), "d" (dofs2), "d" (ip->ftwidth), "d" (t));
    826 	      sofs2 += ip->ftwidth;
    827 	      dofs2 += ip->ftwidth;
    828 	    }
    829 	  pl += bm->row_mod + bm->bytes_per_row;
    830 	}
    831     }
    832 }
    833 
    834 void
    835 scroll_bitmap (bmap_t *bm, u_word x, u_word y, u_word width, u_word height, word dx, word dy, u_byte mask)
    836 {
    837     u_word depth = bm->depth;
    838     u_word lwpr = bm->bytes_per_row >> 2;
    839     if (dx) {
    840     	/* FIX: */ panic ("delta x not supported in scroll bitmap yet.");
    841     }
    842     if (bm->flags & BMF_INTERLEAVED) {
    843 	height *= depth;
    844 	depth = 1;
    845     }
    846     if (dy == 0) {
    847         return;
    848     }
    849     if (dy > 0) {
    850     	int i;
    851     	for (i=0; i < depth && mask; i++, mask >>= 1) {
    852     	    if (0x1 & mask) {
    853 	    	u_long *pl = (u_long *)bm->plane[i];
    854 		u_long *src_y = pl + (lwpr*y);
    855 		u_long *dest_y = pl + (lwpr*(y+dy));
    856 		u_long count = lwpr*(height-dy);
    857 		u_long *clr_y = src_y;
    858 		u_long clr_count = dest_y - src_y;
    859 		u_long bc, cbc;
    860 
    861 		src_y += count - 1;
    862 		dest_y += count - 1;
    863 
    864 		bc = count >> 4;
    865 		count &= 0xf;
    866 
    867 		while (bc--) {
    868 		    *dest_y-- = *src_y--; *dest_y-- = *src_y--;
    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 		}
    877 		while (count--) {
    878 		    *dest_y-- = *src_y--;
    879 		}
    880 
    881 		cbc = clr_count >> 4;
    882 		clr_count &= 0xf;
    883 
    884 		while (cbc--) {
    885 		    *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0;
    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 		}
    890 		while (clr_count--) {
    891 		    *clr_y++ = 0;
    892 		}
    893     	    }
    894 	}
    895     } else if (dy < 0) {
    896     	int i;
    897     	for (i=0; i < depth && mask; i++, mask >>= 1) {
    898     	    if (0x1 & mask) {
    899     		u_long *pl = (u_long *)bm->plane[i];
    900     		u_long *src_y = pl + (lwpr*(y-dy));
    901     		u_long *dest_y = pl + (lwpr*y);
    902 		long count = lwpr*(height + dy);
    903 		u_long *clr_y = dest_y + count;
    904 		u_long clr_count = src_y - dest_y;
    905 		u_long bc, cbc;
    906 
    907 		bc = count >> 4;
    908 		count &= 0xf;
    909 
    910 		while (bc--) {
    911 		    *dest_y++ = *src_y++; *dest_y++ = *src_y++;
    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 		}
    920 		while (count--) {
    921 		    *dest_y++ = *src_y++;
    922 		}
    923 
    924 		cbc = clr_count >> 4;
    925 		clr_count &= 0xf;
    926 
    927 		while (cbc--) {
    928 		    *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0;
    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 		}
    933 		while (clr_count--) {
    934 		    *clr_y++ = 0;
    935 		}
    936 	    }
    937 	}
    938     }
    939 }
    940 #endif
    941