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