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