1 /* $NetBSD: ite_tv.c,v 1.19 2022/06/25 03:57:17 tsutsui Exp $ */ 2 3 /* 4 * Copyright (c) 1997 Masaru Oki. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Masaru Oki. 18 * 4. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #include <sys/cdefs.h> 34 __KERNEL_RCSID(0, "$NetBSD: ite_tv.c,v 1.19 2022/06/25 03:57:17 tsutsui Exp $"); 35 36 #include <sys/param.h> 37 #include <sys/device.h> 38 #include <sys/proc.h> 39 #include <sys/systm.h> 40 41 #include <machine/bus.h> 42 #include <machine/grfioctl.h> 43 44 #include <arch/x68k/x68k/iodevice.h> 45 #include <arch/x68k/dev/itevar.h> 46 #include <arch/x68k/dev/grfvar.h> 47 #include <arch/x68k/dev/mfp.h> 48 49 /* 50 * ITE device dependent routine for X680x0 Text-Video framebuffer. 51 * Use X680x0 ROM fixed width font (8x16) 52 */ 53 54 #define CRTC (IODEVbase->io_crtc) 55 56 /* 57 * font constant 58 */ 59 #define FONTWIDTH 8 60 #define FONTHEIGHT 16 61 #define UNDERLINE 14 62 63 /* 64 * framebuffer constant 65 */ 66 #define PLANEWIDTH 1024 67 #define PLANEHEIGHT 1024 68 #define PLANELINES (PLANEHEIGHT / FONTHEIGHT) 69 #define ROWBYTES (PLANEWIDTH / FONTWIDTH) 70 #define PLANESIZE (PLANEHEIGHT * ROWBYTES) 71 72 static u_int tv_top; 73 static uint8_t *tv_row[PLANELINES]; 74 static uint8_t *tv_font[256]; 75 static volatile uint8_t *tv_kfont[0x7f]; 76 77 uint8_t kern_font[256 * FONTHEIGHT]; 78 79 #define PHYSLINE(y) ((tv_top + (y)) % PLANELINES) 80 #define ROWOFFSET(y) ((y) * FONTHEIGHT * ROWBYTES) 81 #define CHADDR(y, x) (tv_row[PHYSLINE(y)] + (x)) 82 83 #define SETGLYPH(to,from) \ 84 memcpy(&kern_font[(from) * 16],&kern_font[(to) * 16], 16) 85 #define KFONTBASE(left) ((left) * 32 * 0x5e - 0x21 * 32) 86 87 /* prototype */ 88 static void tv_putc(struct ite_softc *, int, int, int, int); 89 static void tv_cursor(struct ite_softc *, int); 90 static void tv_clear(struct ite_softc *, int, int, int, int); 91 static void tv_scroll(struct ite_softc *, int, int, int, int); 92 93 static inline uint32_t expbits(uint32_t); 94 static inline void txrascpy(uint8_t, uint8_t, int16_t, uint16_t); 95 96 static inline void 97 txrascpy(uint8_t src, uint8_t dst, int16_t size, uint16_t mode) 98 { 99 /*int s;*/ 100 uint16_t saved_r21 = CRTC.r21; 101 int8_t d; 102 103 d = ((mode & 0x8000) != 0) ? -1 : 1; 104 src *= FONTHEIGHT / 4; 105 dst *= FONTHEIGHT / 4; 106 size *= 4; 107 if (d < 0) { 108 src += (FONTHEIGHT / 4) - 1; 109 dst += (FONTHEIGHT / 4) - 1; 110 } 111 112 /* specify same time write mode & page */ 113 CRTC.r21 = (mode & 0x0f) | 0x0100; 114 /*mfp.ddr = 0;*/ /* port is input */ 115 116 /*s = splhigh();*/ 117 while (--size >= 0) { 118 /* wait for hsync */ 119 mfp_wait_for_hsync(); 120 CRTC.r22 = (src << 8) | dst; /* specify raster number */ 121 /* start raster copy */ 122 CRTC.crtctrl = 0x0008; 123 124 src += d; 125 dst += d; 126 } 127 /*splx(s);*/ 128 129 /* wait for hsync */ 130 mfp_wait_for_hsync(); 131 132 /* stop raster copy */ 133 CRTC.crtctrl = 0x0000; 134 135 CRTC.r21 = saved_r21; 136 } 137 138 /* 139 * Change glyphs from SRAM switch. 140 */ 141 void 142 ite_set_glyph(void) 143 { 144 uint8_t glyph = IODEVbase->io_sram[0x59]; 145 146 if ((glyph & 4) != 0) 147 SETGLYPH(0x82, '|'); 148 if ((glyph & 2) != 0) 149 SETGLYPH(0x81, '~'); 150 if ((glyph & 1) != 0) 151 SETGLYPH(0x80, '\\'); 152 } 153 154 /* 155 * Initialize 156 */ 157 void 158 tv_init(struct ite_softc *ip) 159 { 160 short i; 161 162 /* 163 * initialize private variables 164 */ 165 tv_top = 0; 166 for (i = 0; i < PLANELINES; i++) 167 tv_row[i] = 168 (void *)__UNVOLATILE(&IODEVbase->tvram[ROWOFFSET(i)]); 169 /* shadow ANK font */ 170 memcpy(kern_font, (void *)&IODEVbase->cgrom0_8x16, 256 * FONTHEIGHT); 171 ite_set_glyph(); 172 /* set font address cache */ 173 for (i = 0; i < 256; i++) 174 tv_font[i] = &kern_font[i * FONTHEIGHT]; 175 for (i = 0x21; i < 0x30; i++) 176 tv_kfont[i] = &IODEVbase->cgrom0_16x16[KFONTBASE(i-0x21)]; 177 for (; i < 0x50; i++) 178 tv_kfont[i] = &IODEVbase->cgrom1_16x16[KFONTBASE(i-0x30)]; 179 for (; i < 0x7f; i++) 180 tv_kfont[i] = &IODEVbase->cgrom2_16x16[KFONTBASE(i-0x50)]; 181 182 /* 183 * initialize part of ip 184 */ 185 ip->cols = ip->grf->g_display.gd_dwidth / FONTWIDTH; 186 ip->rows = ip->grf->g_display.gd_dheight / FONTHEIGHT; 187 /* set draw routine dynamically */ 188 ip->isw->ite_putc = tv_putc; 189 ip->isw->ite_cursor = tv_cursor; 190 ip->isw->ite_clear = tv_clear; 191 ip->isw->ite_scroll = tv_scroll; 192 193 /* 194 * Initialize colormap 195 */ 196 #define RED (0x1f << 6) 197 #define BLUE (0x1f << 1) 198 #define GREEN (0x1f << 11) 199 IODEVbase->tpalet[0] = 0; /* black */ 200 IODEVbase->tpalet[1] = 1 | RED; /* red */ 201 IODEVbase->tpalet[2] = 1 | GREEN; /* green */ 202 IODEVbase->tpalet[3] = 1 | RED | GREEN; /* yellow */ 203 IODEVbase->tpalet[4] = 1 | BLUE; /* blue */ 204 IODEVbase->tpalet[5] = 1 | BLUE | RED; /* magenta */ 205 IODEVbase->tpalet[6] = 1 | BLUE | GREEN; /* cyan */ 206 IODEVbase->tpalet[7] = 1 | BLUE | RED | GREEN; /* white */ 207 } 208 209 /* 210 * Deinitialize 211 */ 212 void 213 tv_deinit(struct ite_softc *ip) 214 { 215 216 ip->flags &= ~ITE_INITED; /* XXX? */ 217 } 218 219 static inline uint8_t *tv_getfont(int, int); 220 typedef void tv_putcfunc(struct ite_softc *, int, char *); 221 static tv_putcfunc tv_putc_nm; 222 static tv_putcfunc tv_putc_in; 223 static tv_putcfunc tv_putc_ul; 224 static tv_putcfunc tv_putc_ul_in; 225 static tv_putcfunc tv_putc_bd; 226 static tv_putcfunc tv_putc_bd_in; 227 static tv_putcfunc tv_putc_bd_ul; 228 static tv_putcfunc tv_putc_bd_ul_in; 229 230 static tv_putcfunc *putc_func[ATTR_ALL + 1] = { 231 [ATTR_NOR] = tv_putc_nm, 232 [ATTR_INV] = tv_putc_in, 233 [ATTR_UL] = tv_putc_ul, 234 [ATTR_INV | ATTR_UL] = tv_putc_ul_in, 235 [ATTR_BOLD] = tv_putc_bd, 236 [ATTR_BOLD | ATTR_INV] = tv_putc_bd_in, 237 [ATTR_BOLD | ATTR_UL] = tv_putc_bd_ul, 238 [ATTR_BOLD | ATTR_UL | ATTR_INV] = tv_putc_bd_ul_in, 239 /* no support for blink */ 240 [ATTR_BLINK] = tv_putc_nm, 241 [ATTR_BLINK | ATTR_INV] = tv_putc_in, 242 [ATTR_BLINK | ATTR_UL] = tv_putc_ul, 243 [ATTR_BLINK | ATTR_UL | ATTR_INV] = tv_putc_ul_in, 244 [ATTR_BLINK | ATTR_BOLD] = tv_putc_bd, 245 [ATTR_BLINK | ATTR_BOLD | ATTR_INV] = tv_putc_bd_in, 246 [ATTR_BLINK | ATTR_BOLD | ATTR_UL] = tv_putc_bd_ul, 247 [ATTR_BLINK | ATTR_BOLD | ATTR_UL | ATTR_INV] = tv_putc_bd_ul_in, 248 }; 249 250 /* 251 * simple put character function 252 */ 253 static void 254 tv_putc(struct ite_softc *ip, int ch, int y, int x, int mode) 255 { 256 uint8_t *p = CHADDR(y, x); 257 short fh; 258 259 /* multi page write mode */ 260 CRTC.r21 = 0x0100 | ip->fgcolor << 4; 261 262 /* draw plane */ 263 putc_func[mode](ip, ch, p); 264 265 /* erase plane */ 266 CRTC.r21 ^= 0x00f0; 267 if (ip->save_char) { 268 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES) 269 *(uint16_t *)p = 0; 270 } else { 271 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES) 272 *p = 0; 273 } 274 275 /* crtc mode reset */ 276 CRTC.r21 = 0; 277 } 278 279 static inline uint8_t * 280 tv_getfont(int cset, int ch) 281 { 282 283 if (cset == CSET_JISKANA) { 284 ch |= 0x80; 285 } else if (cset == CSET_DECGRAPH) { 286 if (ch < 0x80) { 287 ch = ite_decgraph2ascii[ch]; 288 } 289 } 290 291 return tv_font[ch]; 292 } 293 294 static void 295 tv_putc_nm(struct ite_softc *ip, int ch, char *p) 296 { 297 short fh, hi, lo; 298 volatile uint16_t *kf; 299 uint8_t *f; 300 301 hi = ip->save_char & 0x7f; 302 lo = ch & 0x7f; 303 304 if (hi >= 0x21 && hi <= 0x7e && lo >= 0x21 && lo <= 0x7e) { 305 /* multibyte character */ 306 kf = (volatile uint16_t *)tv_kfont[hi]; 307 kf += lo * FONTHEIGHT; 308 /* draw plane */ 309 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES) 310 *(uint16_t *)p = *kf++; 311 return; 312 } 313 314 /* singlebyte character */ 315 f = tv_getfont(*ip->GL, ch); 316 317 /* draw plane */ 318 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES) 319 *p = *f++; 320 } 321 322 static void 323 tv_putc_in(struct ite_softc *ip, int ch, char *p) 324 { 325 short fh, hi, lo; 326 volatile uint16_t *kf; 327 uint8_t *f; 328 329 hi = ip->save_char & 0x7f; 330 lo = ch & 0x7f; 331 332 if (hi >= 0x21 && hi <= 0x7e && lo >= 0x21 && lo <= 0x7e) { 333 /* multibyte character */ 334 kf = (volatile uint16_t *)tv_kfont[hi]; 335 kf += lo * FONTHEIGHT; 336 /* draw plane */ 337 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES) 338 *(uint16_t *)p = ~*kf++; 339 return; 340 } 341 342 /* singlebyte character */ 343 f = tv_getfont(*ip->GL, ch); 344 345 /* draw plane */ 346 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES) 347 *p = ~*f++; 348 } 349 350 static void 351 tv_putc_bd(struct ite_softc *ip, int ch, char *p) 352 { 353 short fh, hi, lo; 354 u_int data; 355 volatile uint16_t *kf; 356 uint8_t *f; 357 358 hi = ip->save_char & 0x7f; 359 lo = ch & 0x7f; 360 361 if (hi >= 0x21 && hi <= 0x7e && lo >= 0x21 && lo <= 0x7e) { 362 /* multibyte character */ 363 kf = (volatile uint16_t *)tv_kfont[hi]; 364 kf += lo * FONTHEIGHT; 365 /* draw plane */ 366 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES) { 367 data = *kf++; 368 *(uint16_t *)p = data | (data >> 1); 369 } 370 return; 371 } 372 373 /* singlebyte character */ 374 f = tv_getfont(*ip->GL, ch); 375 376 /* draw plane */ 377 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES) { 378 data = *f++; 379 *p = data | (data >> 1); 380 } 381 } 382 383 static inline uint32_t 384 expbits(uint32_t data) 385 { 386 int i; 387 u_int nd = 0; 388 389 if ((data & 1) != 0) 390 nd |= 0x02; 391 for (i = 1; i < 32; i++) { 392 if ((data & (1 << i)) != 0) 393 nd |= 0x5 << (i - 1); 394 } 395 nd &= ~data; 396 return ~nd; 397 } 398 399 static void 400 tv_putc_ul(struct ite_softc *ip, int ch, char *p) 401 { 402 short fh, hi, lo; 403 volatile uint16_t *kf; 404 uint8_t *f; 405 406 hi = ip->save_char & 0x7f; 407 lo = ch & 0x7f; 408 409 if (hi >= 0x21 && hi <= 0x7e && lo >= 0x21 && lo <= 0x7e) { 410 /* multibyte character */ 411 kf = (volatile uint16_t *)tv_kfont[hi]; 412 kf += lo * FONTHEIGHT; 413 /* draw plane */ 414 for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES) 415 *(uint16_t *)p = *kf++; 416 *(uint16_t *)p = expbits(*kf++); 417 p += ROWBYTES; 418 for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES) 419 *(uint16_t *)p = *kf++; 420 return; 421 } 422 423 /* singlebyte character */ 424 f = tv_getfont(*ip->GL, ch); 425 426 /* draw plane */ 427 for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES) 428 *p = *f++; 429 *p = expbits(*f++); 430 p += ROWBYTES; 431 for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES) 432 *p = *f++; 433 } 434 435 static void 436 tv_putc_bd_in(struct ite_softc *ip, int ch, char *p) 437 { 438 short fh, hi, lo; 439 u_int data; 440 volatile uint16_t *kf; 441 uint8_t *f; 442 443 hi = ip->save_char & 0x7f; 444 lo = ch & 0x7f; 445 446 if (hi >= 0x21 && hi <= 0x7e && lo >= 0x21 && lo <= 0x7e) { 447 /* multibyte character */ 448 kf = (volatile uint16_t *)tv_kfont[hi]; 449 kf += lo * FONTHEIGHT; 450 /* draw plane */ 451 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES) { 452 data = *kf++; 453 *(uint16_t *)p = ~(data | (data >> 1)); 454 } 455 return; 456 } 457 458 /* singlebyte character */ 459 f = tv_getfont(*ip->GL, ch); 460 461 /* draw plane */ 462 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES) { 463 data = *f++; 464 *p = ~(data | (data >> 1)); 465 } 466 } 467 468 static void 469 tv_putc_ul_in(struct ite_softc *ip, int ch, char *p) 470 { 471 short fh, hi, lo; 472 volatile uint16_t *kf; 473 uint8_t *f; 474 475 hi = ip->save_char & 0x7f; 476 lo = ch & 0x7f; 477 478 if (hi >= 0x21 && hi <= 0x7e && lo >= 0x21 && lo <= 0x7e) { 479 /* multibyte character */ 480 kf = (volatile uint16_t *)tv_kfont[hi]; 481 kf += lo * FONTHEIGHT; 482 /* draw plane */ 483 for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES) 484 *(uint16_t *)p = ~*kf++; 485 *(uint16_t *)p = ~expbits(*kf++); 486 p += ROWBYTES; 487 for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES) 488 *(uint16_t *)p = ~*kf++; 489 return; 490 } 491 492 /* singlebyte character */ 493 f = tv_getfont(*ip->GL, ch); 494 495 /* draw plane */ 496 for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES) 497 *p = ~*f++; 498 *p = ~expbits(*f++); 499 p += ROWBYTES; 500 for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES) 501 *p = ~*f++; 502 } 503 504 static void 505 tv_putc_bd_ul(struct ite_softc *ip, int ch, char *p) 506 { 507 short fh, hi, lo; 508 u_int data; 509 volatile uint16_t *kf; 510 uint8_t *f; 511 512 hi = ip->save_char & 0x7f; 513 lo = ch & 0x7f; 514 515 if (hi >= 0x21 && hi <= 0x7e && lo >= 0x21 && lo <= 0x7e) { 516 /* multibyte character */ 517 kf = (volatile uint16_t *)tv_kfont[hi]; 518 kf += lo * FONTHEIGHT; 519 /* draw plane */ 520 for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES) { 521 data = *kf++; 522 *(uint16_t *)p = data | (data >> 1); 523 } 524 data = *kf++; 525 *(uint16_t *)p = expbits(data | (data >> 1)); 526 p += ROWBYTES; 527 for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES) { 528 data = *kf++; 529 *(uint16_t *)p = data | (data >> 1); 530 } 531 return; 532 } 533 534 /* singlebyte character */ 535 f = tv_getfont(*ip->GL, ch); 536 537 /* draw plane */ 538 for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES) { 539 data = *f++; 540 *p = data | (data >> 1); 541 } 542 data = *f++; 543 *p = expbits(data | (data >> 1)); 544 p += ROWBYTES; 545 for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES) { 546 data = *f++; 547 *p = data | (data >> 1); 548 } 549 } 550 551 static void 552 tv_putc_bd_ul_in(struct ite_softc *ip, int ch, char *p) 553 { 554 short fh, hi, lo; 555 u_int data; 556 volatile uint16_t *kf; 557 uint8_t *f; 558 559 hi = ip->save_char & 0x7f; 560 lo = ch & 0x7f; 561 562 if (hi >= 0x21 && hi <= 0x7e && lo >= 0x21 && lo <= 0x7e) { 563 /* multibyte character */ 564 kf = (volatile uint16_t *)tv_kfont[hi]; 565 kf += lo * FONTHEIGHT; 566 /* draw plane */ 567 for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES) { 568 data = *kf++; 569 *(uint16_t *)p = ~(data | (data >> 1)); 570 } 571 data = *kf++; 572 *(uint16_t *)p = ~expbits(data | (data >> 1)); 573 p += ROWBYTES; 574 for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES) { 575 data = *kf++; 576 *(uint16_t *)p = ~(data | (data >> 1)); 577 } 578 return; 579 } 580 581 /* singlebyte character */ 582 f = tv_getfont(*ip->GL, ch); 583 584 /* draw plane */ 585 for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES) { 586 data = *f++; 587 *p = ~(data | (data >> 1)); 588 } 589 data = *f++; 590 *p = ~expbits(data | (data >> 1)); 591 p += ROWBYTES; 592 for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES) { 593 data = *f++; 594 data |= data >> 1; 595 *p = ~(data | (data >> 1)); 596 } 597 } 598 599 /* 600 * draw/erase/move cursor 601 */ 602 static void 603 tv_cursor(struct ite_softc *ip, int flag) 604 { 605 uint8_t *p; 606 short fh; 607 608 /* erase */ 609 switch (flag) { 610 /*case DRAW_CURSOR:*/ 611 /*case ERASE_CURSOR:*/ 612 /*case MOVE_CURSOR:*/ 613 case START_CURSOROPT: 614 /* 615 * old: ip->cursorx, ip->cursory 616 * new: ip->curx, ip->cury 617 */ 618 p = CHADDR(ip->cursory, ip->cursorx); 619 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES) 620 *p = ~*p; 621 break; 622 } 623 624 /* draw */ 625 switch (flag) { 626 /*case MOVE_CURSOR:*/ 627 case END_CURSOROPT: 628 /* 629 * Use exclusive-or. 630 */ 631 p = CHADDR(ip->cury, ip->curx); 632 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES) 633 *p = ~*p; 634 635 ip->cursorx = ip->curx; 636 ip->cursory = ip->cury; 637 break; 638 } 639 } 640 641 /* 642 * clear rectangle 643 */ 644 static void 645 tv_clear(struct ite_softc *ip, int y, int x, int height, int width) 646 { 647 uint8_t *p; 648 short fh; 649 650 /* XXX: reset scroll register on clearing whole screen */ 651 if (y == 0 && x == 0 && height == ip->rows && width == ip->cols) { 652 CRTC.r10 = 0; 653 CRTC.r11 = tv_top * FONTHEIGHT; 654 } 655 656 CRTC.r21 = 0x01f0; 657 while (height--) { 658 p = CHADDR(y++, x); 659 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES) 660 memset(p, 0, width); 661 } 662 /* crtc mode reset */ 663 CRTC.r21 = 0; 664 } 665 666 /* 667 * scroll lines/columns 668 */ 669 static void 670 tv_scroll(struct ite_softc *ip, int srcy, int srcx, int count, int dir) 671 { 672 int dst, siz, pl; 673 674 switch (dir) { 675 case SCROLL_UP: 676 /* 677 * src: srcy 678 * dst: (srcy - count) 679 * siz: (ip->bottom_margin - sy + 1) 680 */ 681 dst = srcy - count; 682 siz = ip->bottom_margin - srcy + 1; 683 if (dst == 0 && ip->bottom_margin == ip->rows - 1) { 684 /* special case, hardware scroll */ 685 tv_top = (tv_top + count) % PLANELINES; 686 CRTC.r11 = tv_top * FONTHEIGHT; 687 } else { 688 srcy = PHYSLINE(srcy); 689 dst = PHYSLINE(dst); 690 txrascpy(srcy, dst, siz, 0x0f); 691 } 692 break; 693 694 case SCROLL_DOWN: 695 /* 696 * src: srcy 697 * dst: (srcy + count) 698 * siz: (ip->bottom_margin - dy + 1) 699 */ 700 dst = srcy + count; 701 siz = ip->bottom_margin - dst + 1; 702 if (srcy == 0 && ip->bottom_margin == ip->rows - 1) { 703 /* special case, hardware scroll */ 704 tv_top = (tv_top + PLANELINES - count) % PLANELINES; 705 CRTC.r11 = tv_top * FONTHEIGHT; 706 } else { 707 srcy = PHYSLINE(srcy) + siz - 1; 708 dst = PHYSLINE(dst) + siz - 1; 709 txrascpy(srcy, dst, siz, 0x0f | 0x8000); 710 } 711 break; 712 713 case SCROLL_LEFT: 714 for (pl = 0; pl < PLANESIZE * 4; pl += PLANESIZE) { 715 short fh; 716 uint8_t *src = CHADDR(srcy, srcx) + pl; 717 uint8_t *dest = CHADDR(srcy, srcx - count) + pl; 718 719 siz = ip->cols - srcx; 720 for (fh = 0; fh < FONTHEIGHT; fh++) { 721 memcpy(dest, src, siz); 722 src += ROWBYTES; 723 dest += ROWBYTES; 724 } 725 } 726 break; 727 728 case SCROLL_RIGHT: 729 for (pl = 0; pl < PLANESIZE * 4; pl += PLANESIZE) { 730 short fh; 731 uint8_t *src = CHADDR(srcy, srcx) + pl; 732 uint8_t *dest = CHADDR(srcy, srcx + count) + pl; 733 734 siz = ip->cols - (srcx + count); 735 for (fh = 0; fh < FONTHEIGHT; fh++) { 736 memcpy(dest, src, siz); 737 src += ROWBYTES; 738 dest += ROWBYTES; 739 } 740 } 741 break; 742 } 743 } 744