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