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