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