Home | History | Annotate | Line # | Download | only in dev
ite_cv.c revision 1.2
      1 /*	$NetBSD: ite_cv.c,v 1.2 1996/04/21 21:11:59 veego Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1995 Michael Teske
      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  *      Ezra Story, Kari Mettinen, Markus Wild, Lutz Vieweg
     19  *      and Michael Teske.
     20  * 4. The name of the author may not be used to endorse or promote products
     21  *    derived from this software without specific prior written permission
     22  *
     23  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     24  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     25  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     26  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     28  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     29  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     30  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     32  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     33  */
     34 
     35 /*
     36  * The text console is based on ite_cl.c and ite_rh.c by
     37  * Ezra Story, Kari Mettinen, Markus Wild, Lutz Vieweg.
     38  * The gfx console is based on ite_cc.c from Christian E. Hopps.
     39  */
     40 
     41 #include "grfcv.h"
     42 #if NGRFCV > 0
     43 
     44 #include <sys/param.h>
     45 #include <sys/conf.h>
     46 #include <sys/proc.h>
     47 #include <sys/device.h>
     48 #include <sys/ioctl.h>
     49 #include <sys/tty.h>
     50 #include <sys/systm.h>
     51 #include <sys/queue.h>
     52 #include <sys/termios.h>
     53 #include <sys/malloc.h>
     54 #include <dev/cons.h>
     55 #include <machine/cpu.h>
     56 #include <amiga/dev/itevar.h>
     57 #include <amiga/dev/iteioctl.h>
     58 #include <amiga/amiga/device.h>
     59 #include <amiga/dev/grfioctl.h>
     60 #include <amiga/dev/grfvar.h>
     61 #include <amiga/dev/grf_cvreg.h>
     62 
     63 void cv_ite_init __P((struct ite_softc *));
     64 void cv_ite_deinit __P((struct ite_softc *));
     65 static void cv_cursor __P((struct ite_softc *, int));
     66 static void cv_putc __P((struct ite_softc *, int, int, int, int));
     67 static void cv_clear __P((struct ite_softc *, int, int, int, int));
     68 static void cv_scroll __P((struct ite_softc *, int, int, int, int));
     69 
     70 #define MAXROWS 200
     71 #define MAXCOLS 200
     72 static unsigned short cv_rowc[MAXROWS];
     73 
     74 #ifndef CV_DONT_USE_CONBUFFER
     75 
     76 /*
     77  * Console buffer to avoid the slow reading from gfx mem.
     78  * this takes up 40k but it makes scrolling 3 times faster.
     79  * I'd like to alocate it dynamically.
     80  */
     81 static unsigned short console_buffer[MAXCOLS*MAXROWS];
     82 #endif
     83 
     84 /*
     85  * called from grf_cv to return console priority
     86  */
     87 int
     88 grfcv_cnprobe()
     89 {
     90 	static int done;
     91 	int rv;
     92 
     93 	if (done == 0)
     94 #ifdef CV64CONSOLE
     95 		rv = CN_INTERNAL;
     96 #else
     97 		rv = CN_DEAD;
     98 #endif
     99 	else
    100 #ifdef CV64CONSOLE
    101 		rv = CN_NORMAL;
    102 #else
    103 		rv = CN_DEAD;
    104 #endif
    105 	done = 1;
    106 	return(rv);
    107 }
    108 
    109 
    110 /*
    111  * called from grf_cv to init ite portion of
    112  * grf_softc struct
    113  */
    114 void
    115 grfcv_iteinit(gp)
    116 	struct grf_softc *gp;
    117 {
    118 	gp->g_itecursor = cv_cursor;
    119 	gp->g_iteputc = cv_putc;
    120 	gp->g_iteclear = cv_clear;
    121 	gp->g_itescroll = cv_scroll;
    122 	gp->g_iteinit = cv_ite_init;
    123 	gp->g_itedeinit = cv_ite_deinit;
    124 }
    125 
    126 
    127 void
    128 cv_ite_deinit(ip)
    129 	struct ite_softc *ip;
    130 {
    131 	ip->flags &= ~ITE_INITED;
    132 }
    133 
    134 
    135 void
    136 cv_ite_init(ip)
    137 	register struct ite_softc *ip;
    138 {
    139 	struct grfcvtext_mode *md;
    140 	int i;
    141 
    142 	ip->priv = ip->grf->g_data;
    143 	md = (struct grfcvtext_mode *) ip->grf->g_data;
    144 
    145 	ip->cols = md->cols;
    146 	ip->rows = md->rows;
    147 	if (ip->rows > MAXROWS)
    148 		panic ("ite_cv.c: Too many rows!");
    149 
    150 	for (i = 0; i < ip->rows; i++)
    151 		cv_rowc[i] = i * ip->cols;
    152 #ifndef CV_DONT_USE_CONBUFFER
    153 	for (i = 0; i < MAXCOLS*MAXROWS; i++)
    154 		console_buffer[i] = 0x2007;
    155 #endif
    156 }
    157 
    158 
    159 void
    160 cv_cursor(ip, flag)
    161 	struct ite_softc *ip;
    162 	int flag;
    163 {
    164 	volatile caddr_t ba = ip->grf->g_regkva;
    165 
    166 	switch (flag) {
    167 	    case DRAW_CURSOR:
    168 		/*WCrt(ba, CRT_ID_CURSOR_START, & ~0x20); */
    169 	    case MOVE_CURSOR:
    170 		flag = ip->curx + ip->cury * ip->cols;
    171 		WCrt(ba, CRT_ID_CURSOR_LOC_LOW, flag & 0xff);
    172 		WCrt(ba, CRT_ID_CURSOR_LOC_HIGH, flag >> 8);
    173 		ip->cursorx = ip->curx;
    174 		ip->cursory = ip->cury;
    175 		break;
    176 	    case ERASE_CURSOR:
    177 		/*WCrt(ba, CRT_ID_CURSOR_START, | 0x20); */
    178 	    case START_CURSOROPT:
    179 	    case END_CURSOROPT:
    180 	    default:
    181 		break;
    182 	}
    183 }
    184 
    185 
    186 void
    187 cv_putc(ip, c, dy, dx, mode)
    188 	struct ite_softc *ip;
    189 	int c;
    190 	int dy;
    191 	int dx;
    192 	int mode;
    193 {
    194 	caddr_t fb = ip->grf->g_fbkva;
    195 	unsigned char attr;
    196 	unsigned char *cp;
    197 
    198 	attr = (unsigned char) ((mode & ATTR_INV) ? (0x70) : (0x07));
    199 	if (mode & ATTR_UL)     attr  = 0x01;
    200 	if (mode & ATTR_BOLD)   attr |= 0x08;
    201 	if (mode & ATTR_BLINK)  attr |= 0x80;
    202 
    203 	cp = fb + ((cv_rowc[dy] + dx) << 2); /* *4 */
    204 	*cp++ = (unsigned char) c;
    205 	*cp = (unsigned char) attr;
    206 #ifndef CV_DONT_USE_CONBUFFER
    207 	cp = (unsigned char *) &console_buffer[cv_rowc[dy]+dx];
    208 	*cp++ = (unsigned char) c;
    209 	*cp = (unsigned char) attr;
    210 #endif
    211 }
    212 
    213 
    214 void
    215 cv_clear(ip, sy, sx, h, w)
    216 	struct ite_softc *ip;
    217 	int sy;
    218 	int sx;
    219 	int h;
    220 	int w;
    221 {
    222 	/* cv_clear and cv_scroll both rely on ite passing arguments
    223 	 * which describe continuous regions.  For a VT200 terminal,
    224 	 * this is safe behavior.
    225 	 */
    226 	unsigned short  *dst;
    227 	int len;
    228 
    229 	dst = (unsigned short *) (ip->grf->g_fbkva + (((sy * ip->cols) + sx) << 2));
    230 
    231 	for (len = w*h; len > 0 ; len--) {
    232 		*dst = 0x2007;
    233 		dst +=2;
    234 	}
    235 
    236 #ifndef CV_DONT_USE_CONBUFFER
    237 	dst = &console_buffer[(sy * ip->cols) + sx];
    238 	for (len = w*h; len > 0 ; len--) {
    239 		*dst++ = 0x2007;
    240 	}
    241 #endif
    242 }
    243 
    244 void
    245 cv_scroll(ip, sy, sx, count, dir)
    246 	struct ite_softc *ip;
    247 	int sy;
    248 	int sx;
    249 	int count;
    250 	int dir;
    251 {
    252 	unsigned short *src, *dst, *dst2;
    253 	int i;
    254 	int len;
    255 
    256 	src = (unsigned short *)(ip->grf->g_fbkva + ((sy * ip->cols) << 2));
    257 
    258 	switch (dir) {
    259 	    case SCROLL_UP:
    260 		dst = src - ((count * ip->cols)<<1);
    261 #ifdef CV_DONT_USE_CONBUFFER
    262 		for (i = 0; i < (ip->bottom_margin + 1 - sy) * ip->cols; i++) {
    263 			*dst++ = *src++; /* copy only plane 0 and 1 */
    264 			dst++; src++;
    265 		}
    266 #else
    267 		len = (ip->bottom_margin + 1 - sy) * ip->cols;
    268 		src = &console_buffer[sy*ip->cols];
    269 #if 0
    270 		if (count > sy) { /* boundary checks */
    271 			dst2 = console_buffer;
    272 			len -= (count - sy) * ip->cols;
    273 			src += (count - sy) * ip->cols;
    274 		} else
    275 #endif
    276 			dst2 = &console_buffer[(sy-count)*ip->cols];
    277 		bcopy (src, dst2, len << 1);
    278 
    279 		for (i = 0; i < len; i++) {
    280 			*dst++ = *dst2++;
    281 			dst++;
    282 		}
    283 #endif
    284 		break;
    285 	    case SCROLL_DOWN:
    286 		dst = src + ((count * ip->cols)<<1);
    287 #ifdef CV_DONT_USE_CONBUFFER
    288 		len= (ip->bottom_margin + 1 - (sy + count)) * ip->cols;
    289 		dst += len << 1;
    290 		src += len << 1;
    291 		for (i = 0; i < len; i++) {
    292 			*dst-- = *src--;
    293 			dst--; src--;
    294 		}
    295 #else
    296 		len = (ip->bottom_margin + 1 - (sy + count)) * ip->cols;
    297 		src = &console_buffer[sy*ip->cols];
    298 		dst2 = &console_buffer[(sy+count)*ip->cols];
    299 		bcopy (src, dst2, len << 1);
    300 
    301 		for (i = 0; i < len; i++) {
    302 			*dst++ = *dst2++;
    303 			dst++;
    304 		}
    305 #endif
    306 		break;
    307 	    case SCROLL_RIGHT:
    308 		dst = src + ((sx+count)<<1);
    309 #ifdef CV_DONT_USE_CONBUFFER
    310 		src += sx << 1;
    311 		len = (ip->cols - (sx + count));
    312 		dst += (len-1) << 1;
    313 		src += (len-1) << 1;
    314 
    315 		for (i = 0; i < len ; i++) {
    316 			*dst-- = *src--;
    317 			dst--; src--;
    318 		}
    319 #else
    320 		src = &console_buffer[sy*ip->cols + sx];
    321 		len = ip->cols - (sx + count);
    322 		dst2 = &console_buffer[sy*ip->cols + sx + count];
    323 		bcopy (src, dst2, len << 1);
    324 
    325 		for (i = 0; i < len; i++) {
    326 			*dst++ = *dst2++;
    327 			dst++;
    328 		}
    329 #endif
    330 		break;
    331 	    case SCROLL_LEFT:
    332 		dst = src + ((sx - count)<<1);
    333 #ifdef CV_DONT_USE_CONBUFFER
    334 		src += sx << 1;
    335 		for (i = 0; i < (ip->cols - sx) ; i++) {
    336 			*dst++ = *src++;
    337 			dst++; src++;
    338 		}
    339 #else
    340 		src = &console_buffer[sy*ip->cols + sx];
    341 		len = ip->cols - sx;
    342 		dst2 = &console_buffer[sy*ip->cols + sx - count];
    343 		bcopy (src, dst2, len << 1);
    344 
    345 		for (i = 0; i < len; i++) {
    346 			*dst++ = *dst2++;
    347 			dst++;
    348 		}
    349 #endif
    350 	}
    351 }
    352 
    353 #endif /* NGRFCV */
    354