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