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