xref: /csrg-svn/sys/sparc/rcons/rcons_subr.c (revision 63321)
155133Storek /*
2*63321Sbostic  * Copyright (c) 1991, 1993
3*63321Sbostic  *	The Regents of the University of California.  All rights reserved.
455133Storek  *
555133Storek  * This software was developed by the Computer Systems Engineering group
655133Storek  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
755133Storek  * contributed to Berkeley.
855133Storek  *
955502Sbostic  * All advertising materials mentioning features or use of this software
1055502Sbostic  * must display the following acknowledgement:
1155502Sbostic  *	This product includes software developed by the University of
1259212Storek  *	California, Lawrence Berkeley Laboratory.
1355502Sbostic  *
1455133Storek  * %sccs.include.redist.c%
1555133Storek  *
16*63321Sbostic  *	@(#)rcons_subr.c	8.1 (Berkeley) 06/11/93
1755133Storek  *
1859212Storek  * from: $Header: rcons_subr.c,v 1.38 93/04/20 11:15:39 torek Exp $
1955133Storek  */
2055133Storek 
2155133Storek #ifdef KERNEL
2256539Sbostic #include <sys/param.h>
2356539Sbostic #include <sys/fbio.h>
2456539Sbostic #include <sys/device.h>
2556539Sbostic #include <machine/fbvar.h>
2655133Storek #else
2755133Storek #include <sys/types.h>
2855133Storek #include "myfbdevice.h"
2955133Storek #endif
3055133Storek 
3156539Sbostic #include <sparc/rcons/raster.h>
3255133Storek 
3355133Storek void rcons_text(struct fbdevice *, char *, int);
3455133Storek void rcons_pctrl(struct fbdevice *, int);
3555133Storek void rcons_esc(struct fbdevice *, int);
3655133Storek void rcons_doesc(struct fbdevice *, int);
3755133Storek void rcons_cursor(struct fbdevice *);
3855133Storek void rcons_invert(struct fbdevice *, int);
3955133Storek void rcons_clear2eop(struct fbdevice *);
4055133Storek void rcons_clear2eol(struct fbdevice *);
4155133Storek void rcons_scroll(struct fbdevice *, int);
4255133Storek void rcons_delchar(struct fbdevice *, int);
4355133Storek void rcons_delline(struct fbdevice *, int);
4455133Storek void rcons_insertchar(struct fbdevice *, int);
4555133Storek void rcons_insertline(struct fbdevice *, int);
4655133Storek 
4755133Storek extern void rcons_bell(struct fbdevice *);
4855133Storek 
4955133Storek #define RCONS_ISPRINT(c) ((c) >= ' ' && (c) <= '~')
5055133Storek #define RCONS_ISDIGIT(c) ((c) >= '0' && (c) <= '9')
5155133Storek 
5255133Storek /* Output (or at least handle) a string sent to the console */
5355133Storek void
rcons_puts(fb,str,n)5455133Storek rcons_puts(fb, str, n)
5555133Storek 	register struct fbdevice *fb;
5655133Storek 	register char *str;
5755133Storek 	register int n;
5855133Storek {
5955133Storek 	register int c, i, j;
6055133Storek 	register char *cp;
6155133Storek 
6255133Storek 	/* Jump scroll */
6355133Storek 	/* XXX maybe this should be an option? */
6455133Storek 	if ((fb->fb_bits & FB_INESC) == 0) {
6555133Storek 		/* Count newlines up to an escape sequence */
6655133Storek 		i = 0;
6755133Storek 		j = 0;
6855133Storek 		for (cp = str; j++ < n && *cp != '\033'; ++cp) {
6955133Storek 			if (*cp == '\n')
7055133Storek 				++i;
7155133Storek 			else if (*cp == '\013')
7255133Storek 				--i;
7355133Storek 		}
7455133Storek 
7555133Storek 		/* Only jump scroll two or more rows */
7655133Storek 		if (*fb->fb_row + i >= fb->fb_maxrow + 1) {
7755133Storek 			/* Erase the cursor (if necessary) */
7855133Storek 			if (fb->fb_bits & FB_CURSOR)
7955133Storek 				rcons_cursor(fb);
8055133Storek 
8155133Storek 			rcons_scroll(fb, i);
8255133Storek 		}
8355133Storek 	}
8455133Storek 
8555133Storek 	/* Process characters */
8655133Storek 	while (--n >= 0) {
8755133Storek 		c = *str;
8855133Storek 		if (c == '\033') {
8955133Storek 			/* Start an escape (perhaps aborting one in progress) */
9055133Storek 			fb->fb_bits |= FB_INESC | FB_P0_DEFAULT | FB_P1_DEFAULT;
9155133Storek 			fb->fb_bits &= ~(FB_P0 | FB_P1);
9255133Storek 
9355133Storek 			/* Most parameters default to 1 */
9455133Storek 			fb->fb_p0 = fb->fb_p1 = 1;
9555133Storek 		} else if (fb->fb_bits & FB_INESC) {
9655133Storek 			rcons_esc(fb, c);
9755133Storek 		} else {
9855133Storek 			/* Erase the cursor (if necessary) */
9955133Storek 			if (fb->fb_bits & FB_CURSOR)
10055133Storek 				rcons_cursor(fb);
10155133Storek 
10255133Storek 			/* Display the character */
10355133Storek 			if (RCONS_ISPRINT(c)) {
10455133Storek 				/* Try to output as much as possible */
10555133Storek 				j = fb->fb_maxcol - (*fb->fb_col + 1);
10655133Storek 				if (j > n)
10755133Storek 					j = n;
10855133Storek 				for (i = 1; i < j && RCONS_ISPRINT(str[i]); ++i)
10955133Storek 					continue;
11055133Storek 				rcons_text(fb, str, i);
11155133Storek 				--i;
11255133Storek 				str += i;
11355133Storek 				n -= i;
11455133Storek 			} else
11555133Storek 				rcons_pctrl(fb, c);
11655133Storek 		}
11755133Storek 		++str;
11855133Storek 	}
11955133Storek 	/* Redraw the cursor (if necessary) */
12055133Storek 	if ((fb->fb_bits & FB_CURSOR) == 0)
12155133Storek 		rcons_cursor(fb);
12255133Storek }
12355133Storek 
12455133Storek /* Actually write a string to the frame buffer */
12555133Storek void
rcons_text(fb,str,n)12655133Storek rcons_text(fb, str, n)
12755133Storek 	register struct fbdevice *fb;
12855133Storek 	register char *str;
12955133Storek 	register int n;
13055133Storek {
13155133Storek 	register int x, y, op;
13255133Storek 
13355133Storek 	x = *fb->fb_col * fb->fb_font->width + fb->fb_xorigin;
13455133Storek 	y = *fb->fb_row * fb->fb_font->height +
13555133Storek 	    fb->fb_font_ascent + fb->fb_yorigin;
13655133Storek 	op = RAS_SRC;
13755133Storek 	if (((fb->fb_bits & FB_STANDOUT) != 0) ^
13855133Storek 	    ((fb->fb_bits & FB_INVERT) != 0))
13955133Storek 		op = RAS_NOT(op);
14055133Storek 	raster_textn(fb->fb_sp, x, y, op, fb->fb_font, str, n);
14155133Storek 	*fb->fb_col += n;
14255133Storek 	if (*fb->fb_col >= fb->fb_maxcol) {
14355133Storek 		*fb->fb_col = 0;
14455133Storek 		(*fb->fb_row)++;
14555133Storek 	}
14655133Storek 	if (*fb->fb_row >= fb->fb_maxrow)
14755133Storek 		rcons_scroll(fb, 1);
14855133Storek }
14955133Storek 
15055133Storek /* Handle a control character sent to the console */
15155133Storek void
rcons_pctrl(fb,c)15255133Storek rcons_pctrl(fb, c)
15355133Storek 	register struct fbdevice *fb;
15455133Storek 	register int c;
15555133Storek {
15655133Storek 
15755133Storek 	switch (c) {
15855133Storek 
15955133Storek 	case '\r':	/* Carriage return */
16055133Storek 		*fb->fb_col = 0;
16155133Storek 		break;
16255133Storek 
16355133Storek 	case '\b':	/* Backspace */
16455133Storek 		if (*fb->fb_col > 0)
16555133Storek 			(*fb->fb_col)--;
16655133Storek 		break;
16755133Storek 
16855133Storek 	case '\013':	/* Vertical tab */
16955133Storek 		if (*fb->fb_row > 0)
17055133Storek 			(*fb->fb_row)--;
17155133Storek 		break;
17255133Storek 
17355133Storek 	case '\f':	/* Formfeed */
17455133Storek 		*fb->fb_row = *fb->fb_col = 0;
17555133Storek 		rcons_clear2eop(fb);
17655133Storek 		break;
17755133Storek 
17855133Storek 	case '\n':	/* Linefeed */
17955133Storek 		(*fb->fb_row)++;
18055133Storek 		if (*fb->fb_row >= fb->fb_maxrow)
18155133Storek 			rcons_scroll(fb, 1);
18255133Storek 		break;
18355133Storek 
18455133Storek 	case '\007':	/* Bell */
18555133Storek 		rcons_bell(fb);
18655133Storek 		break;
18755133Storek 
18855133Storek 	case '\t':	/* Horizontal tab */
18955133Storek 		*fb->fb_col = (*fb->fb_col + 8) & ~7;
19055133Storek 		if (*fb->fb_col >= fb->fb_maxcol)
19155133Storek 			*fb->fb_col = fb->fb_maxcol - 1;
19255133Storek 		break;
19355133Storek 	}
19455133Storek }
19555133Storek 
19655133Storek /* Handle the next character in an escape sequence */
19755133Storek void
rcons_esc(fb,c)19855133Storek rcons_esc(fb, c)
19955133Storek 	register struct fbdevice *fb;
20055133Storek 	register int c;
20155133Storek {
20255133Storek 
20355133Storek 	if (c == '[') {
20455133Storek 		/* Parameter 0 */
20555133Storek 		fb->fb_bits &= ~FB_P1;
20655133Storek 		fb->fb_bits |= FB_P0;
20755133Storek 	} else if (c == ';') {
20855133Storek 		/* Parameter 1 */
20955133Storek 		fb->fb_bits &= ~FB_P0;
21055133Storek 		fb->fb_bits |= FB_P1;
21155133Storek 	} else if (RCONS_ISDIGIT(c)) {
21255133Storek 		/* Add a digit to a parameter */
21355133Storek 		if (fb->fb_bits & FB_P0) {
21455133Storek 			/* Parameter 0 */
21555133Storek 			if (fb->fb_bits & FB_P0_DEFAULT) {
21655133Storek 				fb->fb_bits &= ~FB_P0_DEFAULT;
21755133Storek 				fb->fb_p0 = 0;
21855133Storek 			}
21955133Storek 			fb->fb_p0 *= 10;
22055133Storek 			fb->fb_p0 += c - '0';
22155133Storek 		} else if (fb->fb_bits & FB_P1) {
22255133Storek 			/* Parameter 1 */
22355133Storek 			if (fb->fb_bits & FB_P1_DEFAULT) {
22455133Storek 				fb->fb_bits &= ~FB_P1_DEFAULT;
22555133Storek 				fb->fb_p1 = 0;
22655133Storek 			}
22755133Storek 			fb->fb_p1 *= 10;
22855133Storek 			fb->fb_p1 += c - '0';
22955133Storek 		}
23055133Storek 	} else {
23155133Storek 		/* Erase the cursor (if necessary) */
23255133Storek 		if (fb->fb_bits & FB_CURSOR)
23355133Storek 			rcons_cursor(fb);
23455133Storek 
23555133Storek 		/* Process the completed escape sequence */
23655133Storek 		rcons_doesc(fb, c);
23755133Storek 		fb->fb_bits &= ~FB_INESC;
23855133Storek 	}
23955133Storek }
24055133Storek 
24155133Storek /* Process a complete escape sequence */
24255133Storek void
rcons_doesc(fb,c)24355133Storek rcons_doesc(fb, c)
24455133Storek 	register struct fbdevice *fb;
24555133Storek 	register int c;
24655133Storek {
24755133Storek 
24855133Storek #ifdef notdef
24955133Storek 	/* XXX add escape sequence to enable visual (and audible) bell */
25055133Storek 	fb->fb_bits = FB_VISBELL;
25155133Storek #endif
25255133Storek 
25355133Storek 	switch (c) {
25455133Storek 
25555133Storek 	case '@':
25655133Storek 		/* Insert Character (ICH) */
25755133Storek 		rcons_insertchar(fb, fb->fb_p0);
25855133Storek 		break;
25955133Storek 
26055133Storek 	case 'A':
26155133Storek 		/* Cursor Up (CUU) */
26255133Storek 		*fb->fb_row -= fb->fb_p0;
26355133Storek 		if (*fb->fb_row < 0)
26455133Storek 			*fb->fb_row = 0;
26555133Storek 		break;
26655133Storek 
26755133Storek 	case 'B':
26855133Storek 		/* Cursor Down (CUD) */
26955133Storek 		*fb->fb_row += fb->fb_p0;
27055133Storek 		if (*fb->fb_row >= fb->fb_maxrow)
27155133Storek 			*fb->fb_row = fb->fb_maxrow - 1;
27255133Storek 		break;
27355133Storek 
27455133Storek 	case 'C':
27555133Storek 		/* Cursor Forward (CUF) */
27655133Storek 		*fb->fb_col += fb->fb_p0;
27755133Storek 		if (*fb->fb_col >= fb->fb_maxcol)
27855133Storek 			*fb->fb_col = fb->fb_maxcol - 1;
27955133Storek 		break;
28055133Storek 
28155133Storek 	case 'D':
28255133Storek 		/* Cursor Backward (CUB) */
28355133Storek 		*fb->fb_col -= fb->fb_p0;
28455133Storek 		if (*fb->fb_col < 0)
28555133Storek 			*fb->fb_col = 0;
28655133Storek 		break;
28755133Storek 
28855133Storek 	case 'E':
28955133Storek 		/* Cursor Next Line (CNL) */
29055133Storek 		*fb->fb_col = 0;
29155133Storek 		*fb->fb_row += fb->fb_p0;
29255133Storek 		if (*fb->fb_row >= fb->fb_maxrow)
29355133Storek 			*fb->fb_row = fb->fb_maxrow - 1;
29455133Storek 		break;
29555133Storek 
29655133Storek 	case 'f':
29755133Storek 		/* Horizontal And Vertical Position (HVP) */
29855133Storek 	case 'H':
29955133Storek 		/* Cursor Position (CUP) */
30055133Storek 		*fb->fb_col = fb->fb_p1 - 1;
30155133Storek 		if (*fb->fb_col < 0)
30255133Storek 			*fb->fb_col = 0;
30355133Storek 		else if (*fb->fb_col >= fb->fb_maxcol)
30455133Storek 			*fb->fb_col = fb->fb_maxcol - 1;
30555133Storek 
30655133Storek 		*fb->fb_row = fb->fb_p0 - 1;
30755133Storek 		if (*fb->fb_row < 0)
30855133Storek 			*fb->fb_row = 0;
30955133Storek 		else if (*fb->fb_row >= fb->fb_maxrow)
31055133Storek 			*fb->fb_row = fb->fb_maxrow - 1;
31155133Storek 		break;
31255133Storek 
31355133Storek 	case 'J':
31455133Storek 		/* Erase in Display (ED) */
31555133Storek 		rcons_clear2eop(fb);
31655133Storek 		break;
31755133Storek 
31855133Storek 	case 'K':
31955133Storek 		/* Erase in Line (EL) */
32055133Storek 		rcons_clear2eol(fb);
32155133Storek 		break;
32255133Storek 
32355133Storek 	case 'L':
32455133Storek 		/* Insert Line (IL) */
32555133Storek 		rcons_insertline(fb, fb->fb_p0);
32655133Storek 		break;
32755133Storek 
32855133Storek 	case 'M':
32955133Storek 		/* Delete Line (DL) */
33055133Storek 		rcons_delline(fb, fb->fb_p0);
33155133Storek 		break;
33255133Storek 
33355133Storek 	case 'P':
33455133Storek 		/* Delete Character (DCH) */
33555133Storek 		rcons_delchar(fb, fb->fb_p0);
33655133Storek 		break;
33755133Storek 
33855133Storek 	case 'm':
33955133Storek 		/* Select Graphic Rendition (SGR); */
34055133Storek 		/* (defaults to zero) */
34155133Storek 		if (fb->fb_bits & FB_P0_DEFAULT)
34255133Storek 			fb->fb_p0 = 0;
34355133Storek 		if (fb->fb_p0)
34455133Storek 			fb->fb_bits |= FB_STANDOUT;
34555133Storek 		else
34655133Storek 			fb->fb_bits &= ~FB_STANDOUT;
34755133Storek 		break;
34855133Storek 
34955133Storek 	case 'p':
35055133Storek 		/* Black On White (SUNBOW) */
35155133Storek 		rcons_invert(fb, 0);
35255133Storek 		break;
35355133Storek 
35455133Storek 	case 'q':
35555133Storek 		/* White On Black (SUNWOB) */
35655133Storek 		rcons_invert(fb, 1);
35755133Storek 		break;
35855133Storek 
35955133Storek 	case 'r':
36055133Storek 		/* Set scrolling (SUNSCRL) */
36155133Storek 		/* (defaults to zero) */
36255133Storek 		if (fb->fb_bits & FB_P0_DEFAULT)
36355133Storek 			fb->fb_p0 = 0;
36455133Storek 		/* XXX not implemented yet */
36555133Storek 		fb->fb_scroll = fb->fb_p0;
36655133Storek 		break;
36755133Storek 
36855133Storek 	case 's':
36955133Storek 		/* Reset terminal emulator (SUNRESET) */
37055133Storek 		fb->fb_bits &= ~FB_STANDOUT;
37155133Storek 		fb->fb_scroll = 0;
37255133Storek 		if (fb->fb_bits & FB_INVERT)
37355133Storek 			rcons_invert(fb, 0);
37455133Storek 		break;
37555133Storek 	}
37655133Storek }
37755133Storek 
37855133Storek /* Paint (or unpaint) the cursor */
37955133Storek void
rcons_cursor(fb)38055133Storek rcons_cursor(fb)
38155133Storek 	register struct fbdevice *fb;
38255133Storek {
38355133Storek 	register int x, y;
38455133Storek 
38555133Storek 	x = *fb->fb_col * fb->fb_font->width + fb->fb_xorigin;
38655133Storek 	y = *fb->fb_row * fb->fb_font->height + fb->fb_yorigin;
38755133Storek 	raster_op(fb->fb_sp, x, y,
38855133Storek #ifdef notdef
38955133Storek 	    /* XXX This is the right way but too slow */
39055133Storek 	    fb->fb_font->chars[(int)' '].r->width,
39155133Storek 	    fb->fb_font->chars[(int)' '].r->height,
39255133Storek #else
39355133Storek 	    fb->fb_font->width, fb->fb_font->height,
39455133Storek #endif
39555133Storek 	    RAS_INVERT, (struct raster *) 0, 0, 0);
39655133Storek 	fb->fb_bits ^= FB_CURSOR;
39755133Storek }
39855133Storek 
39955133Storek /* Possibly change to SUNWOB or SUNBOW mode */
40055133Storek void
rcons_invert(fb,wob)40155133Storek rcons_invert(fb, wob)
40255133Storek 	struct fbdevice *fb;
40355133Storek 	int wob;
40455133Storek {
40555133Storek 	if (((fb->fb_bits & FB_INVERT) != 0) ^ wob) {
40655133Storek 		/* Invert the display */
40755133Storek 		raster_op(fb->fb_sp, 0, 0, fb->fb_sp->width, fb->fb_sp->height,
40855133Storek 		    RAS_INVERT, (struct raster *) 0, 0, 0);
40955133Storek 
41055133Storek 		/* Swap things around */
41155133Storek 		fb->fb_ras_blank = RAS_NOT(fb->fb_ras_blank);
41255133Storek 		fb->fb_bits ^= FB_INVERT;
41355133Storek 	}
41455133Storek }
41555133Storek 
41655133Storek /* Clear to the end of the page */
41755133Storek void
rcons_clear2eop(fb)41855133Storek rcons_clear2eop(fb)
41955133Storek 	register struct fbdevice *fb;
42055133Storek {
42155133Storek 	register int y;
42255133Storek 
42355133Storek 	if (*fb->fb_col == 0 && *fb->fb_row == 0) {
42455133Storek 		/* Clear the entire frame buffer */
42555133Storek 		raster_op(fb->fb_sp, 0, 0,
42655133Storek 		    fb->fb_sp->width, fb->fb_sp->height,
42755133Storek 		    fb->fb_ras_blank, (struct raster *) 0, 0, 0);
42855133Storek 	} else {
42955133Storek 		/* Only clear what needs to be cleared */
43055133Storek 		rcons_clear2eol(fb);
43155133Storek 		y = (*fb->fb_row + 1) * fb->fb_font->height;
43255133Storek 
43355133Storek 		raster_op(fb->fb_sp, fb->fb_xorigin, fb->fb_yorigin + y,
43455133Storek 		    fb->fb_emuwidth, fb->fb_emuheight - y,
43555133Storek 		    fb->fb_ras_blank, (struct raster *) 0, 0, 0);
43655133Storek 	}
43755133Storek }
43855133Storek 
43955133Storek /* Clear to the end of the line */
44055133Storek void
rcons_clear2eol(fb)44155133Storek rcons_clear2eol(fb)
44255133Storek 	register struct fbdevice *fb;
44355133Storek {
44455133Storek 	register int x;
44555133Storek 
44655133Storek 	x = *fb->fb_col * fb->fb_font->width;
44755133Storek 
44855133Storek 	raster_op(fb->fb_sp,
44955133Storek 	    fb->fb_xorigin + x,
45055133Storek 	    *fb->fb_row * fb->fb_font->height + fb->fb_yorigin,
45155133Storek 	    fb->fb_emuwidth - x, fb->fb_font->height,
45255133Storek 	    fb->fb_ras_blank, (struct raster *) 0, 0, 0);
45355133Storek }
45455133Storek 
45555133Storek /* Scroll up one line */
45655133Storek void
rcons_scroll(fb,n)45755133Storek rcons_scroll(fb, n)
45855133Storek 	register struct fbdevice *fb;
45955133Storek 	register int n;
46055133Storek {
46155133Storek 	register int ydiv;
46255133Storek 
46355133Storek 	/* Can't scroll more than the whole screen */
46455133Storek 	if (n > fb->fb_maxrow)
46555133Storek 		n = fb->fb_maxrow;
46655133Storek 
46755133Storek 	/* Calculate new row */
46855133Storek 	*fb->fb_row -= n;
46955133Storek 	if (*fb->fb_row < 0)
47055133Storek 		*fb->fb_row  = 0;
47155133Storek 
47255133Storek 	/* Calculate number of pixels to scroll */
47355133Storek 	ydiv = fb->fb_font->height * n;
47455133Storek 
47555133Storek 	raster_op(fb->fb_sp, fb->fb_xorigin, fb->fb_yorigin,
47655133Storek 	    fb->fb_emuwidth, fb->fb_emuheight - ydiv,
47755133Storek 	    RAS_SRC, fb->fb_sp, fb->fb_xorigin, ydiv + fb->fb_yorigin);
47855133Storek 
47955133Storek 	raster_op(fb->fb_sp,
48055133Storek 	    fb->fb_xorigin, fb->fb_yorigin + fb->fb_emuheight - ydiv,
48155133Storek 	    fb->fb_emuwidth, ydiv, fb->fb_ras_blank, (struct raster *) 0, 0, 0);
48255133Storek }
48355133Storek 
48455133Storek /* Delete characters */
48555133Storek void
rcons_delchar(fb,n)48655133Storek rcons_delchar(fb, n)
48755133Storek 	register struct fbdevice *fb;
48855133Storek 	register int n;
48955133Storek {
49055133Storek 	register int tox, fromx, y, width;
49155133Storek 
49255133Storek 	/* Can't delete more chars than there are */
49355133Storek 	if (n > fb->fb_maxcol - *fb->fb_col)
49455133Storek 		n = fb->fb_maxcol - *fb->fb_col;
49555133Storek 
49655133Storek 	fromx = (*fb->fb_col + n) * fb->fb_font->width;
49755133Storek 	tox = *fb->fb_col * fb->fb_font->width;
49855133Storek 	y = *fb->fb_row * fb->fb_font->height;
49955133Storek 	width = n * fb->fb_font->width;
50055133Storek 
50155133Storek 	raster_op(fb->fb_sp, tox + fb->fb_xorigin, y + fb->fb_yorigin,
50255133Storek 	    fb->fb_emuwidth - fromx, fb->fb_font->height,
50355133Storek 	    RAS_SRC, fb->fb_sp, fromx + fb->fb_xorigin, y + fb->fb_yorigin);
50455133Storek 
50555133Storek 	raster_op(fb->fb_sp,
50655133Storek 	    fb->fb_emuwidth - width + fb->fb_xorigin, y + fb->fb_yorigin,
50755133Storek 	    width, fb->fb_font->height,
50855133Storek 	    fb->fb_ras_blank, (struct raster *) 0, 0, 0);
50955133Storek }
51055133Storek 
51155133Storek /* Delete a number of lines */
51255133Storek void
rcons_delline(fb,n)51355133Storek rcons_delline(fb, n)
51455133Storek 	register struct fbdevice *fb;
51555133Storek 	register int n;
51655133Storek {
51755133Storek 	register int fromy, toy, height;
51855133Storek 
51955133Storek 	/* Can't delete more lines than there are */
52055133Storek 	if (n > fb->fb_maxrow - *fb->fb_row)
52155133Storek 		n = fb->fb_maxrow - *fb->fb_row;
52255133Storek 
52355133Storek 	fromy = (*fb->fb_row + n) * fb->fb_font->height;
52455133Storek 	toy = *fb->fb_row * fb->fb_font->height;
52555133Storek 	height = fb->fb_font->height * n;
52655133Storek 
52755133Storek 	raster_op(fb->fb_sp, fb->fb_xorigin, toy + fb->fb_yorigin,
52855133Storek 	    fb->fb_emuwidth, fb->fb_emuheight - fromy, RAS_SRC,
52955133Storek 	    fb->fb_sp, fb->fb_xorigin, fromy + fb->fb_yorigin);
53055133Storek 
53155133Storek 	raster_op(fb->fb_sp,
53255133Storek 	    fb->fb_xorigin, fb->fb_emuheight - height + fb->fb_yorigin,
53355133Storek 	    fb->fb_emuwidth, height,
53455133Storek 	    fb->fb_ras_blank, (struct raster *) 0, 0, 0);
53555133Storek }
53655133Storek 
53755133Storek /* Insert some characters */
53855133Storek void
rcons_insertchar(fb,n)53955133Storek rcons_insertchar(fb, n)
54055133Storek 	register struct fbdevice *fb;
54155133Storek 	register int n;
54255133Storek {
54355133Storek 	register int tox, fromx, y;
54455133Storek 
54555133Storek 	/* Can't insert more chars than can fit */
54655133Storek 	if (n > fb->fb_maxcol - *fb->fb_col)
54755133Storek 		n = fb->fb_maxcol - *fb->fb_col;
54855133Storek 
54955133Storek 	tox = (*fb->fb_col + n) * fb->fb_font->width;
55055133Storek 	fromx = *fb->fb_col * fb->fb_font->width;
55155133Storek 	y = *fb->fb_row * fb->fb_font->height;
55255133Storek 
55355133Storek 	raster_op(fb->fb_sp, tox + fb->fb_xorigin, y + fb->fb_yorigin,
55455133Storek 	    fb->fb_emuwidth - tox, fb->fb_font->height,
55555133Storek 	    RAS_SRC, fb->fb_sp, fromx + fb->fb_xorigin, y + fb->fb_yorigin);
55655133Storek 
55755133Storek 	raster_op(fb->fb_sp, fromx + fb->fb_xorigin, y + fb->fb_yorigin,
55855133Storek 	    fb->fb_font->width * n, fb->fb_font->height,
55955133Storek 	    fb->fb_ras_blank, (struct raster *) 0, 0, 0);
56055133Storek }
56155133Storek 
56255133Storek /* Insert some lines */
56355133Storek void
rcons_insertline(fb,n)56455133Storek rcons_insertline(fb, n)
56555133Storek 	register struct fbdevice *fb;
56655133Storek 	register int n;
56755133Storek {
56855133Storek 	register int fromy, toy;
56955133Storek 
57055133Storek 	/* Can't insert more lines than can fit */
57155133Storek 	if (n > fb->fb_maxrow - *fb->fb_row)
57255133Storek 		n = fb->fb_maxrow - *fb->fb_row;
57355133Storek 
57455133Storek 	toy = (*fb->fb_row + n) * fb->fb_font->height;
57555133Storek 	fromy = *fb->fb_row * fb->fb_font->height;
57655133Storek 
57755133Storek 	raster_op(fb->fb_sp, fb->fb_xorigin, toy + fb->fb_yorigin,
57855133Storek 	    fb->fb_emuwidth, fb->fb_emuheight - toy,
57955133Storek 	    RAS_SRC, fb->fb_sp, fb->fb_xorigin, fromy + fb->fb_yorigin);
58055133Storek 
58155133Storek 	raster_op(fb->fb_sp, fb->fb_xorigin, fromy + fb->fb_yorigin,
58255133Storek 	    fb->fb_emuwidth, fb->fb_font->height * n,
58355133Storek 	    fb->fb_ras_blank, (struct raster *) 0, 0, 0);
58455133Storek }
585