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