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