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