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