Home | History | Annotate | Line # | Download | only in dev
ite_cc.c revision 1.27
      1 /*	$NetBSD: ite_cc.c,v 1.27 1999/09/20 23:17:15 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 #define USE_C_BFOPS
     89 #if !defined(USE_C_BFOPS)
     90 #define BFEXT(v,p,o,w)	asm("bfextu %1@{%2:%3},%0" : "=d" (v) : \
     91 		"a"(p), "d"(o), "d"(w))
     92 #define BFINS(v,p,o,w)	asm("bfins %0,%1@{%2:%3}" : /* no output */ : \
     93 		"d"(v), "a"(p), "d"(o), "d"(w))
     94 #define BFCLR(p,o,w)	asm("bfclr %0@{%1:%2}" : /* no output */ : \
     95 		"a"(p), "d"(o), "d"(w))
     96 #define BFCHG(p,o,w)	asm("bfchg %0@{%1:%2}" : /* no output */ : \
     97 		"a"(p), "d"(o), "d"(w))
     98 #define BFSET(p,o,w)	asm("bfset %0@{%1:%2}" : /* no output */ : \
     99 		"a"(p), "d"(o), "d"(w))
    100 #else
    101 #define BFEXT(v,p,o,w)	do {v = ((u_int8_t *)(p))[(o)>>3];} while (0)
    102 #define BFINS(v,p,o,w)	do {((u_int8_t *)(p))[(o)>>3] = (v);} while (0)
    103 #define BFCLR(p,o,w)	BFINS(0x00,p,o,w)
    104 #define BFSET(p,o,w)	BFINS(0xff,p,o,w)
    105 #define BFCHG(p,o,w)	do {((u_int8_t *)(p))[(o)>>3] ^= 0xff;} while (0)
    106 #endif
    107 
    108 /*
    109  * This is what ip->priv points to;
    110  * it contains local variables for custom-chip ites.
    111  */
    112 struct ite_priv {
    113 	view_t *view;		/* the view for this ite. */
    114 	u_char **row_ptr;	/* array of pointers into the bitmap  */
    115 	u_long row_bytes;
    116 	u_long cursor_opt;
    117 	u_int  *column_offset;	/* array of offsets for columns */
    118 	u_int  row_offset;	/* the row offset */
    119 	u_short width;		/* the bitmap width */
    120 	u_short underline;	/* where the underline goes */
    121 	u_short ft_x;		/* the font width */
    122 	u_short ft_y;		/* the font height */
    123 	u_char *font_cell[256];	/* the font pointer */
    124 };
    125 typedef struct ite_priv ipriv_t;
    126 
    127 void view_deinit __P((struct ite_softc *));
    128 void view_init __P((struct ite_softc *));
    129 
    130 static void putc8 __P((struct ite_softc *, int, int, int, int));
    131 static void clear8 __P((struct ite_softc *, int, int, int, int));
    132 static void scroll8 __P((struct ite_softc *, int, int, int, int));
    133 static void cursor32 __P((struct ite_softc *, int));
    134 static void scrollbmap __P((bmap_t *, u_short, u_short, u_short, u_short,
    135     short, short, u_char));
    136 
    137 /* patchable */
    138 int ite_default_x = 0;		/* def leftedge offset */
    139 int ite_default_y = 0;		/* def topedge offset */
    140 int ite_default_width = 640;	/* def width */
    141 int ite_default_depth = 2;	/* def depth */
    142 #if defined (GRF_NTSC)
    143 int ite_default_height = 400;	/* def NTSC height */
    144 #elif defined (GRF_PAL)
    145 int ite_default_height = 512;	/* def PAL height */
    146 #else
    147 int ite_default_height = 400;	/* def NON-PAL/NTSC height (?) */
    148 #endif
    149 
    150 int ite_newsize __P((struct ite_softc *, struct itewinsize *));
    151 static void putc_nm __P((ipriv_t *, u_char *, u_char *, u_int, u_int,
    152 			u_int, u_int));
    153 static void putc_in __P((ipriv_t *, u_char *, u_char *, u_int, u_int,
    154 			u_int, u_int));
    155 static void putc_ul __P((ipriv_t *, u_char *, u_char *, u_int, u_int,
    156 			u_int, u_int));
    157 static void putc_ul_in __P((ipriv_t *, u_char *, u_char *, u_int, u_int,
    158 			u_int, u_int));
    159 static void putc_bd __P((ipriv_t *, u_char *, u_char *, u_int, u_int,
    160 			u_int, u_int));
    161 static void putc_bd_in __P((ipriv_t *, u_char *, u_char *, u_int, u_int,
    162 			u_int, u_int));
    163 static void putc_bd_ul __P((ipriv_t *, u_char *, u_char *, u_int, u_int,
    164 			u_int, u_int));
    165 static void putc_bd_ul_in __P((ipriv_t *, u_char *, u_char *, u_int, u_int,
    166 			u_int, u_int));
    167 
    168 /*
    169  * called from grf_cc to return console priority
    170  */
    171 int
    172 grfcc_cnprobe()
    173 {
    174 	return(CN_INTERNAL);
    175 }
    176 
    177 /*
    178  * called from grf_cc to init ite portion of
    179  * grf_softc struct
    180  */
    181 void
    182 grfcc_iteinit(gp)
    183 	struct grf_softc *gp;
    184 {
    185 	gp->g_itecursor = cursor32;
    186 	gp->g_iteputc = putc8;
    187 	gp->g_iteclear = clear8;
    188 	gp->g_itescroll = scroll8;
    189 	gp->g_iteinit = view_init;
    190 	gp->g_itedeinit = view_deinit;
    191 }
    192 
    193 int
    194 ite_newsize(ip, winsz)
    195 	struct ite_softc *ip;
    196 	struct itewinsize *winsz;
    197 {
    198 	extern struct view_softc views[];
    199 	struct view_size vs;
    200 	ipriv_t *cci = ip->priv;
    201 	u_long i;
    202 	int error;
    203 
    204 	vs.x = winsz->x;
    205 	vs.y = winsz->y;
    206 	vs.width = winsz->width;
    207 	vs.height = winsz->height;
    208 	vs.depth = winsz->depth;
    209 	error = viewioctl(0, VIOCSSIZE, (caddr_t)&vs, -1, NULL); /* XXX type of vs ? */
    210 
    211 	/*
    212 	 * Reinitialize our structs
    213 	 */
    214 	cci->view = views[0].view;
    215 
    216 	/* -1 for bold. */
    217 	ip->cols = (cci->view->display.width - 1) / ip->ftwidth;
    218 	ip->rows = cci->view->display.height / ip->ftheight;
    219 
    220 	/*
    221 	 * save new values so that future opens use them
    222 	 * this may not be correct when we implement Virtual Consoles
    223 	 */
    224 	ite_default_height = cci->view->display.height;
    225 	ite_default_width = cci->view->display.width;
    226 	ite_default_x = cci->view->display.x;
    227 	ite_default_y = cci->view->display.y;
    228 	ite_default_depth = cci->view->bitmap->depth;
    229 
    230 	if (cci->row_ptr)
    231 		free_chipmem(cci->row_ptr);
    232 	if (cci->column_offset)
    233 		free_chipmem(cci->column_offset);
    234 
    235 	cci->row_ptr = alloc_chipmem(sizeof(u_char *) * ip->rows);
    236 	cci->column_offset = alloc_chipmem(sizeof(u_int) * ip->cols);
    237 
    238 	if (cci->row_ptr == NULL || cci->column_offset == NULL)
    239 		panic("no chipmem for itecc data");
    240 
    241 
    242 	cci->width = cci->view->bitmap->bytes_per_row << 3;
    243 	cci->underline = ip->ftbaseline + 1;
    244 	cci->row_offset = cci->view->bitmap->bytes_per_row
    245 	    + cci->view->bitmap->row_mod;
    246 	cci->ft_x = ip->ftwidth;
    247 	cci->ft_y = ip->ftheight;
    248 
    249 	cci->row_bytes = cci->row_offset * ip->ftheight;
    250 
    251 	cci->row_ptr[0] = VDISPLAY_LINE (cci->view, 0, 0);
    252 	for (i = 1; i < ip->rows; i++)
    253 		cci->row_ptr[i] = cci->row_ptr[i-1] + cci->row_bytes;
    254 
    255 	/* initialize the column offsets */
    256 	cci->column_offset[0] = 0;
    257 	for (i = 1; i < ip->cols; i++)
    258 		cci->column_offset[i] = cci->column_offset[i - 1] + cci->ft_x;
    259 
    260 	/* initialize the font cell pointers */
    261 	cci->font_cell[ip->font_lo] = ip->font;
    262 	for (i=ip->font_lo+1; i<=ip->font_hi; i++)
    263 		cci->font_cell[i] = cci->font_cell[i-1] + ip->ftheight;
    264 
    265 	return (error);
    266 }
    267 
    268 void
    269 view_init(ip)
    270 	register struct ite_softc *ip;
    271 {
    272 	struct itewinsize wsz;
    273 	ipriv_t *cci;
    274 
    275 	cci = ip->priv;
    276 
    277 	if (cci)
    278 		return;
    279 
    280 	ip->font     = kernel_font;
    281 	ip->font_lo  = kernel_font_lo;
    282 	ip->font_hi  = kernel_font_hi;
    283 	ip->ftwidth  = kernel_font_width;
    284 	ip->ftheight = kernel_font_height;
    285 	ip->ftbaseline = kernel_font_baseline;
    286 	ip->ftboldsmear = kernel_font_boldsmear;
    287 
    288 	/* Find the correct set of rendering routines for this font.  */
    289 	if (ip->ftwidth > 8)
    290 		panic("kernel font size not supported");
    291 	cci = alloc_chipmem(sizeof (*cci));
    292 	if (cci == NULL)
    293 		panic("no memory for console device.");
    294 
    295 	ip->priv = cci;
    296 	cci->cursor_opt = 0;
    297 	cci->view = NULL;
    298 	cci->row_ptr = NULL;
    299 	cci->column_offset = NULL;
    300 
    301 	wsz.x = ite_default_x;
    302 	wsz.y = ite_default_y;
    303 	wsz.width = ite_default_width;
    304 	wsz.height = ite_default_height;
    305 	wsz.depth = ite_default_depth;
    306 
    307 	ite_newsize (ip, &wsz);
    308 	cc_mode(ip->grf, GM_GRFON, NULL, 0, 0);
    309 }
    310 
    311 int
    312 ite_grf_ioctl (ip, cmd, addr, flag, p)
    313 	struct ite_softc *ip;
    314 	u_long cmd;
    315 	caddr_t addr;
    316 	int flag;
    317 	struct proc *p;
    318 {
    319 	struct winsize ws;
    320 	struct itewinsize *is;
    321 	ipriv_t *cci;
    322 	int error;
    323 
    324 	cci = ip->priv;
    325 	error = 0;
    326 
    327 	switch (cmd) {
    328 	case ITEIOCGWINSZ:
    329 		is = (struct itewinsize *)addr;
    330 		is->x = cci->view->display.x;
    331 		is->y = cci->view->display.y;
    332 		is->width = cci->view->display.width;
    333 		is->height = cci->view->display.height;
    334 		is->depth = cci->view->bitmap->depth;
    335 		break;
    336 	case ITEIOCSWINSZ:
    337 		is = (struct itewinsize *)addr;
    338 
    339 		if (ite_newsize(ip, is))
    340 			error = ENOMEM;
    341 		else {
    342 			ws.ws_row = ip->rows;
    343 			ws.ws_col = ip->cols;
    344 			ws.ws_xpixel = cci->view->display.width;
    345 			ws.ws_ypixel = cci->view->display.height;
    346 			ite_reset (ip);
    347 			/*
    348 			 * XXX tell tty about the change
    349 			 * XXX this is messy, but works
    350 			 */
    351 			iteioctl(0, TIOCSWINSZ, (caddr_t)&ws, 0, p);
    352 		}
    353 		break;
    354 	case ITEIOCDSPWIN:
    355 		cc_mode(ip->grf, GM_GRFON, NULL, 0, 0);
    356 		break;
    357 	case ITEIOCREMWIN:
    358 		cc_mode(ip->grf, GM_GRFOFF, NULL, 0, 0);
    359 		break;
    360 	case VIOCSCMAP:
    361 	case VIOCGCMAP:
    362 		/*
    363 		 * XXX needs to be fixed when multiple console implemented
    364 		 * XXX watchout for that -1 its not really the kernel talking
    365 		 * XXX these two commands don't use the proc pointer though
    366 		 */
    367 		error = viewioctl(0, cmd, addr, -1, p);
    368 		break;
    369 	default:
    370 		error = -1;
    371 		break;
    372 	}
    373 	return (error);
    374 }
    375 
    376 void
    377 view_deinit(ip)
    378 	struct ite_softc *ip;
    379 {
    380 	ip->flags &= ~ITE_INITED;
    381 }
    382 
    383 /*** (M<8)-by-N routines ***/
    384 
    385 static void
    386 cursor32(struct ite_softc *ip, int flag)
    387 {
    388 	int cend, ofs, h, cstart, dr_plane;
    389 	u_char *pl;
    390 	ipriv_t *cci;
    391 	bmap_t *bm;
    392 	view_t *v;
    393 
    394 	cci = ip->priv;
    395 	v = cci->view;
    396    	bm = v->bitmap;
    397 	dr_plane = (bm->depth > 1 ? bm->depth-1 : 0);
    398 
    399 	if (flag == END_CURSOROPT)
    400 		cci->cursor_opt--;
    401 	else if (flag == START_CURSOROPT) {
    402 		if (!cci->cursor_opt)
    403 			cursor32 (ip, ERASE_CURSOR);
    404 		cci->cursor_opt++;
    405 		return;		  /* if we are already opted. */
    406 	}
    407 
    408 	if (cci->cursor_opt)
    409 		return;		  /* if we are still nested. */
    410 				  /* else we draw the cursor. */
    411 	cstart = 0;
    412 	cend = ip->ftheight-1;
    413 	pl = VDISPLAY_LINE(v, dr_plane, (ip->cursory * ip->ftheight + cstart));
    414 	ofs = (ip->cursorx * ip->ftwidth);
    415 
    416 	if (flag != DRAW_CURSOR && flag != END_CURSOROPT) {
    417 		/*
    418 		 * erase the cursor
    419 		 */
    420 		int h;
    421 
    422 		if (dr_plane) {
    423 			for (h = cend; h >= 0; h--) {
    424 				BFCLR(pl, ofs, ip->ftwidth);
    425 				pl += cci->row_offset;
    426 			}
    427 		} else {
    428 			for (h = cend; h >= 0; h--) {
    429 				BFCHG(pl, ofs, ip->ftwidth);
    430 				pl += cci->row_offset;
    431 			}
    432 		}
    433 	}
    434 
    435 	if (flag != DRAW_CURSOR && flag != MOVE_CURSOR &&
    436 	    flag != END_CURSOROPT)
    437 		return;
    438 
    439 	/*
    440 	 * draw the cursor
    441 	 */
    442 
    443 	ip->cursorx = min(ip->curx, ip->cols-1);
    444 	ip->cursory = ip->cury;
    445 	cstart = 0;
    446 	cend = ip->ftheight-1;
    447 	pl = VDISPLAY_LINE(v, dr_plane, ip->cursory * ip->ftheight + cstart);
    448 	ofs = ip->cursorx * ip->ftwidth;
    449 
    450 	if (dr_plane) {
    451 		for (h = cend; h >= 0; h--) {
    452 			BFSET(pl, ofs, ip->ftwidth);
    453 			pl += cci->row_offset;
    454 		}
    455 	} else {
    456 		for (h = cend; h >= 0; h--) {
    457 			BFCHG(pl, ofs, ip->ftwidth);
    458 			pl += cci->row_offset;
    459 		}
    460 	}
    461 }
    462 
    463 
    464 static inline
    465 int expbits (int data)
    466 {
    467 	int i, nd = 0;
    468 
    469 	if (data & 1)
    470 		nd |= 0x02;
    471 	for (i=1; i < 32; i++) {
    472 		if (data & (1 << i))
    473 			nd |= 0x5 << (i-1);
    474 	}
    475 	nd &= ~data;
    476 	return(~nd);
    477 }
    478 
    479 
    480 /* Notes: optimizations given the kernel_font_(width|height) #define'd.
    481  *        the dbra loops could be elminated and unrolled using height,
    482  *        the :width in the bfxxx instruction could be made immediate instead
    483  *        of a data register as it now is.
    484  *        the underline could be added when the loop is unrolled
    485  *
    486  *        It would look like hell but be very fast.*/
    487 
    488 static void
    489 putc_nm (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 	BFINS(*f++, p, co, fw);
    500 	p += ro;
    501     }
    502 }
    503 
    504 static void
    505 putc_in (cci,p,f,co,ro,fw,fh)
    506     register ipriv_t *cci;
    507     register u_char  *p;
    508     register u_char  *f;
    509     register u_int    co;
    510     register u_int    ro;
    511     register u_int    fw;
    512     register u_int    fh;
    513 {
    514     while (fh--) {
    515 	BFINS(~(*f++),p,co,fw);
    516 	p += ro;
    517     }
    518 }
    519 
    520 
    521 static void
    522 putc_ul (cci,p,f,co,ro,fw,fh)
    523     register ipriv_t *cci;
    524     register u_char  *p;
    525     register u_char  *f;
    526     register u_int    co;
    527     register u_int    ro;
    528     register u_int    fw;
    529     register u_int    fh;
    530 {
    531     int underline = cci->underline;
    532     while (underline--) {
    533 	BFINS(*f++,p,co,fw);
    534 	p += ro;
    535     }
    536 
    537     BFINS(expbits(*f++),p,co,fw);
    538     p += ro;
    539 
    540     underline = fh - cci->underline - 1;
    541     while (underline--) {
    542 	BFINS(*f++,p,co,fw);
    543 	p += ro;
    544     }
    545 }
    546 
    547 
    548 static void
    549 putc_ul_in (cci,p,f,co,ro,fw,fh)
    550     register ipriv_t *cci;
    551     register u_char  *p;
    552     register u_char  *f;
    553     register u_int    co;
    554     register u_int    ro;
    555     register u_int    fw;
    556     register u_int    fh;
    557 {
    558     int underline = cci->underline;
    559     while (underline--) {
    560 	BFINS(~(*f++),p,co,fw);
    561 	p += ro;
    562     }
    563 
    564     BFINS(~expbits(*f++),p,co,fw);
    565     p += ro;
    566 
    567     underline = fh - cci->underline - 1;
    568     while (underline--) {
    569 	BFINS(~(*f++),p,co,fw);
    570 	p += ro;
    571     }
    572 }
    573 
    574 /* bold */
    575 static void
    576 putc_bd (cci,p,f,co,ro,fw,fh)
    577     register ipriv_t *cci;
    578     register u_char  *p;
    579     register u_char  *f;
    580     register u_int    co;
    581     register u_int    ro;
    582     register u_int    fw;
    583     register u_int    fh;
    584 {
    585     u_short ch;
    586 
    587     while (fh--) {
    588 	ch = *f++;
    589 	ch |= ch << 1;
    590 	BFINS(ch,p,co,fw+1);
    591 	p += ro;
    592     }
    593 }
    594 
    595 static void
    596 putc_bd_in (cci,p,f,co,ro,fw,fh)
    597     register ipriv_t *cci;
    598     register u_char  *p;
    599     register u_char  *f;
    600     register u_int    co;
    601     register u_int    ro;
    602     register u_int    fw;
    603     register u_int    fh;
    604 {
    605     u_short ch;
    606 
    607     while (fh--) {
    608 	ch = *f++;
    609 	ch |= ch << 1;
    610 	BFINS(~ch,p,co,fw+1);
    611 	p += ro;
    612     }
    613 }
    614 
    615 
    616 static void
    617 putc_bd_ul (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_short ch;
    628 
    629     while (underline--) {
    630 	ch = *f++;
    631 	ch |= ch << 1;
    632 	BFINS(ch,p,co,fw+1);
    633 	p += ro;
    634     }
    635 
    636     ch = *f++;
    637     ch |= ch << 1;
    638     BFINS(expbits(ch),p,co,fw+1);
    639     p += ro;
    640 
    641     underline = fh - cci->underline - 1;
    642     while (underline--) {
    643 	ch = *f++;
    644 	ch |= ch << 1;
    645 	BFINS(ch,p,co,fw+1);
    646 	p += ro;
    647     }
    648 }
    649 
    650 
    651 static void
    652 putc_bd_ul_in (cci,p,f,co,ro,fw,fh)
    653     register ipriv_t *cci;
    654     register u_char  *p;
    655     register u_char  *f;
    656     register u_int    co;
    657     register u_int    ro;
    658     register u_int    fw;
    659     register u_int    fh;
    660 {
    661     int underline = cci->underline;
    662     u_short ch;
    663 
    664     while (underline--) {
    665 	ch = *f++;
    666 	ch |= ch << 1;
    667 	BFINS(~ch,p,co,fw+1);
    668 	p += ro;
    669     }
    670 
    671     ch = *f++;
    672     ch |= ch << 1;
    673     BFINS(~expbits(ch),p,co,fw+1);
    674     p += ro;
    675 
    676     underline = fh - cci->underline - 1;
    677     while (underline--) {
    678 	ch = *f++;
    679 	ch |= ch << 1;
    680 	BFINS(~ch,p,co,fw+1);
    681 	p += ro;
    682     }
    683 }
    684 
    685 
    686 typedef void cc_putc_func __P((ipriv_t *, u_char *, u_char *, u_int, u_int,
    687 			u_int, u_int));
    688 
    689 cc_putc_func *put_func[ATTR_ALL+1] = {
    690     putc_nm,
    691     putc_in,
    692     putc_ul,
    693     putc_ul_in,
    694     putc_bd,
    695     putc_bd_in,
    696     putc_bd_ul,
    697     putc_bd_ul_in,
    698 /* no support for blink */
    699     putc_nm,
    700     putc_in,
    701     putc_ul,
    702     putc_ul_in,
    703     putc_bd,
    704     putc_bd_in,
    705     putc_bd_ul,
    706     putc_bd_ul_in
    707 };
    708 
    709 
    710 /* FIX: shouldn't this advance the cursor even if the character to
    711         be output is not available in the font? -ch */
    712 
    713 static void
    714 putc8(ip, c, dy, dx, mode)
    715 	struct ite_softc *ip;
    716 	int c, dy, dx, mode;
    717 {
    718 	ipriv_t *cci = (ipriv_t *) ip->priv;
    719 	/*
    720 	 * if character is higher than font has glyphs, substitute
    721 	 * highest glyph.
    722 	 */
    723 	c = (u_char)c;
    724 	if (c < ip->font_lo || c > ip->font_hi)
    725 		c = ip->font_hi;
    726 	put_func[mode](cci, cci->row_ptr[dy], cci->font_cell[c],
    727 	    cci->column_offset[dx], cci->row_offset, cci->ft_x, cci->ft_y);
    728 }
    729 
    730 static void
    731 clear8(struct ite_softc *ip, int sy, int sx, int h, int w)
    732 {
    733   ipriv_t *cci = (ipriv_t *) ip->priv;
    734   bmap_t *bm = cci->view->bitmap;
    735 
    736   if ((sx == 0) && (w == ip->cols))
    737     {
    738       /* common case: clearing whole lines */
    739       while (h--)
    740 	{
    741 	  int i;
    742 	  u_char *ptr = cci->row_ptr[sy];
    743 	  for (i=0; i < ip->ftheight; i++) {
    744             bzero(ptr, bm->bytes_per_row);
    745             ptr += bm->bytes_per_row + bm->row_mod;			/* don't get any smart
    746                                                    ideas, becuase this is for
    747                                                    interleaved bitmaps */
    748           }
    749 	  sy++;
    750 	}
    751     }
    752   else
    753     {
    754       /* clearing only part of a line */
    755       /* XXX could be optimized MUCH better, but is it worth the trouble? */
    756       while (h--)
    757 	{
    758 	  u_char *pl = cci->row_ptr[sy];
    759           int ofs = sx * ip->ftwidth;
    760 	  int i, j;
    761 	  for (i = w-1; i >= 0; i--)
    762 	    {
    763 	      u_char *ppl = pl;
    764               for (j = ip->ftheight-1; j >= 0; j--)
    765 	        {
    766 		  BFCLR(ppl, ofs, 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 	      BFEXT(t, pl, sofs2, ip->ftwidth);
    827 	      BFINS(t, pl, dofs2, ip->ftwidth);
    828 	    }
    829 	  pl += bm->row_mod + bm->bytes_per_row;
    830 	}
    831     }
    832   else /* SCROLL_LEFT */
    833     {
    834       int sofs = (sx) * ip->ftwidth;
    835       int dofs = (sx - count) * ip->ftwidth;
    836       int i, j;
    837 
    838       cursor32(ip, ERASE_CURSOR);
    839       for (j = ip->ftheight-1; j >= 0; j--)
    840 	{
    841 	  int sofs2 = sofs, dofs2 = dofs;
    842 	  for (i = (ip->cols - sx)-1; i >= 0; i--)
    843 	    {
    844 	      int t;
    845 	      asm("bfextu %1@{%2:%3},%0"
    846 	          : "=d" (t)
    847 		  : "a" (pl), "d" (sofs2), "d" (ip->ftwidth));
    848 	      BFEXT(t, pl, sofs2, ip->ftwidth);
    849 	      BFINS(t, pl, dofs2, ip->ftwidth);
    850 	      sofs2 += ip->ftwidth;
    851 	      dofs2 += ip->ftwidth;
    852 	    }
    853 	  pl += bm->row_mod + bm->bytes_per_row;
    854 	}
    855     }
    856 }
    857 
    858 void
    859 scrollbmap (bmap_t *bm, u_short x, u_short y, u_short width, u_short height, short dx, short dy, u_char mask)
    860 {
    861     u_short depth = bm->depth;
    862     u_short lwpr = bm->bytes_per_row >> 2;
    863     if (dx) {
    864     	/* FIX: */ panic ("delta x not supported in scroll bitmap yet.");
    865     }
    866     if (bm->flags & BMF_INTERLEAVED) {
    867 	height *= depth;
    868 	depth = 1;
    869     }
    870     if (dy == 0) {
    871         return;
    872     }
    873     if (dy > 0) {
    874     	int i;
    875     	for (i=0; i < depth && mask; i++, mask >>= 1) {
    876     	    if (0x1 & mask) {
    877 	    	u_long *pl = (u_long *)bm->plane[i];
    878 		u_long *src_y = pl + (lwpr*y);
    879 		u_long *dest_y = pl + (lwpr*(y+dy));
    880 		u_long count = lwpr*(height-dy);
    881 		u_long *clr_y = src_y;
    882 		u_long clr_count = dest_y - src_y;
    883 		u_long bc, cbc;
    884 
    885 		src_y += count - 1;
    886 		dest_y += count - 1;
    887 
    888 		bc = count >> 4;
    889 		count &= 0xf;
    890 
    891 		while (bc--) {
    892 		    *dest_y-- = *src_y--; *dest_y-- = *src_y--;
    893 		    *dest_y-- = *src_y--; *dest_y-- = *src_y--;
    894 		    *dest_y-- = *src_y--; *dest_y-- = *src_y--;
    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 		}
    901 		while (count--) {
    902 		    *dest_y-- = *src_y--;
    903 		}
    904 
    905 		cbc = clr_count >> 4;
    906 		clr_count &= 0xf;
    907 
    908 		while (cbc--) {
    909 		    *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0;
    910 		    *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0;
    911 		    *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0;
    912 		    *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0;
    913 		}
    914 		while (clr_count--) {
    915 		    *clr_y++ = 0;
    916 		}
    917     	    }
    918 	}
    919     } else if (dy < 0) {
    920     	int i;
    921     	for (i=0; i < depth && mask; i++, mask >>= 1) {
    922     	    if (0x1 & mask) {
    923     		u_long *pl = (u_long *)bm->plane[i];
    924     		u_long *src_y = pl + (lwpr*(y-dy));
    925     		u_long *dest_y = pl + (lwpr*y);
    926 		long count = lwpr*(height + dy);
    927 		u_long *clr_y = dest_y + count;
    928 		u_long clr_count = src_y - dest_y;
    929 		u_long bc, cbc;
    930 
    931 		bc = count >> 4;
    932 		count &= 0xf;
    933 
    934 		while (bc--) {
    935 		    *dest_y++ = *src_y++; *dest_y++ = *src_y++;
    936 		    *dest_y++ = *src_y++; *dest_y++ = *src_y++;
    937 		    *dest_y++ = *src_y++; *dest_y++ = *src_y++;
    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 		}
    944 		while (count--) {
    945 		    *dest_y++ = *src_y++;
    946 		}
    947 
    948 		cbc = clr_count >> 4;
    949 		clr_count &= 0xf;
    950 
    951 		while (cbc--) {
    952 		    *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0;
    953 		    *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0;
    954 		    *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0;
    955 		    *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0;
    956 		}
    957 		while (clr_count--) {
    958 		    *clr_y++ = 0;
    959 		}
    960 	    }
    961 	}
    962     }
    963 }
    964 
    965 #endif /* NGRFCC */
    966