143#ifndef SC_NO_CUTPASTE 144static u_short mouse_and_mask[16] = { 145 0xc000, 0xe000, 0xf000, 0xf800, 0xfc00, 0xfe00, 0xff00, 0xff80, 146 0xfe00, 0x1e00, 0x1f00, 0x0f00, 0x0f00, 0x0000, 0x0000, 0x0000 147}; 148static u_short mouse_or_mask[16] = { 149 0x0000, 0x4000, 0x6000, 0x7000, 0x7800, 0x7c00, 0x7e00, 0x6800, 150 0x0c00, 0x0c00, 0x0600, 0x0600, 0x0000, 0x0000, 0x0000, 0x0000 151}; 152#endif 153 154static void 155vga_nop(scr_stat *scp, ...) 156{ 157} 158 159/* text mode renderer */ 160 161static void 162vga_txtclear(scr_stat *scp, int c, int attr) 163{ 164 sc_vtb_clear(&scp->scr, c, attr); 165} 166 167static void 168vga_txtborder(scr_stat *scp, int color) 169{ 170 (*vidsw[scp->sc->adapter]->set_border)(scp->sc->adp, color); 171} 172 173static void 174vga_txtdraw(scr_stat *scp, int from, int count, int flip) 175{ 176 vm_offset_t p; 177 int c; 178 int a; 179 180 if (from + count > scp->xsize*scp->ysize) 181 count = scp->xsize*scp->ysize - from; 182 183 if (flip) { 184 for (p = sc_vtb_pointer(&scp->scr, from); count-- > 0; ++from) { 185 c = sc_vtb_getc(&scp->vtb, from); 186 a = sc_vtb_geta(&scp->vtb, from); 187 a = (a & 0x8800) | ((a & 0x7000) >> 4) 188 | ((a & 0x0700) << 4); 189 p = sc_vtb_putchar(&scp->scr, p, c, a); 190 } 191 } else { 192 sc_vtb_copy(&scp->vtb, from, &scp->scr, from, count); 193 } 194} 195 196static void 197vga_txtcursor_shape(scr_stat *scp, int base, int height, int blink) 198{ 199 if (base < 0 || base >= scp->font_size) 200 return; 201 /* the caller may set height <= 0 in order to disable the cursor */ 202#if 0 203 scp->cursor_base = base; 204 scp->cursor_height = height; 205#endif 206 (*vidsw[scp->sc->adapter]->set_hw_cursor_shape)(scp->sc->adp, 207 base, height, 208 scp->font_size, blink); 209} 210 211static void 212vga_txtcursor(scr_stat *scp, int at, int blink, int on, int flip) 213{ 214 video_adapter_t *adp; 215 int cursor_attr; 216 217 if (scp->cursor_height <= 0) /* the text cursor is disabled */ 218 return; 219 220 adp = scp->sc->adp; 221 if (blink) { 222 scp->status |= VR_CURSOR_BLINK; 223 if (on) { 224 scp->status |= VR_CURSOR_ON; 225 (*vidsw[adp->va_index]->set_hw_cursor)(adp, 226 at%scp->xsize, 227 at/scp->xsize); 228 } else { 229 if (scp->status & VR_CURSOR_ON) 230 (*vidsw[adp->va_index]->set_hw_cursor)(adp, 231 -1, -1); 232 scp->status &= ~VR_CURSOR_ON; 233 } 234 } else { 235 scp->status &= ~VR_CURSOR_BLINK; 236 if (on) { 237 scp->status |= VR_CURSOR_ON; 238 cursor_attr = sc_vtb_geta(&scp->vtb, at); 239 scp->cursor_saveunder_char = sc_vtb_getc(&scp->scr, at); 240 scp->cursor_saveunder_attr = cursor_attr; 241 if ((cursor_attr & 0x7000) == 0x7000) { 242 cursor_attr &= 0x8f00; 243 if ((cursor_attr & 0x0700) == 0) 244 cursor_attr |= 0x0700; 245 } else { 246 cursor_attr |= 0x7000; 247 if ((cursor_attr & 0x0700) == 0x0700) 248 cursor_attr &= 0xf000; 249 } 250 if (flip) 251 cursor_attr = (cursor_attr & 0x8800) 252 | ((cursor_attr & 0x7000) >> 4) 253 | ((cursor_attr & 0x0700) << 4); 254 sc_vtb_putc(&scp->scr, at, 255 sc_vtb_getc(&scp->scr, at), 256 cursor_attr); 257 } else { 258 cursor_attr = scp->cursor_saveunder_attr; 259 if (flip) 260 cursor_attr = (cursor_attr & 0x8800) 261 | ((cursor_attr & 0x7000) >> 4) 262 | ((cursor_attr & 0x0700) << 4); 263 if (scp->status & VR_CURSOR_ON) 264 sc_vtb_putc(&scp->scr, at, 265 scp->cursor_saveunder_char, 266 cursor_attr); 267 scp->status &= ~VR_CURSOR_ON; 268 } 269 } 270} 271 272static void 273vga_txtblink(scr_stat *scp, int at, int flip) 274{ 275} 276 277#ifndef SC_NO_CUTPASTE 278 279static void 280draw_txtmouse(scr_stat *scp, int x, int y) 281{ 282#ifndef SC_ALT_MOUSE_IMAGE 283 u_char font_buf[128]; 284 u_short cursor[32]; 285 u_char c; 286 int pos; 287 int xoffset, yoffset; 288 int crtc_addr; 289 int i; 290 291 /* prepare mousepointer char's bitmaps */ 292 pos = (y/scp->font_size - scp->yoff)*scp->xsize + x/8 - scp->xoff; 293 bcopy(scp->font + sc_vtb_getc(&scp->vtb, pos)*scp->font_size, 294 &font_buf[0], scp->font_size); 295 bcopy(scp->font + sc_vtb_getc(&scp->vtb, pos + 1)*scp->font_size, 296 &font_buf[32], scp->font_size); 297 bcopy(scp->font 298 + sc_vtb_getc(&scp->vtb, pos + scp->xsize)*scp->font_size, 299 &font_buf[64], scp->font_size); 300 bcopy(scp->font 301 + sc_vtb_getc(&scp->vtb, pos + scp->xsize + 1)*scp->font_size, 302 &font_buf[96], scp->font_size); 303 for (i = 0; i < scp->font_size; ++i) { 304 cursor[i] = font_buf[i]<<8 | font_buf[i+32]; 305 cursor[i + scp->font_size] = font_buf[i+64]<<8 | font_buf[i+96]; 306 } 307 308 /* now and-or in the mousepointer image */ 309 xoffset = x%8; 310 yoffset = y%scp->font_size; 311 for (i = 0; i < 16; ++i) { 312 cursor[i + yoffset] = 313 (cursor[i + yoffset] & ~(mouse_and_mask[i] >> xoffset)) 314 | (mouse_or_mask[i] >> xoffset); 315 } 316 for (i = 0; i < scp->font_size; ++i) { 317 font_buf[i] = (cursor[i] & 0xff00) >> 8; 318 font_buf[i + 32] = cursor[i] & 0xff; 319 font_buf[i + 64] = (cursor[i + scp->font_size] & 0xff00) >> 8; 320 font_buf[i + 96] = cursor[i + scp->font_size] & 0xff; 321 } 322 323#if 1 324 /* wait for vertical retrace to avoid jitter on some videocards */ 325 crtc_addr = scp->sc->adp->va_crtc_addr; 326 while (!(inb(crtc_addr + 6) & 0x08)) /* idle */ ; 327#endif 328 c = scp->sc->mouse_char; 329 (*vidsw[scp->sc->adapter]->load_font)(scp->sc->adp, 0, 32, font_buf, 330 c, 4); 331 332 sc_vtb_putc(&scp->scr, pos, c, sc_vtb_geta(&scp->scr, pos)); 333 /* FIXME: may be out of range! */ 334 sc_vtb_putc(&scp->scr, pos + scp->xsize, c + 2, 335 sc_vtb_geta(&scp->scr, pos + scp->xsize)); 336 if (x < (scp->xsize - 1)*8) { 337 sc_vtb_putc(&scp->scr, pos + 1, c + 1, 338 sc_vtb_geta(&scp->scr, pos + 1)); 339 sc_vtb_putc(&scp->scr, pos + scp->xsize + 1, c + 3, 340 sc_vtb_geta(&scp->scr, pos + scp->xsize + 1)); 341 } 342#else /* SC_ALT_MOUSE_IMAGE */ 343 /* Red, magenta and brown are mapped to green to to keep it readable */ 344 static const int col_conv[16] = { 345 6, 6, 6, 6, 2, 2, 2, 6, 14, 14, 14, 14, 10, 10, 10, 14 346 }; 347 int pos; 348 int color; 349 int a; 350 351 pos = (y/scp->font_size - scp->yoff)*scp->xsize + x/8 - scp->xoff; 352 a = sc_vtb_geta(&scp->scr, pos); 353 if (scp->sc->adp->va_flags & V_ADP_COLOR) 354 color = (col_conv[(a & 0xf000) >> 12] << 12) 355 | ((a & 0x0f00) | 0x0800); 356 else 357 color = ((a & 0xf000) >> 4) | ((a & 0x0f00) << 4); 358 sc_vtb_putc(&scp->scr, pos, sc_vtb_getc(&scp->scr, pos), color); 359#endif /* SC_ALT_MOUSE_IMAGE */ 360} 361 362static void 363remove_txtmouse(scr_stat *scp, int x, int y) 364{ 365} 366 367static void 368vga_txtmouse(scr_stat *scp, int x, int y, int on) 369{ 370 if (on) 371 draw_txtmouse(scp, x, y); 372 else 373 remove_txtmouse(scp, x, y); 374} 375 376#endif /* SC_NO_CUTPASTE */ 377 378#ifdef SC_PIXEL_MODE 379 380/* pixel (raster text) mode renderer */ 381 382static void 383vga_pxlclear(scr_stat *scp, int c, int attr) 384{ 385 vm_offset_t p; 386 int line_width; 387 int lines; 388 int i; 389 390 /* XXX: we are just filling the screen with the background color... */ 391 outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */ 392 outw(GDCIDX, 0x0003); /* data rotate/function select */ 393 outw(GDCIDX, 0x0f01); /* set/reset enable */ 394 outw(GDCIDX, 0xff08); /* bit mask */ 395 outw(GDCIDX, ((attr & 0xf000) >> 4) | 0x00); /* set/reset */ 396 line_width = scp->sc->adp->va_line_width; 397 lines = scp->ysize*scp->font_size; 398 p = scp->sc->adp->va_window + line_width*scp->yoff*scp->font_size 399 + scp->xoff; 400 for (i = 0; i < lines; ++i) { 401 bzero_io((void *)p, scp->xsize); 402 p += line_width; 403 } 404 outw(GDCIDX, 0x0000); /* set/reset */ 405 outw(GDCIDX, 0x0001); /* set/reset enable */ 406} 407 408static void 409vga_pxlborder(scr_stat *scp, int color) 410{ 411 vm_offset_t p; 412 int line_width; 413 int i; 414 415 (*vidsw[scp->sc->adapter]->set_border)(scp->sc->adp, color); 416 417 outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */ 418 outw(GDCIDX, 0x0003); /* data rotate/function select */ 419 outw(GDCIDX, 0x0f01); /* set/reset enable */ 420 outw(GDCIDX, 0xff08); /* bit mask */ 421 outw(GDCIDX, (color << 8) | 0x00); /* set/reset */ 422 line_width = scp->sc->adp->va_line_width; 423 p = scp->sc->adp->va_window; 424 if (scp->yoff > 0) { 425 bzero_io((void *)p, line_width*scp->yoff*scp->font_size); 426 bzero_io((void *)(p + line_width*(scp->yoff + scp->ysize) 427 *scp->font_size), 428 line_width*(scp->ypixel 429 - (scp->yoff + scp->ysize)*scp->font_size)); 430 } 431 if (scp->xoff > 0) { 432 for (i = 0; i < scp->ysize*scp->font_size; ++i) { 433 bzero_io((void *)(p + line_width 434 *(scp->yoff*scp->font_size + i)), 435 scp->xoff); 436 bzero_io((void *)(p + line_width 437 *(scp->yoff*scp->font_size + i) 438 + scp->xoff + scp->xsize), 439 scp->xpixel/8 - scp->xoff - scp->xsize); 440 } 441 } 442 outw(GDCIDX, 0x0000); /* set/reset */ 443 outw(GDCIDX, 0x0001); /* set/reset enable */ 444} 445 446static void 447vga_egadraw(scr_stat *scp, int from, int count, int flip) 448{ 449 vm_offset_t d; 450 vm_offset_t e; 451 u_char *f; 452 u_short bg; 453 u_short col1, col2; 454 int line_width; 455 int i, j; 456 int a; 457 u_char c; 458 459 line_width = scp->sc->adp->va_line_width; 460 d = scp->sc->adp->va_window 461 + scp->xoff 462 + scp->yoff*scp->font_size*line_width 463 + (from%scp->xsize) 464 + scp->font_size*line_width*(from/scp->xsize); 465 466 outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */ 467 outw(GDCIDX, 0x0003); /* data rotate/function select */ 468 outw(GDCIDX, 0x0f01); /* set/reset enable */ 469 bg = -1; 470 if (from + count > scp->xsize*scp->ysize) 471 count = scp->xsize*scp->ysize - from; 472 for (i = from; count-- > 0; ++i) { 473 a = sc_vtb_geta(&scp->vtb, i); 474 if (flip) { 475 col1 = ((a & 0x7000) >> 4) | (a & 0x0800); 476 col2 = ((a & 0x8000) >> 4) | (a & 0x0700); 477 } else { 478 col1 = (a & 0x0f00); 479 col2 = (a & 0xf000) >> 4; 480 } 481 /* set background color in EGA/VGA latch */ 482 if (bg != col2) { 483 bg = col2; 484 outw(GDCIDX, bg | 0x00); /* set/reset */ 485 outw(GDCIDX, 0xff08); /* bit mask */ 486 writeb(d, 0); 487 c = readb(d); /* set bg color in the latch */ 488 } 489 /* foreground color */ 490 outw(GDCIDX, col1 | 0x00); /* set/reset */ 491 e = d; 492 f = &(scp->font[sc_vtb_getc(&scp->vtb, i)*scp->font_size]); 493 for (j = 0; j < scp->font_size; ++j, ++f) { 494 outw(GDCIDX, (*f << 8) | 0x08); /* bit mask */ 495 writeb(e, 0); 496 e += line_width; 497 } 498 ++d; 499 if ((i % scp->xsize) == scp->xsize - 1) 500 d += scp->xoff*2 501 + (scp->font_size - 1)*line_width; 502 } 503 outw(GDCIDX, 0x0000); /* set/reset */ 504 outw(GDCIDX, 0x0001); /* set/reset enable */ 505 outw(GDCIDX, 0xff08); /* bit mask */ 506} 507 508static void 509vga_vgadraw(scr_stat *scp, int from, int count, int flip) 510{ 511 vm_offset_t d; 512 vm_offset_t e; 513 u_char *f; 514 u_short bg; 515 u_short col1, col2; 516 int line_width; 517 int i, j; 518 int a; 519 u_char c; 520 521 line_width = scp->sc->adp->va_line_width; 522 d = scp->sc->adp->va_window 523 + scp->xoff 524 + scp->yoff*scp->font_size*line_width 525 + (from%scp->xsize) 526 + scp->font_size*line_width*(from/scp->xsize); 527 528 outw(GDCIDX, 0x0305); /* read mode 0, write mode 3 */ 529 outw(GDCIDX, 0x0003); /* data rotate/function select */ 530 outw(GDCIDX, 0x0f01); /* set/reset enable */ 531 outw(GDCIDX, 0xff08); /* bit mask */ 532 bg = -1; 533 if (from + count > scp->xsize*scp->ysize) 534 count = scp->xsize*scp->ysize - from; 535 for (i = from; count-- > 0; ++i) { 536 a = sc_vtb_geta(&scp->vtb, i); 537 if (flip) { 538 col1 = ((a & 0x7000) >> 4) | (a & 0x0800); 539 col2 = ((a & 0x8000) >> 4) | (a & 0x0700); 540 } else { 541 col1 = (a & 0x0f00); 542 col2 = (a & 0xf000) >> 4; 543 } 544 /* set background color in EGA/VGA latch */ 545 if (bg != col2) { 546 bg = col2; 547 outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */ 548 outw(GDCIDX, bg | 0x00); /* set/reset */ 549 writeb(d, 0); 550 c = readb(d); /* set bg color in the latch */ 551 outw(GDCIDX, 0x0305); /* read mode 0, write mode 3 */ 552 } 553 /* foreground color */ 554 outw(GDCIDX, col1 | 0x00); /* set/reset */ 555 e = d; 556 f = &(scp->font[sc_vtb_getc(&scp->vtb, i)*scp->font_size]); 557 for (j = 0; j < scp->font_size; ++j, ++f) { 558 writeb(e, *f); 559 e += line_width; 560 } 561 ++d; 562 if ((i % scp->xsize) == scp->xsize - 1) 563 d += scp->xoff*2 564 + (scp->font_size - 1)*line_width; 565 } 566 outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */ 567 outw(GDCIDX, 0x0000); /* set/reset */ 568 outw(GDCIDX, 0x0001); /* set/reset enable */ 569} 570 571static void 572vga_pxlcursor_shape(scr_stat *scp, int base, int height, int blink) 573{ 574 if (base < 0 || base >= scp->font_size) 575 return; 576 /* the caller may set height <= 0 in order to disable the cursor */ 577#if 0 578 scp->cursor_base = base; 579 scp->cursor_height = height; 580#endif 581} 582 583static void 584draw_pxlcursor(scr_stat *scp, int at, int on, int flip) 585{ 586 vm_offset_t d; 587 u_char *f; 588 int line_width; 589 int height; 590 int col; 591 int a; 592 int i; 593 u_char c; 594 595 line_width = scp->sc->adp->va_line_width; 596 d = scp->sc->adp->va_window 597 + scp->xoff 598 + scp->yoff*scp->font_size*line_width 599 + (at%scp->xsize) 600 + scp->font_size*line_width*(at/scp->xsize) 601 + (scp->font_size - scp->cursor_base - 1)*line_width; 602 603 outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */ 604 outw(GDCIDX, 0x0003); /* data rotate/function select */ 605 outw(GDCIDX, 0x0f01); /* set/reset enable */ 606 /* set background color in EGA/VGA latch */ 607 a = sc_vtb_geta(&scp->vtb, at); 608 if (flip) 609 col = (on) ? ((a & 0xf000) >> 4) : (a & 0x0f00); 610 else 611 col = (on) ? (a & 0x0f00) : ((a & 0xf000) >> 4); 612 outw(GDCIDX, col | 0x00); /* set/reset */ 613 outw(GDCIDX, 0xff08); /* bit mask */ 614 writeb(d, 0); 615 c = readb(d); /* set bg color in the latch */ 616 /* foreground color */ 617 if (flip) 618 col = (on) ? (a & 0x0f00) : ((a & 0xf000) >> 4); 619 else 620 col = (on) ? ((a & 0xf000) >> 4) : (a & 0x0f00); 621 outw(GDCIDX, col | 0x00); /* set/reset */ 622 f = &(scp->font[sc_vtb_getc(&scp->vtb, at)*scp->font_size 623 + scp->font_size - scp->cursor_base - 1]); 624 height = imin(scp->cursor_height, scp->font_size); 625 for (i = 0; i < height; ++i, --f) { 626 outw(GDCIDX, (*f << 8) | 0x08); /* bit mask */ 627 writeb(d, 0); 628 d -= line_width; 629 } 630 outw(GDCIDX, 0x0000); /* set/reset */ 631 outw(GDCIDX, 0x0001); /* set/reset enable */ 632 outw(GDCIDX, 0xff08); /* bit mask */ 633} 634 635static void 636vga_pxlcursor(scr_stat *scp, int at, int blink, int on, int flip) 637{ 638 if (scp->cursor_height <= 0) /* the text cursor is disabled */ 639 return; 640 641 if (on) { 642 scp->status |= VR_CURSOR_ON; 643 draw_pxlcursor(scp, at, on, flip); 644 } else { 645 if (scp->status & VR_CURSOR_ON) 646 draw_pxlcursor(scp, at, on, flip); 647 scp->status &= ~VR_CURSOR_ON; 648 } 649 if (blink) 650 scp->status |= VR_CURSOR_BLINK; 651 else 652 scp->status &= ~VR_CURSOR_BLINK; 653} 654 655static void 656vga_pxlblink(scr_stat *scp, int at, int flip) 657{ 658 static int blinkrate = 0; 659 660 if (!(scp->status & VR_CURSOR_BLINK)) 661 return; 662 if (!(++blinkrate & 4)) 663 return; 664 blinkrate = 0; 665 scp->status ^= VR_CURSOR_ON; 666 draw_pxlcursor(scp, at, scp->status & VR_CURSOR_ON, flip); 667} 668 669#ifndef SC_NO_CUTPASTE 670 671static void 672draw_pxlmouse(scr_stat *scp, int x, int y) 673{ 674 vm_offset_t p; 675 int line_width; 676 int xoff, yoff; 677 int ymax; 678 u_short m; 679 int i, j; 680 681 line_width = scp->sc->adp->va_line_width; 682 xoff = (x - scp->xoff*8)%8; 683 yoff = y - (y/line_width)*line_width; 684 ymax = imin(y + 16, scp->ypixel); 685 686 outw(GDCIDX, 0x0805); /* read mode 1, write mode 0 */ 687 outw(GDCIDX, 0x0001); /* set/reset enable */ 688 outw(GDCIDX, 0x0002); /* color compare */ 689 outw(GDCIDX, 0x0007); /* color don't care */ 690 outw(GDCIDX, 0xff08); /* bit mask */ 691 outw(GDCIDX, 0x0803); /* data rotate/function select (and) */ 692 p = scp->sc->adp->va_window + line_width*y + x/8; 693 if (x < scp->xpixel - 16) { 694 for (i = y, j = 0; i < ymax; ++i, ++j) { 695 m = ~(mouse_and_mask[j] >> xoff); 696#ifdef __i386__ 697 *(u_char *)p &= m >> 8; 698 *(u_char *)(p + 1) &= m; 699#elif defined(__alpha__) 700 writeb(p, readb(p) & (m >> 8)); 701 writeb(p + 1, readb(p + 1) & (m >> 8)); 702#endif 703 p += line_width; 704 } 705 } else { 706 xoff += 8; 707 for (i = y, j = 0; i < ymax; ++i, ++j) { 708 m = ~(mouse_and_mask[j] >> xoff); 709#ifdef __i386__ 710 *(u_char *)p &= m; 711#elif defined(__alpha__) 712 writeb(p, readb(p) & (m >> 8)); 713#endif 714 p += line_width; 715 } 716 } 717 outw(GDCIDX, 0x1003); /* data rotate/function select (or) */ 718 p = scp->sc->adp->va_window + line_width*y + x/8; 719 if (x < scp->xpixel - 16) { 720 for (i = y, j = 0; i < ymax; ++i, ++j) { 721 m = mouse_or_mask[j] >> xoff; 722#ifdef __i386__ 723 *(u_char *)p &= m >> 8; 724 *(u_char *)(p + 1) &= m; 725#elif defined(__alpha__) 726 writeb(p, readb(p) & (m >> 8)); 727 writeb(p + 1, readb(p + 1) & (m >> 8)); 728#endif 729 p += line_width; 730 } 731 } else { 732 for (i = y, j = 0; i < ymax; ++i, ++j) { 733 m = mouse_or_mask[j] >> xoff; 734#ifdef __i386__ 735 *(u_char *)p &= m; 736#elif defined(__alpha__) 737 writeb(p, readb(p) & (m >> 8)); 738#endif 739 p += line_width; 740 } 741 } 742 outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */ 743 outw(GDCIDX, 0x0003); /* data rotate/function select */ 744} 745 746static void 747remove_pxlmouse(scr_stat *scp, int x, int y) 748{ 749 vm_offset_t p; 750 int col, row; 751 int pos; 752 int line_width; 753 int ymax; 754 int i; 755 756 /* erase the mouse cursor image */ 757 col = x/8 - scp->xoff; 758 row = y/scp->font_size - scp->yoff; 759 pos = row*scp->xsize + col; 760 i = (col < scp->xsize - 1) ? 2 : 1; 761 (*scp->rndr->draw)(scp, pos, i, FALSE); 762 if (row < scp->ysize - 1) 763 (*scp->rndr->draw)(scp, pos + scp->xsize, i, FALSE); 764 765 /* paint border if necessary */ 766 line_width = scp->sc->adp->va_line_width; 767 outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */ 768 outw(GDCIDX, 0x0003); /* data rotate/function select */ 769 outw(GDCIDX, 0x0f01); /* set/reset enable */ 770 outw(GDCIDX, 0xff08); /* bit mask */ 771 outw(GDCIDX, (scp->border << 8) | 0x00); /* set/reset */ 772 if (row == scp->ysize - 1) { 773 i = (scp->ysize + scp->yoff)*scp->font_size; 774 ymax = imin(i + scp->font_size, scp->ypixel); 775 p = scp->sc->adp->va_window + i*line_width + scp->xoff + col; 776 if (col < scp->xsize - 1) { 777 for (; i < ymax; ++i) { 778 writeb(p, 0); 779 writeb(p + 1, 0); 780 p += line_width; 781 } 782 } else { 783 for (; i < ymax; ++i) { 784 writeb(p, 0); 785 p += line_width; 786 } 787 } 788 } 789 if ((col == scp->xsize - 1) && (scp->xoff > 0)) { 790 i = (row + scp->yoff)*scp->font_size; 791 ymax = imin(i + scp->font_size*2, scp->ypixel); 792 p = scp->sc->adp->va_window + i*line_width 793 + scp->xoff + scp->xsize; 794 for (; i < ymax; ++i) { 795 writeb(p, 0); 796 p += line_width; 797 } 798 } 799 outw(GDCIDX, 0x0000); /* set/reset */ 800 outw(GDCIDX, 0x0001); /* set/reset enable */ 801} 802 803static void 804vga_pxlmouse(scr_stat *scp, int x, int y, int on) 805{ 806 if (on) 807 draw_pxlmouse(scp, x, y); 808 else 809 remove_pxlmouse(scp, x, y); 810} 811 812#endif /* SC_NO_CUTPASTE */ 813#endif /* SC_PIXEL_MODE */ 814 815#ifndef SC_NO_MODE_CHANGE 816 817/* graphics mode renderer */ 818 819static void 820vga_grborder(scr_stat *scp, int color) 821{ 822 (*vidsw[scp->sc->adapter]->set_border)(scp->sc->adp, color); 823} 824 825#endif 826 827#endif /* NSC > 0 && NVGA > 0 */
| 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 164static void 165vga_txtclear(scr_stat *scp, int c, int attr) 166{ 167 sc_vtb_clear(&scp->scr, c, attr); 168} 169 170static void 171vga_txtborder(scr_stat *scp, int color) 172{ 173 (*vidsw[scp->sc->adapter]->set_border)(scp->sc->adp, color); 174} 175 176static void 177vga_txtdraw(scr_stat *scp, int from, int count, int flip) 178{ 179 vm_offset_t p; 180 int c; 181 int a; 182 183 if (from + count > scp->xsize*scp->ysize) 184 count = scp->xsize*scp->ysize - from; 185 186 if (flip) { 187 for (p = sc_vtb_pointer(&scp->scr, from); count-- > 0; ++from) { 188 c = sc_vtb_getc(&scp->vtb, from); 189 a = sc_vtb_geta(&scp->vtb, from); 190 a = (a & 0x8800) | ((a & 0x7000) >> 4) 191 | ((a & 0x0700) << 4); 192 p = sc_vtb_putchar(&scp->scr, p, c, a); 193 } 194 } else { 195 sc_vtb_copy(&scp->vtb, from, &scp->scr, from, count); 196 } 197} 198 199static void 200vga_txtcursor_shape(scr_stat *scp, int base, int height, int blink) 201{ 202 if (base < 0 || base >= scp->font_size) 203 return; 204 /* the caller may set height <= 0 in order to disable the cursor */ 205#if 0 206 scp->cursor_base = base; 207 scp->cursor_height = height; 208#endif 209 (*vidsw[scp->sc->adapter]->set_hw_cursor_shape)(scp->sc->adp, 210 base, height, 211 scp->font_size, blink); 212} 213 214static void 215vga_txtcursor(scr_stat *scp, int at, int blink, int on, int flip) 216{ 217 video_adapter_t *adp; 218 int cursor_attr; 219 220 if (scp->cursor_height <= 0) /* the text cursor is disabled */ 221 return; 222 223 adp = scp->sc->adp; 224 if (blink) { 225 scp->status |= VR_CURSOR_BLINK; 226 if (on) { 227 scp->status |= VR_CURSOR_ON; 228 (*vidsw[adp->va_index]->set_hw_cursor)(adp, 229 at%scp->xsize, 230 at/scp->xsize); 231 } else { 232 if (scp->status & VR_CURSOR_ON) 233 (*vidsw[adp->va_index]->set_hw_cursor)(adp, 234 -1, -1); 235 scp->status &= ~VR_CURSOR_ON; 236 } 237 } else { 238 scp->status &= ~VR_CURSOR_BLINK; 239 if (on) { 240 scp->status |= VR_CURSOR_ON; 241 cursor_attr = sc_vtb_geta(&scp->vtb, at); 242 scp->cursor_saveunder_char = sc_vtb_getc(&scp->scr, at); 243 scp->cursor_saveunder_attr = cursor_attr; 244 if ((cursor_attr & 0x7000) == 0x7000) { 245 cursor_attr &= 0x8f00; 246 if ((cursor_attr & 0x0700) == 0) 247 cursor_attr |= 0x0700; 248 } else { 249 cursor_attr |= 0x7000; 250 if ((cursor_attr & 0x0700) == 0x0700) 251 cursor_attr &= 0xf000; 252 } 253 if (flip) 254 cursor_attr = (cursor_attr & 0x8800) 255 | ((cursor_attr & 0x7000) >> 4) 256 | ((cursor_attr & 0x0700) << 4); 257 sc_vtb_putc(&scp->scr, at, 258 sc_vtb_getc(&scp->scr, at), 259 cursor_attr); 260 } else { 261 cursor_attr = scp->cursor_saveunder_attr; 262 if (flip) 263 cursor_attr = (cursor_attr & 0x8800) 264 | ((cursor_attr & 0x7000) >> 4) 265 | ((cursor_attr & 0x0700) << 4); 266 if (scp->status & VR_CURSOR_ON) 267 sc_vtb_putc(&scp->scr, at, 268 scp->cursor_saveunder_char, 269 cursor_attr); 270 scp->status &= ~VR_CURSOR_ON; 271 } 272 } 273} 274 275static void 276vga_txtblink(scr_stat *scp, int at, int flip) 277{ 278} 279 280#ifndef SC_NO_CUTPASTE 281 282static void 283draw_txtmouse(scr_stat *scp, int x, int y) 284{ 285#ifndef SC_ALT_MOUSE_IMAGE 286 u_char font_buf[128]; 287 u_short cursor[32]; 288 u_char c; 289 int pos; 290 int xoffset, yoffset; 291 int crtc_addr; 292 int i; 293 294 /* prepare mousepointer char's bitmaps */ 295 pos = (y/scp->font_size - scp->yoff)*scp->xsize + x/8 - scp->xoff; 296 bcopy(scp->font + sc_vtb_getc(&scp->vtb, pos)*scp->font_size, 297 &font_buf[0], scp->font_size); 298 bcopy(scp->font + sc_vtb_getc(&scp->vtb, pos + 1)*scp->font_size, 299 &font_buf[32], scp->font_size); 300 bcopy(scp->font 301 + sc_vtb_getc(&scp->vtb, pos + scp->xsize)*scp->font_size, 302 &font_buf[64], scp->font_size); 303 bcopy(scp->font 304 + sc_vtb_getc(&scp->vtb, pos + scp->xsize + 1)*scp->font_size, 305 &font_buf[96], scp->font_size); 306 for (i = 0; i < scp->font_size; ++i) { 307 cursor[i] = font_buf[i]<<8 | font_buf[i+32]; 308 cursor[i + scp->font_size] = font_buf[i+64]<<8 | font_buf[i+96]; 309 } 310 311 /* now and-or in the mousepointer image */ 312 xoffset = x%8; 313 yoffset = y%scp->font_size; 314 for (i = 0; i < 16; ++i) { 315 cursor[i + yoffset] = 316 (cursor[i + yoffset] & ~(mouse_and_mask[i] >> xoffset)) 317 | (mouse_or_mask[i] >> xoffset); 318 } 319 for (i = 0; i < scp->font_size; ++i) { 320 font_buf[i] = (cursor[i] & 0xff00) >> 8; 321 font_buf[i + 32] = cursor[i] & 0xff; 322 font_buf[i + 64] = (cursor[i + scp->font_size] & 0xff00) >> 8; 323 font_buf[i + 96] = cursor[i + scp->font_size] & 0xff; 324 } 325 326#if 1 327 /* wait for vertical retrace to avoid jitter on some videocards */ 328 crtc_addr = scp->sc->adp->va_crtc_addr; 329 while (!(inb(crtc_addr + 6) & 0x08)) /* idle */ ; 330#endif 331 c = scp->sc->mouse_char; 332 (*vidsw[scp->sc->adapter]->load_font)(scp->sc->adp, 0, 32, font_buf, 333 c, 4); 334 335 sc_vtb_putc(&scp->scr, pos, c, sc_vtb_geta(&scp->scr, pos)); 336 /* FIXME: may be out of range! */ 337 sc_vtb_putc(&scp->scr, pos + scp->xsize, c + 2, 338 sc_vtb_geta(&scp->scr, pos + scp->xsize)); 339 if (x < (scp->xsize - 1)*8) { 340 sc_vtb_putc(&scp->scr, pos + 1, c + 1, 341 sc_vtb_geta(&scp->scr, pos + 1)); 342 sc_vtb_putc(&scp->scr, pos + scp->xsize + 1, c + 3, 343 sc_vtb_geta(&scp->scr, pos + scp->xsize + 1)); 344 } 345#else /* SC_ALT_MOUSE_IMAGE */ 346 /* Red, magenta and brown are mapped to green to to keep it readable */ 347 static const int col_conv[16] = { 348 6, 6, 6, 6, 2, 2, 2, 6, 14, 14, 14, 14, 10, 10, 10, 14 349 }; 350 int pos; 351 int color; 352 int a; 353 354 pos = (y/scp->font_size - scp->yoff)*scp->xsize + x/8 - scp->xoff; 355 a = sc_vtb_geta(&scp->scr, pos); 356 if (scp->sc->adp->va_flags & V_ADP_COLOR) 357 color = (col_conv[(a & 0xf000) >> 12] << 12) 358 | ((a & 0x0f00) | 0x0800); 359 else 360 color = ((a & 0xf000) >> 4) | ((a & 0x0f00) << 4); 361 sc_vtb_putc(&scp->scr, pos, sc_vtb_getc(&scp->scr, pos), color); 362#endif /* SC_ALT_MOUSE_IMAGE */ 363} 364 365static void 366remove_txtmouse(scr_stat *scp, int x, int y) 367{ 368} 369 370static void 371vga_txtmouse(scr_stat *scp, int x, int y, int on) 372{ 373 if (on) 374 draw_txtmouse(scp, x, y); 375 else 376 remove_txtmouse(scp, x, y); 377} 378 379#endif /* SC_NO_CUTPASTE */ 380 381#ifdef SC_PIXEL_MODE 382 383/* pixel (raster text) mode renderer */ 384 385static void 386vga_pxlclear(scr_stat *scp, int c, int attr) 387{ 388 vm_offset_t p; 389 int line_width; 390 int lines; 391 int i; 392 393 /* XXX: we are just filling the screen with the background color... */ 394 outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */ 395 outw(GDCIDX, 0x0003); /* data rotate/function select */ 396 outw(GDCIDX, 0x0f01); /* set/reset enable */ 397 outw(GDCIDX, 0xff08); /* bit mask */ 398 outw(GDCIDX, ((attr & 0xf000) >> 4) | 0x00); /* set/reset */ 399 line_width = scp->sc->adp->va_line_width; 400 lines = scp->ysize*scp->font_size; 401 p = scp->sc->adp->va_window + line_width*scp->yoff*scp->font_size 402 + scp->xoff; 403 for (i = 0; i < lines; ++i) { 404 bzero_io((void *)p, scp->xsize); 405 p += line_width; 406 } 407 outw(GDCIDX, 0x0000); /* set/reset */ 408 outw(GDCIDX, 0x0001); /* set/reset enable */ 409} 410 411static void 412vga_pxlborder(scr_stat *scp, int color) 413{ 414 vm_offset_t p; 415 int line_width; 416 int i; 417 418 (*vidsw[scp->sc->adapter]->set_border)(scp->sc->adp, color); 419 420 outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */ 421 outw(GDCIDX, 0x0003); /* data rotate/function select */ 422 outw(GDCIDX, 0x0f01); /* set/reset enable */ 423 outw(GDCIDX, 0xff08); /* bit mask */ 424 outw(GDCIDX, (color << 8) | 0x00); /* set/reset */ 425 line_width = scp->sc->adp->va_line_width; 426 p = scp->sc->adp->va_window; 427 if (scp->yoff > 0) { 428 bzero_io((void *)p, line_width*scp->yoff*scp->font_size); 429 bzero_io((void *)(p + line_width*(scp->yoff + scp->ysize) 430 *scp->font_size), 431 line_width*(scp->ypixel 432 - (scp->yoff + scp->ysize)*scp->font_size)); 433 } 434 if (scp->xoff > 0) { 435 for (i = 0; i < scp->ysize*scp->font_size; ++i) { 436 bzero_io((void *)(p + line_width 437 *(scp->yoff*scp->font_size + i)), 438 scp->xoff); 439 bzero_io((void *)(p + line_width 440 *(scp->yoff*scp->font_size + i) 441 + scp->xoff + scp->xsize), 442 scp->xpixel/8 - scp->xoff - scp->xsize); 443 } 444 } 445 outw(GDCIDX, 0x0000); /* set/reset */ 446 outw(GDCIDX, 0x0001); /* set/reset enable */ 447} 448 449static void 450vga_egadraw(scr_stat *scp, int from, int count, int flip) 451{ 452 vm_offset_t d; 453 vm_offset_t e; 454 u_char *f; 455 u_short bg; 456 u_short col1, col2; 457 int line_width; 458 int i, j; 459 int a; 460 u_char c; 461 462 line_width = scp->sc->adp->va_line_width; 463 d = scp->sc->adp->va_window 464 + scp->xoff 465 + scp->yoff*scp->font_size*line_width 466 + (from%scp->xsize) 467 + scp->font_size*line_width*(from/scp->xsize); 468 469 outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */ 470 outw(GDCIDX, 0x0003); /* data rotate/function select */ 471 outw(GDCIDX, 0x0f01); /* set/reset enable */ 472 bg = -1; 473 if (from + count > scp->xsize*scp->ysize) 474 count = scp->xsize*scp->ysize - from; 475 for (i = from; count-- > 0; ++i) { 476 a = sc_vtb_geta(&scp->vtb, i); 477 if (flip) { 478 col1 = ((a & 0x7000) >> 4) | (a & 0x0800); 479 col2 = ((a & 0x8000) >> 4) | (a & 0x0700); 480 } else { 481 col1 = (a & 0x0f00); 482 col2 = (a & 0xf000) >> 4; 483 } 484 /* set background color in EGA/VGA latch */ 485 if (bg != col2) { 486 bg = col2; 487 outw(GDCIDX, bg | 0x00); /* set/reset */ 488 outw(GDCIDX, 0xff08); /* bit mask */ 489 writeb(d, 0); 490 c = readb(d); /* set bg color in the latch */ 491 } 492 /* foreground color */ 493 outw(GDCIDX, col1 | 0x00); /* set/reset */ 494 e = d; 495 f = &(scp->font[sc_vtb_getc(&scp->vtb, i)*scp->font_size]); 496 for (j = 0; j < scp->font_size; ++j, ++f) { 497 outw(GDCIDX, (*f << 8) | 0x08); /* bit mask */ 498 writeb(e, 0); 499 e += line_width; 500 } 501 ++d; 502 if ((i % scp->xsize) == scp->xsize - 1) 503 d += scp->xoff*2 504 + (scp->font_size - 1)*line_width; 505 } 506 outw(GDCIDX, 0x0000); /* set/reset */ 507 outw(GDCIDX, 0x0001); /* set/reset enable */ 508 outw(GDCIDX, 0xff08); /* bit mask */ 509} 510 511static void 512vga_vgadraw(scr_stat *scp, int from, int count, int flip) 513{ 514 vm_offset_t d; 515 vm_offset_t e; 516 u_char *f; 517 u_short bg; 518 u_short col1, col2; 519 int line_width; 520 int i, j; 521 int a; 522 u_char c; 523 524 line_width = scp->sc->adp->va_line_width; 525 d = scp->sc->adp->va_window 526 + scp->xoff 527 + scp->yoff*scp->font_size*line_width 528 + (from%scp->xsize) 529 + scp->font_size*line_width*(from/scp->xsize); 530 531 outw(GDCIDX, 0x0305); /* read mode 0, write mode 3 */ 532 outw(GDCIDX, 0x0003); /* data rotate/function select */ 533 outw(GDCIDX, 0x0f01); /* set/reset enable */ 534 outw(GDCIDX, 0xff08); /* bit mask */ 535 bg = -1; 536 if (from + count > scp->xsize*scp->ysize) 537 count = scp->xsize*scp->ysize - from; 538 for (i = from; count-- > 0; ++i) { 539 a = sc_vtb_geta(&scp->vtb, i); 540 if (flip) { 541 col1 = ((a & 0x7000) >> 4) | (a & 0x0800); 542 col2 = ((a & 0x8000) >> 4) | (a & 0x0700); 543 } else { 544 col1 = (a & 0x0f00); 545 col2 = (a & 0xf000) >> 4; 546 } 547 /* set background color in EGA/VGA latch */ 548 if (bg != col2) { 549 bg = col2; 550 outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */ 551 outw(GDCIDX, bg | 0x00); /* set/reset */ 552 writeb(d, 0); 553 c = readb(d); /* set bg color in the latch */ 554 outw(GDCIDX, 0x0305); /* read mode 0, write mode 3 */ 555 } 556 /* foreground color */ 557 outw(GDCIDX, col1 | 0x00); /* set/reset */ 558 e = d; 559 f = &(scp->font[sc_vtb_getc(&scp->vtb, i)*scp->font_size]); 560 for (j = 0; j < scp->font_size; ++j, ++f) { 561 writeb(e, *f); 562 e += line_width; 563 } 564 ++d; 565 if ((i % scp->xsize) == scp->xsize - 1) 566 d += scp->xoff*2 567 + (scp->font_size - 1)*line_width; 568 } 569 outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */ 570 outw(GDCIDX, 0x0000); /* set/reset */ 571 outw(GDCIDX, 0x0001); /* set/reset enable */ 572} 573 574static void 575vga_pxlcursor_shape(scr_stat *scp, int base, int height, int blink) 576{ 577 if (base < 0 || base >= scp->font_size) 578 return; 579 /* the caller may set height <= 0 in order to disable the cursor */ 580#if 0 581 scp->cursor_base = base; 582 scp->cursor_height = height; 583#endif 584} 585 586static void 587draw_pxlcursor(scr_stat *scp, int at, int on, int flip) 588{ 589 vm_offset_t d; 590 u_char *f; 591 int line_width; 592 int height; 593 int col; 594 int a; 595 int i; 596 u_char c; 597 598 line_width = scp->sc->adp->va_line_width; 599 d = scp->sc->adp->va_window 600 + scp->xoff 601 + scp->yoff*scp->font_size*line_width 602 + (at%scp->xsize) 603 + scp->font_size*line_width*(at/scp->xsize) 604 + (scp->font_size - scp->cursor_base - 1)*line_width; 605 606 outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */ 607 outw(GDCIDX, 0x0003); /* data rotate/function select */ 608 outw(GDCIDX, 0x0f01); /* set/reset enable */ 609 /* set background color in EGA/VGA latch */ 610 a = sc_vtb_geta(&scp->vtb, at); 611 if (flip) 612 col = (on) ? ((a & 0xf000) >> 4) : (a & 0x0f00); 613 else 614 col = (on) ? (a & 0x0f00) : ((a & 0xf000) >> 4); 615 outw(GDCIDX, col | 0x00); /* set/reset */ 616 outw(GDCIDX, 0xff08); /* bit mask */ 617 writeb(d, 0); 618 c = readb(d); /* set bg color in the latch */ 619 /* foreground color */ 620 if (flip) 621 col = (on) ? (a & 0x0f00) : ((a & 0xf000) >> 4); 622 else 623 col = (on) ? ((a & 0xf000) >> 4) : (a & 0x0f00); 624 outw(GDCIDX, col | 0x00); /* set/reset */ 625 f = &(scp->font[sc_vtb_getc(&scp->vtb, at)*scp->font_size 626 + scp->font_size - scp->cursor_base - 1]); 627 height = imin(scp->cursor_height, scp->font_size); 628 for (i = 0; i < height; ++i, --f) { 629 outw(GDCIDX, (*f << 8) | 0x08); /* bit mask */ 630 writeb(d, 0); 631 d -= line_width; 632 } 633 outw(GDCIDX, 0x0000); /* set/reset */ 634 outw(GDCIDX, 0x0001); /* set/reset enable */ 635 outw(GDCIDX, 0xff08); /* bit mask */ 636} 637 638static void 639vga_pxlcursor(scr_stat *scp, int at, int blink, int on, int flip) 640{ 641 if (scp->cursor_height <= 0) /* the text cursor is disabled */ 642 return; 643 644 if (on) { 645 scp->status |= VR_CURSOR_ON; 646 draw_pxlcursor(scp, at, on, flip); 647 } else { 648 if (scp->status & VR_CURSOR_ON) 649 draw_pxlcursor(scp, at, on, flip); 650 scp->status &= ~VR_CURSOR_ON; 651 } 652 if (blink) 653 scp->status |= VR_CURSOR_BLINK; 654 else 655 scp->status &= ~VR_CURSOR_BLINK; 656} 657 658static void 659vga_pxlblink(scr_stat *scp, int at, int flip) 660{ 661 static int blinkrate = 0; 662 663 if (!(scp->status & VR_CURSOR_BLINK)) 664 return; 665 if (!(++blinkrate & 4)) 666 return; 667 blinkrate = 0; 668 scp->status ^= VR_CURSOR_ON; 669 draw_pxlcursor(scp, at, scp->status & VR_CURSOR_ON, flip); 670} 671 672#ifndef SC_NO_CUTPASTE 673 674static void 675draw_pxlmouse(scr_stat *scp, int x, int y) 676{ 677 vm_offset_t p; 678 int line_width; 679 int xoff, yoff; 680 int ymax; 681 u_short m; 682 int i, j; 683 684 line_width = scp->sc->adp->va_line_width; 685 xoff = (x - scp->xoff*8)%8; 686 yoff = y - (y/line_width)*line_width; 687 ymax = imin(y + 16, scp->ypixel); 688 689 outw(GDCIDX, 0x0805); /* read mode 1, write mode 0 */ 690 outw(GDCIDX, 0x0001); /* set/reset enable */ 691 outw(GDCIDX, 0x0002); /* color compare */ 692 outw(GDCIDX, 0x0007); /* color don't care */ 693 outw(GDCIDX, 0xff08); /* bit mask */ 694 outw(GDCIDX, 0x0803); /* data rotate/function select (and) */ 695 p = scp->sc->adp->va_window + line_width*y + x/8; 696 if (x < scp->xpixel - 16) { 697 for (i = y, j = 0; i < ymax; ++i, ++j) { 698 m = ~(mouse_and_mask[j] >> xoff); 699#ifdef __i386__ 700 *(u_char *)p &= m >> 8; 701 *(u_char *)(p + 1) &= m; 702#elif defined(__alpha__) 703 writeb(p, readb(p) & (m >> 8)); 704 writeb(p + 1, readb(p + 1) & (m >> 8)); 705#endif 706 p += line_width; 707 } 708 } else { 709 xoff += 8; 710 for (i = y, j = 0; i < ymax; ++i, ++j) { 711 m = ~(mouse_and_mask[j] >> xoff); 712#ifdef __i386__ 713 *(u_char *)p &= m; 714#elif defined(__alpha__) 715 writeb(p, readb(p) & (m >> 8)); 716#endif 717 p += line_width; 718 } 719 } 720 outw(GDCIDX, 0x1003); /* data rotate/function select (or) */ 721 p = scp->sc->adp->va_window + line_width*y + x/8; 722 if (x < scp->xpixel - 16) { 723 for (i = y, j = 0; i < ymax; ++i, ++j) { 724 m = mouse_or_mask[j] >> xoff; 725#ifdef __i386__ 726 *(u_char *)p &= m >> 8; 727 *(u_char *)(p + 1) &= m; 728#elif defined(__alpha__) 729 writeb(p, readb(p) & (m >> 8)); 730 writeb(p + 1, readb(p + 1) & (m >> 8)); 731#endif 732 p += line_width; 733 } 734 } else { 735 for (i = y, j = 0; i < ymax; ++i, ++j) { 736 m = mouse_or_mask[j] >> xoff; 737#ifdef __i386__ 738 *(u_char *)p &= m; 739#elif defined(__alpha__) 740 writeb(p, readb(p) & (m >> 8)); 741#endif 742 p += line_width; 743 } 744 } 745 outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */ 746 outw(GDCIDX, 0x0003); /* data rotate/function select */ 747} 748 749static void 750remove_pxlmouse(scr_stat *scp, int x, int y) 751{ 752 vm_offset_t p; 753 int col, row; 754 int pos; 755 int line_width; 756 int ymax; 757 int i; 758 759 /* erase the mouse cursor image */ 760 col = x/8 - scp->xoff; 761 row = y/scp->font_size - scp->yoff; 762 pos = row*scp->xsize + col; 763 i = (col < scp->xsize - 1) ? 2 : 1; 764 (*scp->rndr->draw)(scp, pos, i, FALSE); 765 if (row < scp->ysize - 1) 766 (*scp->rndr->draw)(scp, pos + scp->xsize, i, FALSE); 767 768 /* paint border if necessary */ 769 line_width = scp->sc->adp->va_line_width; 770 outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */ 771 outw(GDCIDX, 0x0003); /* data rotate/function select */ 772 outw(GDCIDX, 0x0f01); /* set/reset enable */ 773 outw(GDCIDX, 0xff08); /* bit mask */ 774 outw(GDCIDX, (scp->border << 8) | 0x00); /* set/reset */ 775 if (row == scp->ysize - 1) { 776 i = (scp->ysize + scp->yoff)*scp->font_size; 777 ymax = imin(i + scp->font_size, scp->ypixel); 778 p = scp->sc->adp->va_window + i*line_width + scp->xoff + col; 779 if (col < scp->xsize - 1) { 780 for (; i < ymax; ++i) { 781 writeb(p, 0); 782 writeb(p + 1, 0); 783 p += line_width; 784 } 785 } else { 786 for (; i < ymax; ++i) { 787 writeb(p, 0); 788 p += line_width; 789 } 790 } 791 } 792 if ((col == scp->xsize - 1) && (scp->xoff > 0)) { 793 i = (row + scp->yoff)*scp->font_size; 794 ymax = imin(i + scp->font_size*2, scp->ypixel); 795 p = scp->sc->adp->va_window + i*line_width 796 + scp->xoff + scp->xsize; 797 for (; i < ymax; ++i) { 798 writeb(p, 0); 799 p += line_width; 800 } 801 } 802 outw(GDCIDX, 0x0000); /* set/reset */ 803 outw(GDCIDX, 0x0001); /* set/reset enable */ 804} 805 806static void 807vga_pxlmouse(scr_stat *scp, int x, int y, int on) 808{ 809 if (on) 810 draw_pxlmouse(scp, x, y); 811 else 812 remove_pxlmouse(scp, x, y); 813} 814 815#endif /* SC_NO_CUTPASTE */ 816#endif /* SC_PIXEL_MODE */ 817 818#ifndef SC_NO_MODE_CHANGE 819 820/* graphics mode renderer */ 821 822static void 823vga_grborder(scr_stat *scp, int color) 824{ 825 (*vidsw[scp->sc->adapter]->set_border)(scp->sc->adp, color); 826} 827 828#endif 829 830#endif /* NSC > 0 && NVGA > 0 */
|