xref: /dragonfly/sys/dev/misc/syscons/scvgarndr.c (revision c89a6c1b)
1 /*-
2  * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
3  * All rights reserved.
4  *
5  * This code is derived from software contributed to The DragonFly Project
6  * by Sascha Wildner <saw@online.de>
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer as
13  *    the first lines of this file unmodified.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  *
29  * $FreeBSD: src/sys/dev/syscons/scvgarndr.c,v 1.5.2.3 2001/07/28 12:51:47 yokota Exp $
30  * $DragonFly: src/sys/dev/misc/syscons/scvgarndr.c,v 1.17 2008/08/10 19:45:01 swildner Exp $
31  */
32 
33 #include "opt_syscons.h"
34 #include "opt_vga.h"
35 
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/kernel.h>
39 
40 #include <machine/console.h>
41 
42 #include <dev/video/fb/fbreg.h>
43 #include <dev/video/fb/vgareg.h>
44 #include "syscons.h"
45 
46 #include <bus/isa/isareg.h>
47 
48 static vr_draw_border_t		vga_txtborder;
49 static vr_draw_t		vga_txtdraw;
50 static vr_set_cursor_t		vga_txtcursor_shape;
51 static vr_draw_cursor_t		vga_txtcursor;
52 static vr_blink_cursor_t	vga_txtblink;
53 #ifndef SC_NO_CUTPASTE
54 static vr_draw_mouse_t		vga_txtmouse;
55 #else
56 #define	vga_txtmouse		(vr_draw_mouse_t *)vga_nop
57 #endif
58 
59 #ifdef SC_PIXEL_MODE
60 static vr_draw_border_t		vga_pxlborder_direct;
61 static vr_draw_border_t		vga_pxlborder_packed;
62 static vr_draw_border_t		vga_pxlborder_planar;
63 static vr_draw_t		vga_vgadraw_direct;
64 static vr_draw_t		vga_vgadraw_packed;
65 static vr_draw_t		vga_vgadraw_planar;
66 static vr_set_cursor_t		vga_pxlcursor_shape;
67 static vr_draw_cursor_t		vga_pxlcursor_direct;
68 static vr_draw_cursor_t		vga_pxlcursor_packed;
69 static vr_draw_cursor_t		vga_pxlcursor_planar;
70 static vr_blink_cursor_t	vga_pxlblink_direct;
71 static vr_blink_cursor_t	vga_pxlblink_packed;
72 static vr_blink_cursor_t	vga_pxlblink_planar;
73 #ifndef SC_NO_CUTPASTE
74 static vr_draw_mouse_t		vga_pxlmouse_direct;
75 static vr_draw_mouse_t		vga_pxlmouse_packed;
76 static vr_draw_mouse_t		vga_pxlmouse_planar;
77 #else
78 #define	vga_pxlmouse_direct	(vr_draw_mouse_t *)vga_nop
79 #define	vga_pxlmouse_packed	(vr_draw_mouse_t *)vga_nop
80 #define	vga_pxlmouse_planar	(vr_draw_mouse_t *)vga_nop
81 #endif
82 #endif /* SC_PIXEL_MODE */
83 
84 #ifndef SC_NO_MODE_CHANGE
85 static vr_draw_border_t		vga_grborder;
86 #endif
87 
88 static void			vga_nop(scr_stat *scp, ...);
89 
90 static sc_rndr_sw_t txtrndrsw = {
91 	vga_txtborder,
92 	vga_txtdraw,
93 	vga_txtcursor_shape,
94 	vga_txtcursor,
95 	vga_txtblink,
96 	vga_txtmouse,
97 };
98 RENDERER(vga, V_INFO_MM_TEXT, txtrndrsw, vga_set);
99 
100 #ifdef SC_PIXEL_MODE
101 static sc_rndr_sw_t directrndrsw = {
102 	vga_pxlborder_direct,
103 	vga_vgadraw_direct,
104 	vga_pxlcursor_shape,
105 	vga_pxlcursor_direct,
106 	vga_pxlblink_direct,
107 	vga_pxlmouse_direct,
108 };
109 RENDERER(vga, V_INFO_MM_DIRECT, directrndrsw, vga_set);
110 
111 static sc_rndr_sw_t packedrndrsw = {
112 	vga_pxlborder_packed,
113 	vga_vgadraw_packed,
114 	vga_pxlcursor_shape,
115 	vga_pxlcursor_packed,
116 	vga_pxlblink_packed,
117 	vga_pxlmouse_packed,
118 };
119 RENDERER(vga, V_INFO_MM_PACKED, packedrndrsw, vga_set);
120 
121 static sc_rndr_sw_t planarrndrsw = {
122 	vga_pxlborder_planar,
123 	vga_vgadraw_planar,
124 	vga_pxlcursor_shape,
125 	vga_pxlcursor_planar,
126 	vga_pxlblink_planar,
127 	vga_pxlmouse_planar,
128 };
129 RENDERER(vga, V_INFO_MM_PLANAR, planarrndrsw, vga_set);
130 #endif /* SC_PIXEL_MODE */
131 
132 #ifndef SC_NO_MODE_CHANGE
133 static sc_rndr_sw_t grrndrsw = {
134 	vga_grborder,
135 	(vr_draw_t *)vga_nop,
136 	(vr_set_cursor_t *)vga_nop,
137 	(vr_draw_cursor_t *)vga_nop,
138 	(vr_blink_cursor_t *)vga_nop,
139 	(vr_draw_mouse_t *)vga_nop,
140 };
141 RENDERER(vga, V_INFO_MM_OTHER, grrndrsw, vga_set);
142 #endif /* SC_NO_MODE_CHANGE */
143 
144 RENDERER_MODULE(vga, vga_set);
145 
146 #ifndef SC_NO_CUTPASTE
147 static u_short mouse_and_mask[16] = {
148 	0xc000, 0xe000, 0xf000, 0xf800, 0xfc00, 0xfe00, 0xff00, 0xff80,
149 	0xfe00, 0x1e00, 0x1f00, 0x0f00, 0x0f00, 0x0000, 0x0000, 0x0000
150 };
151 static u_short mouse_or_mask[16] = {
152 	0x0000, 0x4000, 0x6000, 0x7000, 0x7800, 0x7c00, 0x7e00, 0x6800,
153 	0x0c00, 0x0c00, 0x0600, 0x0600, 0x0000, 0x0000, 0x0000, 0x0000
154 };
155 #endif
156 
157 static void
158 vga_nop(scr_stat *scp, ...)
159 {
160 }
161 
162 /* text mode renderer */
163 
164 static void
165 vga_txtborder(scr_stat *scp, int color)
166 {
167 	(*vidsw[scp->sc->adapter]->set_border)(scp->sc->adp, color);
168 }
169 
170 static void
171 vga_txtdraw(scr_stat *scp, int from, int count, int flip)
172 {
173 	uint16_t *p;
174 	int c;
175 	int a;
176 
177 	if (from + count > scp->xsize*scp->ysize)
178 		count = scp->xsize*scp->ysize - from;
179 
180 	if (flip) {
181 		for (p = scp->scr.vtb_buffer + from; count-- > 0; ++from) {
182 			c = sc_vtb_getc(&scp->vtb, from);
183 			a = sc_vtb_geta(&scp->vtb, from);
184 			a = (a & 0x8800) | ((a & 0x7000) >> 4)
185 				| ((a & 0x0700) << 4);
186 			p = sc_vtb_putchar(&scp->scr, p, c, a);
187 		}
188 	} else {
189 		sc_vtb_copy(&scp->vtb, from, &scp->scr, from, count);
190 	}
191 }
192 
193 static void
194 vga_txtcursor_shape(scr_stat *scp, int base, int height, int blink)
195 {
196 	if (base < 0 || base >= scp->font_size)
197 		return;
198 	/* the caller may set height <= 0 in order to disable the cursor */
199 #if 0
200 	scp->cursor_base = base;
201 	scp->cursor_height = height;
202 #endif
203 	(*vidsw[scp->sc->adapter]->set_hw_cursor_shape)(scp->sc->adp,
204 							base, height,
205 							scp->font_size, blink);
206 }
207 
208 static void
209 draw_txtcharcursor(scr_stat *scp, int at, u_short c, u_short a, int flip)
210 {
211 	sc_softc_t *sc;
212 
213 	sc = scp->sc;
214 	scp->cursor_saveunder_char = c;
215 	scp->cursor_saveunder_attr = a;
216 
217 #ifndef SC_NO_FONT_LOADING
218 	if (sc->flags & SC_CHAR_CURSOR) {
219 		unsigned char *font;
220 		int h;
221 		int i;
222 
223 		if (scp->font_size < 14) {
224 			font = sc->font_8;
225 			h = 8;
226 		} else if (scp->font_size >= 16) {
227 			font = sc->font_16;
228 			h = 16;
229 		} else {
230 			font = sc->font_14;
231 			h = 14;
232 		}
233 		if (scp->cursor_base >= h)
234 			return;
235 		if (flip)
236 			a = (a & 0x8800)
237 				| ((a & 0x7000) >> 4) | ((a & 0x0700) << 4);
238 		bcopy(font + c*h, font + sc->cursor_char*h, h);
239 		font = font + sc->cursor_char*h;
240 		for (i = imax(h - scp->cursor_base - scp->cursor_height, 0);
241 			i < h - scp->cursor_base; ++i) {
242 			font[i] ^= 0xff;
243 		}
244 		sc->font_loading_in_progress = TRUE;
245 		/* XXX */
246 		(*vidsw[sc->adapter]->load_font)(sc->adp, 0, h, font,
247 						 sc->cursor_char, 1);
248 		sc->font_loading_in_progress = FALSE;
249 		sc_vtb_putc(&scp->scr, at, sc->cursor_char, a);
250 	} else
251 #endif /* SC_NO_FONT_LOADING */
252 	{
253 		if ((a & 0x7000) == 0x7000) {
254 			a &= 0x8f00;
255 			if ((a & 0x0700) == 0)
256 				a |= 0x0700;
257 		} else {
258 			a |= 0x7000;
259 			if ((a & 0x0700) == 0x0700)
260 				a &= 0xf000;
261 		}
262 		if (flip)
263 			a = (a & 0x8800)
264 				| ((a & 0x7000) >> 4) | ((a & 0x0700) << 4);
265 		sc_vtb_putc(&scp->scr, at, c, a);
266 	}
267 }
268 
269 static void
270 vga_txtcursor(scr_stat *scp, int at, int blink, int on, int flip)
271 {
272 	video_adapter_t *adp;
273 	int cursor_attr;
274 
275 	if (scp->cursor_height <= 0)	/* the text cursor is disabled */
276 		return;
277 
278 	adp = scp->sc->adp;
279 	if (blink) {
280 		scp->status |= VR_CURSOR_BLINK;
281 		if (on) {
282 			scp->status |= VR_CURSOR_ON;
283 			(*vidsw[adp->va_index]->set_hw_cursor)(adp,
284 							       at%scp->xsize,
285 							       at/scp->xsize);
286 		} else {
287 			if (scp->status & VR_CURSOR_ON)
288 				(*vidsw[adp->va_index]->set_hw_cursor)(adp,
289 								       -1, -1);
290 			scp->status &= ~VR_CURSOR_ON;
291 		}
292 	} else {
293 		scp->status &= ~VR_CURSOR_BLINK;
294 		if (on) {
295 			scp->status |= VR_CURSOR_ON;
296 			draw_txtcharcursor(scp, at,
297 					   sc_vtb_getc(&scp->scr, at),
298 					   sc_vtb_geta(&scp->scr, at),
299 					   flip);
300 		} else {
301 			cursor_attr = scp->cursor_saveunder_attr;
302 			if (flip)
303 				cursor_attr = (cursor_attr & 0x8800)
304 					| ((cursor_attr & 0x7000) >> 4)
305 					| ((cursor_attr & 0x0700) << 4);
306 			if (scp->status & VR_CURSOR_ON)
307 				sc_vtb_putc(&scp->scr, at,
308 					    scp->cursor_saveunder_char,
309 					    cursor_attr);
310 			scp->status &= ~VR_CURSOR_ON;
311 		}
312 	}
313 }
314 
315 static void
316 vga_txtblink(scr_stat *scp, int at, int flip)
317 {
318 }
319 
320 #ifndef SC_NO_CUTPASTE
321 
322 static void
323 draw_txtmouse(scr_stat *scp, int x, int y)
324 {
325 #ifndef SC_ALT_MOUSE_IMAGE
326     if (ISMOUSEAVAIL(scp->sc->adp->va_flags)) {
327 	u_char font_buf[128];
328 	u_short cursor[32];
329 	u_char c;
330 	int pos;
331 	int xoffset, yoffset;
332 	int i;
333 
334 	/* prepare mousepointer char's bitmaps */
335 	pos = (y/scp->font_size - scp->yoff)*scp->xsize + x/8 - scp->xoff;
336 	bcopy(scp->font + sc_vtb_getc(&scp->scr, pos)*scp->font_size,
337 	      &font_buf[0], scp->font_size);
338 	bcopy(scp->font + sc_vtb_getc(&scp->scr, pos + 1)*scp->font_size,
339 	      &font_buf[32], scp->font_size);
340 	bcopy(scp->font
341 		 + sc_vtb_getc(&scp->scr, pos + scp->xsize)*scp->font_size,
342 	      &font_buf[64], scp->font_size);
343 	bcopy(scp->font
344 		 + sc_vtb_getc(&scp->scr, pos + scp->xsize + 1)*scp->font_size,
345 	      &font_buf[96], scp->font_size);
346 	for (i = 0; i < scp->font_size; ++i) {
347 		cursor[i] = font_buf[i]<<8 | font_buf[i+32];
348 		cursor[i + scp->font_size] = font_buf[i+64]<<8 | font_buf[i+96];
349 	}
350 
351 	/* now and-or in the mousepointer image */
352 	xoffset = x%8;
353 	yoffset = y%scp->font_size;
354 	for (i = 0; i < 16; ++i) {
355 		cursor[i + yoffset] =
356 	    		(cursor[i + yoffset] & ~(mouse_and_mask[i] >> xoffset))
357 	    		| (mouse_or_mask[i] >> xoffset);
358 	}
359 	for (i = 0; i < scp->font_size; ++i) {
360 		font_buf[i] = (cursor[i] & 0xff00) >> 8;
361 		font_buf[i + 32] = cursor[i] & 0xff;
362 		font_buf[i + 64] = (cursor[i + scp->font_size] & 0xff00) >> 8;
363 		font_buf[i + 96] = cursor[i + scp->font_size] & 0xff;
364 	}
365 
366 #if 1
367 	/* wait for vertical retrace to avoid jitter on some videocards */
368 	while (!(inb(CRTC + 6) & 0x08)) /* idle */ ;
369 #endif
370 	c = scp->sc->mouse_char;
371 	(*vidsw[scp->sc->adapter]->load_font)(scp->sc->adp, 0, 32, font_buf,
372 					      c, 4);
373 
374 	sc_vtb_putc(&scp->scr, pos, c, sc_vtb_geta(&scp->scr, pos));
375 	/* FIXME: may be out of range! */
376 	sc_vtb_putc(&scp->scr, pos + scp->xsize, c + 2,
377 		    sc_vtb_geta(&scp->scr, pos + scp->xsize));
378 	if (x < (scp->xsize - 1)*8) {
379 		sc_vtb_putc(&scp->scr, pos + 1, c + 1,
380 			    sc_vtb_geta(&scp->scr, pos + 1));
381 		sc_vtb_putc(&scp->scr, pos + scp->xsize + 1, c + 3,
382 			    sc_vtb_geta(&scp->scr, pos + scp->xsize + 1));
383 	}
384     } else
385 #endif /* SC_ALT_MOUSE_IMAGE */
386     {
387 	/* Red, magenta and brown are mapped to green to to keep it readable */
388 	static const int col_conv[16] = {
389 		6, 6, 6, 6, 2, 2, 2, 6, 14, 14, 14, 14, 10, 10, 10, 14
390 	};
391 	int pos;
392 	int color;
393 	int a;
394 
395 	pos = (y/scp->font_size - scp->yoff)*scp->xsize + x/8 - scp->xoff;
396 	a = sc_vtb_geta(&scp->scr, pos);
397 	if (scp->sc->adp->va_flags & V_ADP_COLOR)
398 		color = (col_conv[(a & 0xf000) >> 12] << 12)
399 			| ((a & 0x0f00) | 0x0800);
400 	else
401 		color = ((a & 0xf000) >> 4) | ((a & 0x0f00) << 4);
402 	sc_vtb_putc(&scp->scr, pos, sc_vtb_getc(&scp->scr, pos), color);
403     }
404 }
405 
406 static void
407 remove_txtmouse(scr_stat *scp, int x, int y)
408 {
409 }
410 
411 static void
412 vga_txtmouse(scr_stat *scp, int x, int y, int on)
413 {
414 	if (on)
415 		draw_txtmouse(scp, x, y);
416 	else
417 		remove_txtmouse(scp, x, y);
418 }
419 
420 #endif /* SC_NO_CUTPASTE */
421 
422 #ifdef SC_PIXEL_MODE
423 
424 /* pixel (raster text) mode renderer */
425 
426 static void
427 vga_pxlborder_direct(scr_stat *scp, int color)
428 {
429 	int i, x, y;
430 	int line_width, pixel_size;
431 	uint32_t u32 = 0;
432 	vm_offset_t draw_pos, draw_end, p;
433 
434 	line_width = scp->sc->adp->va_line_width;
435 	pixel_size = scp->sc->adp->va_info.vi_pixel_size;
436 
437 	for (i = 0; i < 4 / pixel_size; ++i)
438 		u32 += scp->ega_palette[color] << (i * 8 * pixel_size);
439 
440 	if (scp->yoff > 0) {
441 		draw_pos = scp->sc->adp->va_window;
442 		draw_end = draw_pos + line_width * scp->yoff * scp->font_size;
443 
444 		for (p = draw_pos; p < draw_end; p += 4)
445 			writel(p, u32);
446 	}
447 
448 	y = (scp->yoff + scp->ysize) * scp->font_size;
449 
450 	if (scp->ypixel > y) {
451 		draw_pos = scp->sc->adp->va_window + line_width * y;
452 		draw_end = draw_pos + line_width * (scp->ypixel - y);
453 
454 		for (p = draw_pos; p < draw_end; p += 4)
455 			writel(p, u32);
456 	}
457 
458 	y = scp->yoff * scp->font_size;
459 	x = scp->xpixel / 8 - scp->xoff - scp->xsize;
460 
461 	for (i = 0; i < scp->ysize * scp->font_size; ++i) {
462 		if (scp->xoff > 0) {
463 			draw_pos = scp->sc->adp->va_window +
464 			    line_width * (y + i);
465 			draw_end = draw_pos + scp->xoff * 8 * pixel_size;
466 
467 			for (p = draw_pos; p < draw_end; p += 4)
468 				writel(p, u32);
469 		}
470 
471 		if (x > 0) {
472 			draw_pos = scp->sc->adp->va_window +
473 			    line_width * (y + i) +
474 			    scp->xoff * 8 * pixel_size +
475 			    scp->xsize * 8 * pixel_size;
476 			draw_end = draw_pos + x * 8 * pixel_size;
477 
478 			for (p = draw_pos; p < draw_end; p += 4)
479 				writel(p, u32);
480 		}
481 	}
482 }
483 
484 static void
485 vga_pxlborder_packed(scr_stat *scp, int color)
486 {
487 	int i, x, y;
488 	int line_width;
489 	uint32_t u32;
490 	vm_offset_t draw_pos, draw_end, p;
491 
492 	line_width = scp->sc->adp->va_line_width;
493 	u32 = (color << 24) + (color << 16) + (color << 8) + color;
494 
495 	if (scp->yoff > 0) {
496 		draw_pos = scp->sc->adp->va_window;
497 		draw_end = draw_pos + line_width * scp->yoff * scp->font_size;
498 
499 		for (p = draw_pos; p < draw_end; p += 4)
500 			writel(p, u32);
501 	}
502 
503 	y = (scp->yoff + scp->ysize) * scp->font_size;
504 
505 	if (scp->ypixel > y) {
506 		draw_pos = scp->sc->adp->va_window + line_width * y;
507 		draw_end = draw_pos + line_width * (scp->ypixel - y);
508 
509 		for (p = draw_pos; p < draw_end; p += 4)
510 			writel(p, u32);
511 	}
512 
513 	y = scp->yoff * scp->font_size;
514 	x = scp->xpixel / 8 - scp->xoff - scp->xsize;
515 
516 	for (i = 0; i < scp->ysize * scp->font_size; ++i) {
517 		if (scp->xoff > 0) {
518 			draw_pos = scp->sc->adp->va_window +
519 			    line_width * (y + i);
520 			draw_end = draw_pos + scp->xoff * 8;
521 
522 			for (p = draw_pos; p < draw_end; p += 4)
523 				writel(p, u32);
524 		}
525 
526 		if (x > 0) {
527 			draw_pos = scp->sc->adp->va_window +
528 			    line_width * (y + i) + scp->xoff * 8 +
529 			    scp->xsize * 8;
530 			draw_end = draw_pos + x * 8;
531 
532 			for (p = draw_pos; p < draw_end; p += 4)
533 				writel(p, u32);
534 		}
535 	}
536 }
537 
538 static void
539 vga_pxlborder_planar(scr_stat *scp, int color)
540 {
541 	vm_offset_t p;
542 	int line_width;
543 	int x;
544 	int y;
545 	int i;
546 
547 	(*vidsw[scp->sc->adapter]->set_border)(scp->sc->adp, color);
548 
549 	outw(GDCIDX, 0x0005);		/* read mode 0, write mode 0 */
550 	outw(GDCIDX, 0x0003);		/* data rotate/function select */
551 	outw(GDCIDX, 0x0f01);		/* set/reset enable */
552 	outw(GDCIDX, 0xff08);		/* bit mask */
553 	outw(GDCIDX, (color << 8) | 0x00);	/* set/reset */
554 	line_width = scp->sc->adp->va_line_width;
555 	p = scp->sc->adp->va_window;
556 	if (scp->yoff > 0)
557 		bzero_io((void *)p, line_width*scp->yoff*scp->font_size);
558 	y = (scp->yoff + scp->ysize)*scp->font_size;
559 	if (scp->ypixel > y)
560 		bzero_io((void *)(p + line_width*y), line_width*(scp->ypixel - y));
561 	y = scp->yoff*scp->font_size;
562 	x = scp->xpixel/8 - scp->xoff - scp->xsize;
563 	for (i = 0; i < scp->ysize*scp->font_size; ++i) {
564 		if (scp->xoff > 0)
565 			bzero_io((void *)(p + line_width*(y + i)), scp->xoff);
566 		if (x > 0)
567 			bzero_io((void *)(p + line_width*(y + i)
568 				     + scp->xoff + scp->xsize), x);
569 	}
570 	outw(GDCIDX, 0x0000);		/* set/reset */
571 	outw(GDCIDX, 0x0001);		/* set/reset enable */
572 }
573 
574 static void
575 vga_vgadraw_direct(scr_stat *scp, int from, int count, int flip)
576 {
577 	int line_width, pixel_size;
578 	int a, i, j, k, l, pos;
579 	uint32_t fg, bg, u32;
580 	unsigned char *char_data;
581 	vm_offset_t draw_pos, p;
582 
583 	line_width = scp->sc->adp->va_line_width;
584 	pixel_size = scp->sc->adp->va_info.vi_pixel_size;
585 
586 	draw_pos = VIDEO_MEMORY_POS(scp, from, 8 * pixel_size);
587 
588 	if (from + count > scp->xsize * scp->ysize)
589 		count = scp->xsize * scp->ysize - from;
590 
591 	for (i = from; count-- > 0; ++i) {
592 		a = sc_vtb_geta(&scp->vtb, i);
593 
594 		if (flip) {
595 			fg = scp->ega_palette[(((a & 0x7000) >> 4) |
596 			    (a & 0x0800)) >> 8];
597 			bg = scp->ega_palette[(((a & 0x8000) >> 4) |
598 			    (a & 0x0700)) >> 8];
599 		} else {
600 			fg = scp->ega_palette[(a & 0x0f00) >> 8];
601 			bg = scp->ega_palette[(a & 0xf000) >> 12];
602 		}
603 
604 		p = draw_pos;
605 		char_data = &(scp->font[sc_vtb_getc(&scp->vtb, i) *
606 		    scp->font_size]);
607 
608 		for (j = 0; j < scp->font_size; ++j, ++char_data) {
609 			pos = 7;
610 
611 			for (k = 0; k < 2 * pixel_size; ++k) {
612 				u32 = 0;
613 
614 				for (l = 0; l < 4 / pixel_size; ++l) {
615 					u32 += (*char_data & (1 << pos--) ?
616 					    fg : bg) << (l * 8 * pixel_size);
617 				}
618 
619 				writel(p, u32);
620 				p += 4;
621 			}
622 
623 			p += line_width - 8 * pixel_size;
624 		}
625 
626 		draw_pos += 8 * pixel_size;
627 
628 		if ((i % scp->xsize) == scp->xsize - 1)
629 			draw_pos += scp->xoff * 16 * pixel_size +
630 			     (scp->font_size - 1) * line_width;
631 	}
632 }
633 
634 static void
635 vga_vgadraw_packed(scr_stat *scp, int from, int count, int flip)
636 {
637 	int line_width;
638 	int a, i, j;
639 	uint32_t fg, bg, u32;
640 	unsigned char *char_data;
641 	vm_offset_t draw_pos, p;
642 
643 	line_width = scp->sc->adp->va_line_width;
644 
645 	draw_pos = VIDEO_MEMORY_POS(scp, from, 8);
646 
647 	if (from + count > scp->xsize * scp->ysize)
648 		count = scp->xsize * scp->ysize - from;
649 
650 	for (i = from; count-- > 0; ++i) {
651 		a = sc_vtb_geta(&scp->vtb, i);
652 
653 		if (flip) {
654 			fg = ((a & 0xf000) >> 4) >> 8;
655 			bg = (a & 0x0f00) >> 8;
656 		} else {
657 			fg = (a & 0x0f00) >> 8;
658 			bg = ((a & 0xf000) >> 4) >> 8;
659 		}
660 
661 		p = draw_pos;
662 		char_data = &(scp->font[sc_vtb_getc(&scp->vtb, i) *
663 		    scp->font_size]);
664 
665 		for (j = 0; j < scp->font_size; ++j, ++char_data) {
666 			u32 = ((*char_data & 1 ? fg : bg) << 24) +
667 			      ((*char_data & 2 ? fg : bg) << 16) +
668 			      ((*char_data & 4 ? fg : bg) << 8) +
669 			      (*char_data & 8 ? fg : bg);
670 			writel(p + 4, u32);
671 
672 			u32 = ((*char_data & 16 ? fg : bg) << 24) +
673 			      ((*char_data & 32 ? fg : bg) << 16) +
674 			      ((*char_data & 64 ? fg : bg) << 8) +
675 			      (*char_data & 128 ? fg : bg);
676 			writel(p, u32);
677 
678 			p += line_width;
679 		}
680 
681 		draw_pos += 8;
682 
683 		if ((i % scp->xsize) == scp->xsize - 1)
684 			draw_pos += scp->xoff * 16 +
685 			     (scp->font_size - 1) * line_width;
686 	}
687 }
688 
689 static void
690 vga_vgadraw_planar(scr_stat *scp, int from, int count, int flip)
691 {
692 	vm_offset_t d;
693 	vm_offset_t e;
694 	u_char *f;
695 	u_short bg;
696 	u_short col1, col2;
697 	int line_width;
698 	int i, j;
699 	int a;
700 	u_char c;
701 
702 	d = VIDEO_MEMORY_POS(scp, from, 1);
703 
704 	line_width = scp->sc->adp->va_line_width;
705 
706 	outw(GDCIDX, 0x0305);		/* read mode 0, write mode 3 */
707 	outw(GDCIDX, 0x0003);		/* data rotate/function select */
708 	outw(GDCIDX, 0x0f01);		/* set/reset enable */
709 	outw(GDCIDX, 0xff08);		/* bit mask */
710 	bg = -1;
711 	if (from + count > scp->xsize*scp->ysize)
712 		count = scp->xsize*scp->ysize - from;
713 	for (i = from; count-- > 0; ++i) {
714 		a = sc_vtb_geta(&scp->vtb, i);
715 		if (flip) {
716 			col1 = ((a & 0x7000) >> 4) | (a & 0x0800);
717 			col2 = ((a & 0x8000) >> 4) | (a & 0x0700);
718 		} else {
719 			col1 = (a & 0x0f00);
720 			col2 = (a & 0xf000) >> 4;
721 		}
722 		/* set background color in EGA/VGA latch */
723 		if (bg != col2) {
724 			bg = col2;
725 			outw(GDCIDX, 0x0005);	/* read mode 0, write mode 0 */
726 			outw(GDCIDX, bg | 0x00); /* set/reset */
727 			writeb(d, 0);
728 			c = readb(d);		/* set bg color in the latch */
729 			outw(GDCIDX, 0x0305);	/* read mode 0, write mode 3 */
730 		}
731 		/* foreground color */
732 		outw(GDCIDX, col1 | 0x00);	/* set/reset */
733 		e = d;
734 		f = &(scp->font[sc_vtb_getc(&scp->vtb, i)*scp->font_size]);
735 		for (j = 0; j < scp->font_size; ++j, ++f) {
736 	        	writeb(e, *f);
737 			e += line_width;
738 		}
739 		++d;
740 		if ((i % scp->xsize) == scp->xsize - 1)
741 			d += scp->xoff*2
742 				 + (scp->font_size - 1)*line_width;
743 	}
744 	outw(GDCIDX, 0x0005);		/* read mode 0, write mode 0 */
745 	outw(GDCIDX, 0x0000);		/* set/reset */
746 	outw(GDCIDX, 0x0001);		/* set/reset enable */
747 }
748 
749 static void
750 vga_pxlcursor_shape(scr_stat *scp, int base, int height, int blink)
751 {
752 	if (base < 0 || base >= scp->font_size)
753 		return;
754 	/* the caller may set height <= 0 in order to disable the cursor */
755 #if 0
756 	scp->cursor_base = base;
757 	scp->cursor_height = height;
758 #endif
759 }
760 
761 static void
762 draw_pxlcursor_direct(scr_stat *scp, int at, int on, int flip)
763 {
764 	int line_width, pixel_size, height;
765 	int a, i, j, k, pos;
766 	uint32_t fg, bg, u32;
767 	unsigned char *char_data;
768 	vm_offset_t draw_pos;
769 
770 	line_width = scp->sc->adp->va_line_width;
771 	pixel_size = scp->sc->adp->va_info.vi_pixel_size;
772 
773 	draw_pos = VIDEO_MEMORY_POS(scp, at, 8 * pixel_size) +
774 	    (scp->font_size - scp->cursor_base - 1) * line_width;
775 
776 	a = sc_vtb_geta(&scp->vtb, at);
777 
778 	if (flip) {
779 		fg = scp->ega_palette[((on) ? (a & 0x0f00) :
780 		    ((a & 0xf000) >> 4)) >> 8];
781 		bg = scp->ega_palette[((on) ? ((a & 0xf000) >> 4) :
782 		    (a & 0x0f00)) >> 8];
783 	} else {
784 		fg = scp->ega_palette[((on) ? ((a & 0xf000) >> 4) :
785 		    (a & 0x0f00)) >> 8];
786 		bg = scp->ega_palette[((on) ? (a & 0x0f00) :
787 		    ((a & 0xf000) >> 4)) >> 8];
788 	}
789 
790 	char_data = &(scp->font[sc_vtb_getc(&scp->vtb, at) * scp->font_size +
791 	    scp->font_size - scp->cursor_base - 1]);
792 
793 	height = imin(scp->cursor_height, scp->font_size);
794 
795 	for (i = 0; i < height; ++i, --char_data) {
796 		pos = 7;
797 
798 		for (j = 0; j < 2 * pixel_size; ++j) {
799 			u32 = 0;
800 
801 			for (k = 0; k < 4 / pixel_size; ++k) {
802 				u32 += (*char_data & (1 << pos--) ?
803 				    fg : bg) << (k * 8 * pixel_size);
804 			}
805 
806 			writel(draw_pos, u32);
807 			draw_pos += 4;
808 		}
809 
810 		draw_pos -= line_width + 8 * pixel_size;
811 	}
812 }
813 
814 static void
815 draw_pxlcursor_packed(scr_stat *scp, int at, int on, int flip)
816 {
817 	int line_width, height;
818 	int a, i;
819 	uint32_t fg, bg, u32;
820 	unsigned char *char_data;
821 	vm_offset_t draw_pos;
822 
823 	line_width = scp->sc->adp->va_line_width;
824 
825 	draw_pos = VIDEO_MEMORY_POS(scp, at, 8) +
826 	    (scp->font_size - scp->cursor_base - 1) * line_width;
827 
828 	a = sc_vtb_geta(&scp->vtb, at);
829 
830 	if (flip) {
831 		fg = ((on) ? (a & 0x0f00) : ((a & 0xf000) >> 4)) >> 8;
832 		bg = ((on) ? ((a & 0xf000) >> 4) : (a & 0x0f00)) >> 8;
833 	} else {
834 		fg = ((on) ? ((a & 0xf000) >> 4) : (a & 0x0f00)) >> 8;
835 		bg = ((on) ? (a & 0x0f00) : ((a & 0xf000) >> 4)) >> 8;
836 	}
837 
838 	char_data = &(scp->font[sc_vtb_getc(&scp->vtb, at) * scp->font_size +
839 	    scp->font_size - scp->cursor_base - 1]);
840 
841 	height = imin(scp->cursor_height, scp->font_size);
842 
843 	for (i = 0; i < height; ++i, --char_data) {
844 		u32 = ((*char_data & 1 ? fg : bg) << 24) +
845 		      ((*char_data & 2 ? fg : bg) << 16) +
846 		      ((*char_data & 4 ? fg : bg) << 8) +
847 		      (*char_data & 8 ? fg : bg);
848 		writel(draw_pos + 4, u32);
849 
850 		u32 = ((*char_data & 16 ? fg : bg) << 24) +
851 		      ((*char_data & 32 ? fg : bg) << 16) +
852 		      ((*char_data & 64 ? fg : bg) << 8) +
853 		      (*char_data & 128 ? fg : bg);
854 		writel(draw_pos, u32);
855 
856 		draw_pos -= line_width;
857 	}
858 }
859 
860 static void
861 draw_pxlcursor_planar(scr_stat *scp, int at, int on, int flip)
862 {
863 	vm_offset_t d;
864 	u_char *f;
865 	int line_width;
866 	int height;
867 	int col;
868 	int a;
869 	int i;
870 	u_char c;
871 
872 	line_width = scp->sc->adp->va_line_width;
873 
874 	d = VIDEO_MEMORY_POS(scp, at, 1) +
875 	    (scp->font_size - scp->cursor_base - 1) * line_width;
876 
877 	outw(GDCIDX, 0x0005);		/* read mode 0, write mode 0 */
878 	outw(GDCIDX, 0x0003);		/* data rotate/function select */
879 	outw(GDCIDX, 0x0f01);		/* set/reset enable */
880 	/* set background color in EGA/VGA latch */
881 	a = sc_vtb_geta(&scp->vtb, at);
882 	if (flip)
883 		col = (on) ? ((a & 0xf000) >> 4) : (a & 0x0f00);
884 	else
885 		col = (on) ? (a & 0x0f00) : ((a & 0xf000) >> 4);
886 	outw(GDCIDX, col | 0x00);	/* set/reset */
887 	outw(GDCIDX, 0xff08);		/* bit mask */
888 	writeb(d, 0);
889 	c = readb(d);			/* set bg color in the latch */
890 	/* foreground color */
891 	if (flip)
892 		col = (on) ? (a & 0x0f00) : ((a & 0xf000) >> 4);
893 	else
894 		col = (on) ? ((a & 0xf000) >> 4) : (a & 0x0f00);
895 	outw(GDCIDX, col | 0x00);	/* set/reset */
896 	f = &(scp->font[sc_vtb_getc(&scp->vtb, at)*scp->font_size
897 		+ scp->font_size - scp->cursor_base - 1]);
898 	height = imin(scp->cursor_height, scp->font_size);
899 	for (i = 0; i < height; ++i, --f) {
900 		outw(GDCIDX, (*f << 8) | 0x08);	/* bit mask */
901 	       	writeb(d, 0);
902 		d -= line_width;
903 	}
904 	outw(GDCIDX, 0x0000);		/* set/reset */
905 	outw(GDCIDX, 0x0001);		/* set/reset enable */
906 	outw(GDCIDX, 0xff08);		/* bit mask */
907 }
908 
909 static int pxlblinkrate = 0;
910 
911 static void
912 vga_pxlcursor_direct(scr_stat *scp, int at, int blink, int on, int flip)
913 {
914 	if (scp->cursor_height <= 0)	/* the text cursor is disabled */
915 		return;
916 
917 	if (on) {
918 		if (!blink) {
919 			scp->status |= VR_CURSOR_ON;
920 			draw_pxlcursor_direct(scp, at, on, flip);
921 		} else if (++pxlblinkrate & 4) {
922 			pxlblinkrate = 0;
923 			scp->status ^= VR_CURSOR_ON;
924 			draw_pxlcursor_direct(scp, at,
925 					      scp->status & VR_CURSOR_ON,
926 					      flip);
927 		}
928 	} else {
929 		if (scp->status & VR_CURSOR_ON)
930 			draw_pxlcursor_direct(scp, at, on, flip);
931 		scp->status &= ~VR_CURSOR_ON;
932 	}
933 	if (blink)
934 		scp->status |= VR_CURSOR_BLINK;
935 	else
936 		scp->status &= ~VR_CURSOR_BLINK;
937 }
938 
939 static void
940 vga_pxlcursor_packed(scr_stat *scp, int at, int blink, int on, int flip)
941 {
942 	if (scp->cursor_height <= 0)	/* the text cursor is disabled */
943 		return;
944 
945 	if (on) {
946 		if (!blink) {
947 			scp->status |= VR_CURSOR_ON;
948 			draw_pxlcursor_packed(scp, at, on, flip);
949 		} else if (++pxlblinkrate & 4) {
950 			pxlblinkrate = 0;
951 			scp->status ^= VR_CURSOR_ON;
952 			draw_pxlcursor_packed(scp, at,
953 					      scp->status & VR_CURSOR_ON,
954 					      flip);
955 		}
956 	} else {
957 		if (scp->status & VR_CURSOR_ON)
958 			draw_pxlcursor_packed(scp, at, on, flip);
959 		scp->status &= ~VR_CURSOR_ON;
960 	}
961 	if (blink)
962 		scp->status |= VR_CURSOR_BLINK;
963 	else
964 		scp->status &= ~VR_CURSOR_BLINK;
965 }
966 
967 static void
968 vga_pxlcursor_planar(scr_stat *scp, int at, int blink, int on, int flip)
969 {
970 	if (scp->cursor_height <= 0)	/* the text cursor is disabled */
971 		return;
972 
973 	if (on) {
974 		if (!blink) {
975 			scp->status |= VR_CURSOR_ON;
976 			draw_pxlcursor_planar(scp, at, on, flip);
977 		} else if (++pxlblinkrate & 4) {
978 			pxlblinkrate = 0;
979 			scp->status ^= VR_CURSOR_ON;
980 			draw_pxlcursor_planar(scp, at,
981 					      scp->status & VR_CURSOR_ON,
982 					      flip);
983 		}
984 	} else {
985 		if (scp->status & VR_CURSOR_ON)
986 			draw_pxlcursor_planar(scp, at, on, flip);
987 		scp->status &= ~VR_CURSOR_ON;
988 	}
989 	if (blink)
990 		scp->status |= VR_CURSOR_BLINK;
991 	else
992 		scp->status &= ~VR_CURSOR_BLINK;
993 }
994 
995 static void
996 vga_pxlblink_direct(scr_stat *scp, int at, int flip)
997 {
998 	if (!(scp->status & VR_CURSOR_BLINK))
999 		return;
1000 	if (!(++pxlblinkrate & 4))
1001 		return;
1002 	pxlblinkrate = 0;
1003 	scp->status ^= VR_CURSOR_ON;
1004 	draw_pxlcursor_direct(scp, at, scp->status & VR_CURSOR_ON, flip);
1005 }
1006 
1007 static void
1008 vga_pxlblink_packed(scr_stat *scp, int at, int flip)
1009 {
1010 	if (!(scp->status & VR_CURSOR_BLINK))
1011 		return;
1012 	if (!(++pxlblinkrate & 4))
1013 		return;
1014 	pxlblinkrate = 0;
1015 	scp->status ^= VR_CURSOR_ON;
1016 	draw_pxlcursor_packed(scp, at, scp->status & VR_CURSOR_ON, flip);
1017 }
1018 
1019 static void
1020 vga_pxlblink_planar(scr_stat *scp, int at, int flip)
1021 {
1022 	if (!(scp->status & VR_CURSOR_BLINK))
1023 		return;
1024 	if (!(++pxlblinkrate & 4))
1025 		return;
1026 	pxlblinkrate = 0;
1027 	scp->status ^= VR_CURSOR_ON;
1028 	draw_pxlcursor_planar(scp, at, scp->status & VR_CURSOR_ON, flip);
1029 }
1030 
1031 #ifndef SC_NO_CUTPASTE
1032 
1033 static void
1034 draw_pxlmouse_direct(scr_stat *scp, int x, int y)
1035 {
1036 	int line_width, pixel_size;
1037 	int xend, yend;
1038 	int i, j;
1039 	vm_offset_t draw_pos;
1040 
1041 	line_width = scp->sc->adp->va_line_width;
1042 	pixel_size = scp->sc->adp->va_info.vi_pixel_size;
1043 
1044 	xend = imin(x + 8, 8 * (scp->xoff + scp->xsize));
1045 	yend = imin(y + 16, scp->font_size * (scp->yoff + scp->ysize));
1046 
1047 	draw_pos = scp->sc->adp->va_window + y * line_width + x * pixel_size;
1048 
1049 	for (i = 0; i < (yend - y); i++) {
1050 		for (j = (xend - x - 1); j >= 0; j--) {
1051 			switch (scp->sc->adp->va_info.vi_depth) {
1052 			case 32:
1053 				if (mouse_or_mask[i] & 1 << (15 - j))
1054 					writel(draw_pos + 4 * j,
1055 					    scp->ega_palette[15]);
1056 				else if (mouse_and_mask[i] & 1 << (15 - j))
1057 					writel(draw_pos + 4 * j,
1058 					    scp->ega_palette[0]);
1059 				break;
1060 			case 16:
1061 				/* FALLTHROUGH */
1062 			case 15:
1063 				if (mouse_or_mask[i] & 1 << (15 - j))
1064 					writew(draw_pos + 2 * j,
1065 					    scp->ega_palette[15]);
1066 				else if (mouse_and_mask[i] & 1 << (15 - j))
1067 					writew(draw_pos + 2 * j,
1068 					    scp->ega_palette[0]);
1069 				break;
1070 			}
1071 		}
1072 
1073 		draw_pos += line_width;
1074 	}
1075 }
1076 
1077 static void
1078 draw_pxlmouse_packed(scr_stat *scp, int x, int y)
1079 {
1080 	int line_width;
1081 	int xend, yend;
1082 	int i, j;
1083 	vm_offset_t draw_pos;
1084 
1085 	line_width = scp->sc->adp->va_line_width;
1086 
1087 	xend = imin(8 * (scp->xoff + scp->xsize), imin(x + 16, scp->xpixel));
1088 	yend = imin(scp->font_size * (scp->yoff + scp->ysize),
1089 	    imin(y + 16, scp->ypixel));
1090 
1091 	draw_pos = scp->sc->adp->va_window + y * line_width + x;
1092 
1093 	for (i = 0; i < (yend - y); i++) {
1094 		for (j = (xend - x - 1); j >= 0; j--) {
1095 			if (mouse_or_mask[i] & 1 << (15 - j))
1096 				writeb(draw_pos + j, 15);
1097 			else if (mouse_and_mask[i] & 1 << (15 - j))
1098 				writeb(draw_pos + j, 0);
1099 		}
1100 
1101 		draw_pos += line_width;
1102 	}
1103 }
1104 
1105 static void
1106 draw_pxlmouse_planar(scr_stat *scp, int x, int y)
1107 {
1108 	vm_offset_t p;
1109 	int line_width;
1110 	int xoff;
1111 	int ymax;
1112 	u_short m;
1113 	int i, j;
1114 
1115 	line_width = scp->sc->adp->va_line_width;
1116 	xoff = (x - scp->xoff*8)%8;
1117 	ymax = imin(y + 16, scp->font_size * (scp->yoff + scp->ysize));
1118 
1119 	outw(GDCIDX, 0x0805);		/* read mode 1, write mode 0 */
1120 	outw(GDCIDX, 0x0001);		/* set/reset enable */
1121 	outw(GDCIDX, 0x0002);		/* color compare */
1122 	outw(GDCIDX, 0x0007);		/* color don't care */
1123 	outw(GDCIDX, 0xff08);		/* bit mask */
1124 	outw(GDCIDX, 0x0803);		/* data rotate/function select (and) */
1125 	p = scp->sc->adp->va_window + line_width*y + x/8;
1126 	if (x < 8 * (scp->xoff + scp->xsize) - 8) {
1127 		for (i = y, j = 0; i < ymax; ++i, ++j) {
1128 			m = ~(mouse_and_mask[j] >> xoff);
1129 			*(u_char *)p &= m >> 8;
1130 			*(u_char *)(p + 1) &= m;
1131 			p += line_width;
1132 		}
1133 	} else {
1134 		xoff += 8;
1135 		for (i = y, j = 0; i < ymax; ++i, ++j) {
1136 			m = ~(mouse_and_mask[j] >> xoff);
1137 			*(u_char *)p &= m;
1138 			p += line_width;
1139 		}
1140 	}
1141 	outw(GDCIDX, 0x1003);		/* data rotate/function select (or) */
1142 	p = scp->sc->adp->va_window + line_width*y + x/8;
1143 	if (x < 8 * (scp->xoff + scp->xsize) - 8) {
1144 		for (i = y, j = 0; i < ymax; ++i, ++j) {
1145 			m = mouse_or_mask[j] >> xoff;
1146 			*(u_char *)p &= m >> 8;
1147 			*(u_char *)(p + 1) &= m;
1148 			p += line_width;
1149 		}
1150 	} else {
1151 		for (i = y, j = 0; i < ymax; ++i, ++j) {
1152 			m = mouse_or_mask[j] >> xoff;
1153 			*(u_char *)p &= m;
1154 			p += line_width;
1155 		}
1156 	}
1157 	outw(GDCIDX, 0x0005);		/* read mode 0, write mode 0 */
1158 	outw(GDCIDX, 0x0003);		/* data rotate/function select */
1159 }
1160 
1161 static void
1162 remove_pxlmouse(scr_stat *scp, int x, int y)
1163 {
1164 	int col, row;
1165 	int pos;
1166 	int i;
1167 
1168 	/* erase the mouse cursor image */
1169 	col = x/8 - scp->xoff;
1170 	row = y/scp->font_size - scp->yoff;
1171 	pos = row*scp->xsize + col;
1172 	i = (col < scp->xsize - 1) ? 2 : 1;
1173 	(*scp->rndr->draw)(scp, pos, i, FALSE);
1174 	if (row < scp->ysize - 1)
1175 		(*scp->rndr->draw)(scp, pos + scp->xsize, i, FALSE);
1176 }
1177 
1178 static void
1179 vga_pxlmouse_direct(scr_stat *scp, int x, int y, int on)
1180 {
1181 	if (on)
1182 		draw_pxlmouse_direct(scp, x, y);
1183 	else
1184 		remove_pxlmouse(scp, x, y);
1185 }
1186 
1187 static void
1188 vga_pxlmouse_packed(scr_stat *scp, int x, int y, int on)
1189 {
1190 	if (on)
1191 		draw_pxlmouse_packed(scp, x, y);
1192 	else
1193 		remove_pxlmouse(scp, x, y);
1194 }
1195 
1196 static void
1197 vga_pxlmouse_planar(scr_stat *scp, int x, int y, int on)
1198 {
1199 	if (on)
1200 		draw_pxlmouse_planar(scp, x, y);
1201 	else
1202 		remove_pxlmouse(scp, x, y);
1203 }
1204 
1205 #endif /* SC_NO_CUTPASTE */
1206 #endif /* SC_PIXEL_MODE */
1207 
1208 #ifndef SC_NO_MODE_CHANGE
1209 
1210 /* graphics mode renderer */
1211 
1212 static void
1213 vga_grborder(scr_stat *scp, int color)
1214 {
1215 	(*vidsw[scp->sc->adapter]->set_border)(scp->sc->adp, color);
1216 }
1217 
1218 #endif
1219