Home | History | Annotate | Line # | Download | only in dev
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