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