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