1 /* $OpenBSD: bmd.c,v 1.4 2013/10/29 21:49:07 miod Exp $ */ 2 /* $NetBSD: bmd.c,v 1.2 2013/01/20 13:35:43 tsutsui Exp $ */ 3 4 /* 5 * Copyright (c) 1992 OMRON Corporation. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * OMRON Corporation. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the University of 21 * California, Berkeley and its contributors. 22 * 4. Neither the name of the University nor the names of its contributors 23 * may be used to endorse or promote products derived from this software 24 * without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 * 38 * @(#)bmd.c 8.2 (Berkeley) 8/15/93 39 */ 40 /* 41 * Copyright (c) 1992, 1993 42 * The Regents of the University of California. All rights reserved. 43 * 44 * This code is derived from software contributed to Berkeley by 45 * OMRON Corporation. 46 * 47 * Redistribution and use in source and binary forms, with or without 48 * modification, are permitted provided that the following conditions 49 * are met: 50 * 1. Redistributions of source code must retain the above copyright 51 * notice, this list of conditions and the following disclaimer. 52 * 2. Redistributions in binary form must reproduce the above copyright 53 * notice, this list of conditions and the following disclaimer in the 54 * documentation and/or other materials provided with the distribution. 55 * 3. Neither the name of the University nor the names of its contributors 56 * may be used to endorse or promote products derived from this software 57 * without specific prior written permission. 58 * 59 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 60 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 61 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 62 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 63 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 64 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 65 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 66 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 67 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 68 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 69 * SUCH DAMAGE. 70 * 71 * @(#)bmd.c 8.2 (Berkeley) 8/15/93 72 */ 73 /* 74 75 * bmd.c --- Bitmap-Display raw-level driver routines 76 * 77 * by A.Fujita, SEP-09-1992 78 */ 79 80 81 #include <sys/param.h> 82 #include <machine/board.h> 83 #include <luna88k/stand/boot/samachdep.h> 84 85 /* 86 * RFCNT register 87 */ 88 89 union bmd_rfcnt { 90 struct { 91 short rfc_hcnt; 92 short rfc_vcnt; 93 } p; 94 uint32_t u; 95 }; 96 97 #define isprint(c) ((c) >= 0x20 && (c) < 0x7f) 98 99 /* 100 * Width & Height 101 */ 102 103 #define PB_WIDTH 2048 /* Plane Width (Bit) */ 104 #define PB_HEIGHT 1024 /* Plane Height (Bit) */ 105 #define PS_WIDTH 128 /* Plane Width (Short) */ 106 #define P_WIDTH 256 /* Plane Width (Byte) */ 107 108 #define SB_WIDTH 1280 /* Screen Width (Bit) */ 109 #define SB_HEIGHT 1024 /* Screen Height (Bit) */ 110 #define SS_WIDTH 80 /* Screen Width (Short) */ 111 #define S_WIDTH 160 /* Screen Width (Byte) */ 112 113 #define FB_WIDTH 12 /* Font Width (Bit) */ 114 #define FB_HEIGHT 20 /* Font Height (Bit) */ 115 116 117 #define NEXT_LINE(addr) ((addr) + (PS_WIDTH * FB_HEIGHT)) 118 #define SKIP_NEXT_LINE(addr) (addr) += (PS_WIDTH - SS_WIDTH) 119 120 121 void bmd_draw_char(char *, char *, int, int, int); 122 void bmd_reverse_char(char *, char *, int, int); 123 void bmd_erase_char(char *, char *, int, int); 124 void bmd_erase_screen(volatile u_short *); 125 void bmd_scroll_screen(volatile u_short *, volatile u_short *, 126 int, int, int, int); 127 128 129 struct bmd_linec { 130 struct bmd_linec *bl_next; 131 struct bmd_linec *bl_prev; 132 int bl_col; 133 int bl_end; 134 u_char bl_line[128]; 135 }; 136 137 struct bmd_softc { 138 int bc_stat; 139 char *bc_raddr; 140 char *bc_waddr; 141 int bc_xmin; 142 int bc_xmax; 143 int bc_ymin; 144 int bc_ymax; 145 int bc_col; 146 int bc_row; 147 struct bmd_linec *bc_bl; 148 char bc_escseq[8]; 149 char *bc_esc; 150 void (*bc_escape)(int); 151 }; 152 153 #define STAT_NORMAL 0x0000 154 #define STAT_ESCAPE 0x0001 155 #define STAT_INSERT 0x0100 156 157 struct bmd_softc bmd_softc; 158 struct bmd_linec bmd_linec[52]; 159 160 void bmd_escape(int); 161 void bmd_escape_0(int); 162 void bmd_escape_1(int); 163 164 165 /* 166 * Escape-Sequence 167 */ 168 169 void 170 bmd_escape(int c) 171 { 172 struct bmd_softc *bp = &bmd_softc; 173 174 switch (c) { 175 176 case '[': 177 bp->bc_escape = bmd_escape_0; 178 break; 179 180 default: 181 bp->bc_stat &= ~STAT_ESCAPE; 182 bp->bc_esc = &bp->bc_escseq[0]; 183 bp->bc_escape = bmd_escape; 184 break; 185 } 186 } 187 188 void 189 bmd_escape_0(int c) 190 { 191 struct bmd_softc *bp = &bmd_softc; 192 struct bmd_linec *bq = bp->bc_bl; 193 194 switch (c) { 195 196 case 'A': 197 if (bp->bc_row > bp->bc_ymin) { 198 bp->bc_row--; 199 } 200 break; 201 202 case 'C': 203 if (bq->bl_col < bp->bc_xmax - 1) { 204 bq->bl_col++; 205 } 206 break; 207 208 case 'K': 209 if (bq->bl_col < bp->bc_xmax) { 210 int col; 211 for (col = bq->bl_col; col < bp->bc_xmax; col++) 212 bmd_erase_char(bp->bc_raddr, 213 bp->bc_waddr, 214 col, bp->bc_row); 215 } 216 bq->bl_end = bq->bl_col; 217 break; 218 219 case 'H': 220 bq->bl_col = bq->bl_end = bp->bc_xmin; 221 bp->bc_row = bp->bc_ymin; 222 break; 223 224 default: 225 /* 226 *bp->bc_esc++ = c; 227 bp->bc_escape = bmd_escape_1; 228 return; 229 */ 230 break; 231 } 232 233 bp->bc_stat &= ~STAT_ESCAPE; 234 bp->bc_esc = &bp->bc_escseq[0]; 235 bp->bc_escape = bmd_escape; 236 } 237 238 void 239 bmd_escape_1(int c) 240 { 241 struct bmd_softc *bp = &bmd_softc; 242 struct bmd_linec *bq = bp->bc_bl; 243 int col = 0, row = 0; 244 char *p; 245 246 switch (c) { 247 248 case 'J': 249 bp->bc_stat &= ~STAT_ESCAPE; 250 bp->bc_esc = &bp->bc_escseq[0]; 251 bp->bc_escape = bmd_escape; 252 break; 253 254 case 'H': 255 for (p = &bp->bc_escseq[0]; *p != ';'; p++) 256 row = (row * 10) + (*p - 0x30); 257 p++; 258 for (p = &bp->bc_escseq[0]; p != bp->bc_esc; p++) 259 col = (col * 10) + (*p - 0x30); 260 261 bq->bl_col = col + bp->bc_xmin; 262 bp->bc_row = row + bp->bc_ymin; 263 264 bp->bc_stat &= ~STAT_ESCAPE; 265 bp->bc_esc = &bp->bc_escseq[0]; 266 bp->bc_escape = bmd_escape; 267 break; 268 269 default: 270 *bp->bc_esc++ = c; 271 break; 272 } 273 } 274 275 276 /* 277 * Entry Routine 278 */ 279 280 void 281 bmdinit(void) 282 { 283 volatile uint32_t *bmd_rfcnt = (volatile uint32_t *)BMAP_RFCNT; 284 volatile long *bmd_bmsel = (volatile long *)BMAP_BMSEL; 285 struct bmd_softc *bp = &bmd_softc; 286 struct bmd_linec *bq; 287 int i; 288 union bmd_rfcnt rfcnt; 289 290 /* 291 * adjust plane position 292 */ 293 294 bp->bc_raddr = (char *)(BMAP_BMAP0 + 8); /* plane-0 hardware address */ 295 bp->bc_waddr = (char *)(BMAP_BMP + 8); /* common bitmap hardware address */ 296 rfcnt.p.rfc_hcnt = 7; /* shift left 16 dot */ 297 rfcnt.p.rfc_vcnt = -27; /* shift down 1 dot */ 298 *bmd_rfcnt = rfcnt.u; 299 300 bp->bc_stat = STAT_NORMAL; 301 302 bp->bc_xmin = 8; 303 bp->bc_xmax = 96; 304 bp->bc_ymin = 2; 305 bp->bc_ymax = 48; 306 307 bp->bc_row = bp->bc_ymin; 308 309 for (i = bp->bc_ymin; i < bp->bc_ymax; i++) { 310 bmd_linec[i].bl_next = &bmd_linec[i+1]; 311 bmd_linec[i].bl_prev = &bmd_linec[i-1]; 312 } 313 bmd_linec[bp->bc_ymax-1].bl_next = &bmd_linec[bp->bc_ymin]; 314 bmd_linec[bp->bc_ymin].bl_prev = &bmd_linec[bp->bc_ymax-1]; 315 316 bq = bp->bc_bl = &bmd_linec[bp->bc_ymin]; 317 bq->bl_col = bq->bl_end = bp->bc_xmin; 318 319 bp->bc_col = bp->bc_xmin; 320 321 bp->bc_esc = &bp->bc_escseq[0]; 322 bp->bc_escape = bmd_escape; 323 324 *bmd_bmsel = 0xff; /* all planes */ 325 bmd_erase_screen((u_short *) bp->bc_waddr); /* clear screen */ 326 *bmd_bmsel = 0x01; /* 1 plane */ 327 328 /* turn on cursole */ 329 bmd_reverse_char(bp->bc_raddr, 330 bp->bc_waddr, 331 bq->bl_col, bp->bc_row); 332 } 333 334 void 335 bmdadjust(short hcnt, short vcnt) 336 { 337 volatile uint32_t *bmd_rfcnt = (volatile uint32_t *)BMAP_RFCNT; 338 union bmd_rfcnt rfcnt; 339 340 printf("bmdadjust: hcnt = %d, vcnt = %d\n", hcnt, vcnt); 341 342 rfcnt.p.rfc_hcnt = hcnt; /* shift left 16 dot */ 343 rfcnt.p.rfc_vcnt = vcnt; /* shift down 1 dot */ 344 345 *bmd_rfcnt = rfcnt.u; 346 } 347 348 int 349 bmdputc(int c) 350 { 351 struct bmd_softc *bp = &bmd_softc; 352 struct bmd_linec *bq = bp->bc_bl; 353 int i; 354 355 c &= 0x7F; 356 /* turn off cursole */ 357 bmd_reverse_char(bp->bc_raddr, 358 bp->bc_waddr, 359 bq->bl_col, bp->bc_row); 360 /* do escape-sequence */ 361 if (bp->bc_stat & STAT_ESCAPE) { 362 *bp->bc_esc++ = c; 363 (*bp->bc_escape)(c); 364 goto done; 365 } 366 367 if (isprint(c)) { 368 bmd_draw_char(bp->bc_raddr, bp->bc_waddr, 369 bq->bl_col, bp->bc_row, c); 370 bq->bl_col++; 371 bq->bl_end++; 372 if (bq->bl_col >= bp->bc_xmax) { 373 bq->bl_col = bq->bl_end = bp->bc_xmin; 374 bp->bc_row++; 375 if (bp->bc_row >= bp->bc_ymax) { 376 bmd_scroll_screen((u_short *) bp->bc_raddr, 377 (u_short *) bp->bc_waddr, 378 bp->bc_xmin, bp->bc_xmax, 379 bp->bc_ymin, bp->bc_ymax); 380 381 bp->bc_row = bp->bc_ymax - 1; 382 } 383 } 384 } else { 385 switch (c) { 386 case 0x08: /* BS */ 387 if (bq->bl_col > bp->bc_xmin) { 388 bq->bl_col--; 389 } 390 break; 391 392 case 0x09: /* HT */ 393 case 0x0B: /* VT */ 394 i = ((bq->bl_col / 8) + 1) * 8; 395 if (i < bp->bc_xmax) { 396 bq->bl_col = bq->bl_end = i; 397 } 398 break; 399 400 case 0x0A: /* NL */ 401 bp->bc_row++; 402 if (bp->bc_row >= bp->bc_ymax) { 403 bmd_scroll_screen((u_short *) bp->bc_raddr, 404 (u_short *) bp->bc_waddr, 405 bp->bc_xmin, bp->bc_xmax, 406 bp->bc_ymin, bp->bc_ymax); 407 408 bp->bc_row = bp->bc_ymax - 1; 409 } 410 break; 411 412 case 0x0D: /* CR */ 413 bq->bl_col = bp->bc_xmin; 414 break; 415 416 case 0x1b: /* ESC */ 417 bp->bc_stat |= STAT_ESCAPE; 418 *bp->bc_esc++ = 0x1b; 419 break; 420 421 case 0x7F: /* DEL */ 422 if (bq->bl_col > bp->bc_xmin) { 423 bq->bl_col--; 424 bmd_erase_char(bp->bc_raddr, 425 bp->bc_waddr, 426 bq->bl_col, bp->bc_row); 427 } 428 break; 429 430 default: 431 break; 432 } 433 } 434 435 done: 436 /* turn on cursole */ 437 bmd_reverse_char(bp->bc_raddr, 438 bp->bc_waddr, 439 bq->bl_col, bp->bc_row); 440 441 return(c); 442 } 443 444 void 445 bmdclear(void) 446 { 447 struct bmd_softc *bp = &bmd_softc; 448 struct bmd_linec *bq = bp->bc_bl; 449 450 bmd_erase_screen((u_short *) bp->bc_waddr); /* clear screen */ 451 452 bq->bl_col = bq->bl_end = bp->bc_xmin; 453 bp->bc_row = bp->bc_ymin; 454 455 bmd_reverse_char(bp->bc_raddr, 456 bp->bc_waddr, 457 bq->bl_col, bp->bc_row); /* turn on cursole */ 458 } 459 460 461 /* 462 * charactor operation routines 463 */ 464 465 void 466 bmd_draw_char(char *raddr, char *waddr, int col, int row, int c) 467 { 468 volatile u_short *p, *q; 469 const u_short *fp; 470 int i; 471 472 fp = &bmdfont[c][0]; 473 474 switch (col % 4) { 475 476 case 0: 477 p = (u_short *) ( raddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 )); 478 q = (u_short *) ( waddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 )); 479 for (i = 0; i < FB_HEIGHT; i++) { 480 *q = (*p & 0x000F) | (*fp & 0xFFF0); 481 p += 128; 482 q += 128; 483 fp++; 484 } 485 break; 486 487 case 1: 488 p = (u_short *) ( raddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 )); 489 q = (u_short *) ( waddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 )); 490 for (i = 0; i < FB_HEIGHT; i++) { 491 q[0] = (p[0] & 0xFFF0) | ((*fp & 0xF000) >> 12); 492 q[1] = (p[1] & 0x00FF) | ((*fp & 0x0FF0) << 4); 493 p += 128; 494 q += 128; 495 fp++; 496 } 497 break; 498 499 case 2: 500 p = (u_short *) ( raddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 2 ); 501 q = (u_short *) ( waddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 2 ); 502 for (i = 0; i < FB_HEIGHT; i++) { 503 q[0] = (p[0] & 0xFF00) | ((*fp & 0xFF00) >> 8); 504 q[1] = (p[1] & 0x0FFF) | ((*fp & 0x00F0) << 8); 505 p += 128; 506 q += 128; 507 fp++; 508 } 509 break; 510 511 case 3: 512 p = (u_short *) ( raddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 4 ); 513 q = (u_short *) ( waddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 4 ); 514 for (i = 0; i < FB_HEIGHT; i++) { 515 *q = (*p & 0xF000) | ((*fp & 0xFFF0) >> 4); 516 p += 128; 517 q += 128; 518 fp++; 519 } 520 break; 521 522 default: 523 break; 524 } 525 } 526 527 void 528 bmd_reverse_char(char *raddr, char *waddr, int col, int row) 529 { 530 volatile u_short *p, *q; 531 int i; 532 533 switch (col%4) { 534 535 case 0: 536 p = (u_short *) ( raddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 )); 537 q = (u_short *) ( waddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 )); 538 for (i = 0; i < FB_HEIGHT; i++) { 539 *q = (*p & 0x000F) | (~(*p) & 0xFFF0); 540 p += 128; 541 q += 128; 542 } 543 break; 544 545 case 1: 546 p = (u_short *) ( raddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 )); 547 q = (u_short *) ( waddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 )); 548 for (i = 0; i < FB_HEIGHT; i++) { 549 q[0] = (p[0] & 0xFFF0) | (~p[0] & 0x000F); 550 q[1] = (p[1] & 0x00FF) | (~p[1] & 0xFF00); 551 p += 128; 552 q += 128; 553 } 554 break; 555 556 case 2: 557 p = (u_short *) ( raddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 2 ); 558 q = (u_short *) ( waddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 2 ); 559 for (i = 0; i < FB_HEIGHT; i++) { 560 q[0] = (p[0] & 0xFF00) | (~p[0] & 0x00FF); 561 q[1] = (p[1] & 0x0FFF) | (~p[1] & 0xF000); 562 p += 128; 563 q += 128; 564 } 565 break; 566 567 case 3: 568 p = (u_short *) ( raddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 4 ); 569 q = (u_short *) ( waddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 4 ); 570 for (i = 0; i < FB_HEIGHT; i++) { 571 *q = (*p & 0xF000) | (~(*p) & 0x0FFF); 572 p += 128; 573 q += 128; 574 } 575 break; 576 577 default: 578 break; 579 } 580 } 581 582 void 583 bmd_erase_char(char *raddr, char *waddr, int col, int row) 584 { 585 bmd_draw_char(raddr, waddr, col, row, 0); 586 587 return; 588 } 589 590 591 /* 592 * screen operation routines 593 */ 594 595 void 596 bmd_erase_screen(volatile u_short *p) 597 { 598 int i, j; 599 600 for (i = 0; i < SB_HEIGHT; i++) { 601 for (j = 0; j < SS_WIDTH; j++) 602 *p++ = 0; 603 SKIP_NEXT_LINE(p); 604 } 605 606 return; 607 } 608 609 void 610 bmd_scroll_screen(volatile u_short *p, volatile u_short *q, 611 int xmin, int xmax, int ymin, int ymax) 612 { 613 int i, j; 614 615 p += ((PS_WIDTH * FB_HEIGHT) * (ymin + 1)); 616 q += ((PS_WIDTH * FB_HEIGHT) * ymin); 617 618 for (i = 0; i < ((ymax - ymin -1) * FB_HEIGHT); i++) { 619 for (j = 0; j < SS_WIDTH; j++) { 620 *q++ = *p++; 621 } 622 p += (PS_WIDTH - SS_WIDTH); 623 q += (PS_WIDTH - SS_WIDTH); 624 } 625 626 for (i = 0; i < FB_HEIGHT; i++) { 627 for (j = 0; j < SS_WIDTH; j++) { 628 *q++ = 0; 629 } 630 q += (PS_WIDTH - SS_WIDTH); 631 } 632 633 } 634