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