bmd.c revision 1.5
1/* $NetBSD: bmd.c,v 1.5 2015/02/14 05:03:09 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 <luna68k/stand/boot/samachdep.h> 82 83/* 84 * RFCNT register 85 */ 86 87union bmd_rfcnt { 88 struct { 89 int16_t rfc_hcnt; 90 int16_t rfc_vcnt; 91 } p; 92 uint32_t u; 93}; 94 95#define isprint(c) ((c) >= 0x20 && (c) < 0x7f) 96 97/* 98 * Width & Height 99 */ 100 101#define PB_WIDTH 2048 /* Plane Width (Bit) */ 102#define PB_HEIGHT 1024 /* Plane Hight (Bit) */ 103#define PL_WIDTH 64 /* Plane Width (long) */ 104#define PS_WIDTH 128 /* Plane Width (long) */ 105#define P_WIDTH 256 /* Plane Width (Byte) */ 106 107#define SB_WIDTH 1280 /* Screen Width (Bit) */ 108#define SB_HEIGHT 1024 /* Screen Hight (Bit) */ 109#define SL_WIDTH 40 /* Screen Width (Long) */ 110#define S_WIDTH 160 /* Screen Width (Byte) */ 111 112#define FB_WIDTH 12 /* Font Width (Bit) */ 113#define FB_HEIGHT 20 /* Font Hight (Bit) */ 114 115 116#define NEXT_LINE(addr) (addr + (PL_WIDTH * FB_HEIGHT)) 117#define SKIP_NEXT_LINE(addr) (addr += (PL_WIDTH - SL_WIDTH)) 118 119 120void bmd_draw_char(uint8_t *, uint8_t *, int, int, int); 121void bmd_reverse_char(uint8_t *, uint8_t *, int, int); 122void bmd_erase_char(uint8_t *, uint8_t *, int, int); 123void bmd_erase_screen(volatile uint32_t *); 124void bmd_scroll_screen(volatile uint32_t *, volatile uint32_t *, 125 int, int, int, int); 126 127 128struct bmd_linec { 129 struct bmd_linec *bl_next; 130 struct bmd_linec *bl_prev; 131 int bl_col; 132 int bl_end; 133 uint8_t bl_line[128]; 134}; 135 136struct bmd_softc { 137 int bc_stat; 138 uint8_t *bc_raddr; 139 uint8_t *bc_waddr; 140 int bc_xmin; 141 int bc_xmax; 142 int bc_ymin; 143 int bc_ymax; 144 int bc_col; 145 int bc_row; 146 struct bmd_linec *bc_bl; 147 char bc_escseq[8]; 148 char *bc_esc; 149 void (*bc_escape)(int); 150}; 151 152#define STAT_NORMAL 0x0000 153#define STAT_ESCAPE 0x0001 154#define STAT_INSERT 0x0100 155 156struct bmd_softc bmd_softc; 157struct bmd_linec bmd_linec[52]; 158 159void bmd_escape(int); 160void bmd_escape_0(int); 161void bmd_escape_1(int); 162 163 164/* 165 * Escape-Sequence 166 */ 167 168void 169bmd_escape(int c) 170{ 171 struct bmd_softc *bp = &bmd_softc; 172 173 switch (c) { 174 175 case '[': 176 bp->bc_escape = bmd_escape_0; 177 break; 178 179 default: 180 bp->bc_stat &= ~STAT_ESCAPE; 181 bp->bc_esc = &bp->bc_escseq[0]; 182 bp->bc_escape = bmd_escape; 183 break; 184 } 185} 186 187void 188bmd_escape_0(int c) 189{ 190 struct bmd_softc *bp = &bmd_softc; 191 struct bmd_linec *bq = bp->bc_bl; 192 193 switch (c) { 194 195 case 'A': 196 if (bp->bc_row > bp->bc_ymin) { 197 bp->bc_row--; 198 } 199 break; 200 201 case 'C': 202 if (bq->bl_col < bp->bc_xmax - 1) { 203 bq->bl_col++; 204 } 205 break; 206 207 case 'K': 208 if (bq->bl_col < bp->bc_xmax) { 209 int col; 210 for (col = bq->bl_col; col < bp->bc_xmax; col++) 211 bmd_erase_char(bp->bc_raddr, 212 bp->bc_waddr, 213 col, bp->bc_row); 214 } 215 bq->bl_end = bq->bl_col; 216 break; 217 218 case 'H': 219 bq->bl_col = bq->bl_end = bp->bc_xmin; 220 bp->bc_row = bp->bc_ymin; 221 break; 222 223 default: 224#if 0 225 *bp->bc_esc++ = c; 226 bp->bc_escape = bmd_escape_1; 227 return; 228#endif 229 break; 230 } 231 232 bp->bc_stat &= ~STAT_ESCAPE; 233 bp->bc_esc = &bp->bc_escseq[0]; 234 bp->bc_escape = bmd_escape; 235} 236 237void 238bmd_escape_1(int c) 239{ 240 struct bmd_softc *bp = &bmd_softc; 241 struct bmd_linec *bq = bp->bc_bl; 242 int col = 0, row = 0; 243 char *p; 244 245 switch (c) { 246 247 case 'J': 248 bp->bc_stat &= ~STAT_ESCAPE; 249 bp->bc_esc = &bp->bc_escseq[0]; 250 bp->bc_escape = bmd_escape; 251 break; 252 253 case 'H': 254 for (p = &bp->bc_escseq[0]; *p != ';'; p++) 255 row = (row * 10) + (*p - 0x30); 256 p++; 257 for (p = &bp->bc_escseq[0]; p != bp->bc_esc; p++) 258 col = (col * 10) + (*p - 0x30); 259 260 bq->bl_col = col + bp->bc_xmin; 261 bp->bc_row = row + bp->bc_ymin; 262 263 bp->bc_stat &= ~STAT_ESCAPE; 264 bp->bc_esc = &bp->bc_escseq[0]; 265 bp->bc_escape = bmd_escape; 266 break; 267 268 default: 269 *bp->bc_esc++ = c; 270 break; 271 } 272} 273 274 275/* 276 * Entry Routine 277 */ 278 279void 280bmdinit(void) 281{ 282 volatile uint32_t *bmd_rfcnt = (uint32_t *)0xB1000000; 283 volatile uint32_t *bmd_bmsel = (uint32_t *)0xB1040000; 284 struct bmd_softc *bp = &bmd_softc; 285 struct bmd_linec *bq; 286 int i; 287 union bmd_rfcnt rfcnt; 288 289 /* 290 * adjust plane position 291 */ 292 293 bp->bc_raddr = (uint8_t *)0xB10C0008; /* plane-0 hardware address */ 294 bp->bc_waddr = (uint8_t *)0xB1080008; /* common bitmap hardware address */ 295 rfcnt.p.rfc_hcnt = 7; /* shift left 16 dot */ 296 rfcnt.p.rfc_vcnt = -27; /* shift down 1 dot */ 297 *bmd_rfcnt = rfcnt.u; 298 299 bp->bc_stat = STAT_NORMAL; 300 301 bp->bc_xmin = 8; 302 bp->bc_xmax = 96; 303 bp->bc_ymin = 2; 304 bp->bc_ymax = 48; 305 306 bp->bc_row = bp->bc_ymin; 307 308 for (i = bp->bc_ymin; i < bp->bc_ymax; i++) { 309 bmd_linec[i].bl_next = &bmd_linec[i + 1]; 310 bmd_linec[i].bl_prev = &bmd_linec[i - 1]; 311 } 312 bmd_linec[bp->bc_ymax - 1].bl_next = &bmd_linec[bp->bc_ymin]; 313 bmd_linec[bp->bc_ymin].bl_prev = &bmd_linec[bp->bc_ymax - 1]; 314 315 bq = bp->bc_bl = &bmd_linec[bp->bc_ymin]; 316 bq->bl_col = bq->bl_end = bp->bc_xmin; 317 318 bp->bc_col = bp->bc_xmin; 319 320 bp->bc_esc = &bp->bc_escseq[0]; 321 bp->bc_escape = bmd_escape; 322 323 *bmd_bmsel = 0xff; /* all planes */ 324 bmd_erase_screen((uint32_t *)bp->bc_waddr); /* clear screen */ 325 *bmd_bmsel = 0x01; /* 1 plane */ 326 327 /* turn on cursole */ 328 bmd_reverse_char(bp->bc_raddr, 329 bp->bc_waddr, 330 bq->bl_col, bp->bc_row); 331} 332 333void 334bmdadjust(int16_t hcnt, int16_t vcnt) 335{ 336 volatile uint32_t *bmd_rfcnt = (uint32_t *)0xB1000000; 337 union bmd_rfcnt rfcnt; 338 339 printf("bmdadjust: hcnt = %d, vcnt = %d\n", hcnt, vcnt); 340 341 rfcnt.p.rfc_hcnt = hcnt; /* shift left 16 dot */ 342 rfcnt.p.rfc_vcnt = vcnt; /* shift down 1 dot */ 343 344 *bmd_rfcnt = rfcnt.u; 345} 346 347int 348bmdputc(int c) 349{ 350 struct bmd_softc *bp = &bmd_softc; 351 struct bmd_linec *bq = bp->bc_bl; 352 int i; 353 354 c &= 0x7F; 355 /* turn off cursole */ 356 bmd_reverse_char(bp->bc_raddr, 357 bp->bc_waddr, 358 bq->bl_col, bp->bc_row); 359 /* do escape-sequence */ 360 if (bp->bc_stat & STAT_ESCAPE) { 361 *bp->bc_esc++ = c; 362 (*bp->bc_escape)(c); 363 goto done; 364 } 365 366 if (isprint(c)) { 367 bmd_draw_char(bp->bc_raddr, bp->bc_waddr, 368 bq->bl_col, bp->bc_row, c); 369 bq->bl_col++; 370 bq->bl_end++; 371 if (bq->bl_col >= bp->bc_xmax) { 372 bq->bl_col = bq->bl_end = bp->bc_xmin; 373 bp->bc_row++; 374 if (bp->bc_row >= bp->bc_ymax) { 375 bmd_scroll_screen((uint32_t *)bp->bc_raddr, 376 (uint32_t *)bp->bc_waddr, 377 bp->bc_xmin, bp->bc_xmax, 378 bp->bc_ymin, bp->bc_ymax); 379 380 bp->bc_row = bp->bc_ymax - 1; 381 } 382 } 383 } else { 384 switch (c) { 385 case 0x08: /* BS */ 386 if (bq->bl_col > bp->bc_xmin) { 387 bq->bl_col--; 388 } 389 break; 390 391 case 0x09: /* HT */ 392 case 0x0B: /* VT */ 393 i = ((bq->bl_col / 8) + 1) * 8; 394 if (i < bp->bc_xmax) { 395 bq->bl_col = bq->bl_end = i; 396 } 397 break; 398 399 case 0x0A: /* NL */ 400 bp->bc_row++; 401 if (bp->bc_row >= bp->bc_ymax) { 402 bmd_scroll_screen((uint32_t *)bp->bc_raddr, 403 (uint32_t *)bp->bc_waddr, 404 bp->bc_xmin, bp->bc_xmax, 405 bp->bc_ymin, bp->bc_ymax); 406 407 bp->bc_row = bp->bc_ymax - 1; 408 } 409 break; 410 411 case 0x0D: /* CR */ 412 bq->bl_col = bp->bc_xmin; 413 break; 414 415 case 0x1b: /* ESC */ 416 bp->bc_stat |= STAT_ESCAPE; 417 *bp->bc_esc++ = 0x1b; 418 break; 419 420 case 0x7F: /* DEL */ 421 if (bq->bl_col > bp->bc_xmin) { 422 bq->bl_col--; 423 bmd_erase_char(bp->bc_raddr, 424 bp->bc_waddr, 425 bq->bl_col, bp->bc_row); 426 } 427 break; 428 429 default: 430 break; 431 } 432 } 433 434 done: 435 /* turn on cursole */ 436 bmd_reverse_char(bp->bc_raddr, 437 bp->bc_waddr, 438 bq->bl_col, bp->bc_row); 439 440 return c; 441} 442 443void 444bmdclear(void) 445{ 446 struct bmd_softc *bp = &bmd_softc; 447 struct bmd_linec *bq = bp->bc_bl; 448 449 bmd_erase_screen((uint32_t *)bp->bc_waddr); /* clear screen */ 450 451 bq->bl_col = bq->bl_end = bp->bc_xmin; 452 bp->bc_row = bp->bc_ymin; 453 454 bmd_reverse_char(bp->bc_raddr, 455 bp->bc_waddr, 456 bq->bl_col, bp->bc_row); /* turn on cursole */ 457} 458 459 460/* 461 * charactor operation routines 462 */ 463 464void 465bmd_draw_char(uint8_t *raddr, uint8_t *waddr, int col, int row, int c) 466{ 467 volatile uint16_t *p, *q; 468 volatile uint32_t *lp, *lq; 469 const uint16_t *fp; 470 int i; 471 472 fp = &bmdfont[c][0]; 473 474 switch (col % 4) { 475 476 case 0: 477 p = (uint16_t *)(raddr + ((row * FB_HEIGHT) << 8) 478 + ((col / 4) * 6)); 479 q = (uint16_t *)(waddr + ((row * FB_HEIGHT) << 8) 480 + ((col / 4) * 6)); 481 for (i = 0; i < FB_HEIGHT; i++) { 482 *q = (*p & 0x000F) | (*fp & 0xFFF0); 483 p += 128; 484 q += 128; 485 fp++; 486 } 487 break; 488 489 case 1: 490 lp = (uint32_t *)(raddr + ((row * FB_HEIGHT) << 8) 491 + ((col / 4) * 6)); 492 lq = (uint32_t *)(waddr + ((row * FB_HEIGHT) << 8) 493 + ((col / 4) * 6)); 494 for (i = 0; i < FB_HEIGHT; i++) { 495 *lq = (*lp & 0xFFF000FF) | 496 ((uint32_t)(*fp & 0xFFF0) << 4); 497 lp += 64; 498 lq += 64; 499 fp++; 500 } 501 break; 502 503 case 2: 504 lp = (uint32_t *)(raddr + ((row * FB_HEIGHT) << 8) 505 + ((col / 4) * 6) + 2); 506 lq = (uint32_t *)(waddr + ((row * FB_HEIGHT) << 8) 507 + ((col / 4) * 6) + 2); 508 for (i = 0; i < FB_HEIGHT; i++) { 509 *lq = (*lp & 0xFF000FFF) | 510 ((uint32_t)(*fp & 0xFFF0) << 8); 511 lp += 64; 512 lq += 64; 513 fp++; 514 } 515 break; 516 517 case 3: 518 p = (uint16_t *)(raddr + ((row * FB_HEIGHT) << 8) 519 + ((col / 4) * 6) + 4); 520 q = (uint16_t *)(waddr + ((row * FB_HEIGHT) << 8) 521 + ((col / 4) * 6) + 4); 522 for (i = 0; i < FB_HEIGHT; i++) { 523 *q = (*p & 0xF000) | ((*fp & 0xFFF0) >> 4); 524 p += 128; 525 q += 128; 526 fp++; 527 } 528 break; 529 530 default: 531 break; 532 } 533} 534 535void 536bmd_reverse_char(uint8_t *raddr, uint8_t *waddr, int col, int row) 537{ 538 volatile uint16_t *p, *q; 539 volatile uint32_t *lp, *lq; 540 int i; 541 542 switch (col % 4) { 543 544 case 0: 545 p = (uint16_t *)(raddr + ((row * FB_HEIGHT) << 8) 546 + ((col / 4) * 6)); 547 q = (uint16_t *)(waddr + ((row * FB_HEIGHT) << 8) 548 + ((col / 4) * 6)); 549 for (i = 0; i < FB_HEIGHT; i++) { 550 *q = (*p & 0x000F) | (~(*p) & 0xFFF0); 551 p += 128; 552 q += 128; 553 } 554 break; 555 556 case 1: 557 lp = (uint32_t *)(raddr + ((row * FB_HEIGHT) << 8) 558 + ((col / 4) * 6)); 559 lq = (uint32_t *)(waddr + ((row * FB_HEIGHT) << 8) 560 + ((col / 4) * 6)); 561 for (i = 0; i < FB_HEIGHT; i++) { 562 *lq = (*lp & 0xFFF000FF) | (~(*lp) & 0x000FFF00); 563 lp += 64; 564 lq += 64; 565 } 566 break; 567 568 case 2: 569 lp = (uint32_t *)(raddr + ((row * FB_HEIGHT) << 8) 570 + ((col / 4) * 6) + 2); 571 lq = (uint32_t *)(waddr + ((row * FB_HEIGHT) << 8) 572 + ((col / 4) * 6) + 2); 573 for (i = 0; i < FB_HEIGHT; i++) { 574 *lq = (*lp & 0xFF000FFF) | (~(*lp) & 0x00FFF000); 575 lp += 64; 576 lq += 64; 577 } 578 break; 579 580 case 3: 581 p = (uint16_t *)(raddr + ((row * FB_HEIGHT) << 8) 582 + ((col / 4) * 6) + 4); 583 q = (uint16_t *)(waddr + ((row * FB_HEIGHT) << 8) 584 + ((col / 4) * 6) + 4); 585 for (i = 0; i < FB_HEIGHT; i++) { 586 *q = (*p & 0xF000) | (~(*p) & 0x0FFF); 587 p += 128; 588 q += 128; 589 } 590 break; 591 592 default: 593 break; 594 } 595} 596 597void 598bmd_erase_char(uint8_t *raddr, uint8_t *waddr, int col, int row) 599{ 600 601 bmd_draw_char(raddr, waddr, col, row, 0); 602} 603 604 605/* 606 * screen operation routines 607 */ 608 609void 610bmd_erase_screen(volatile uint32_t *lp) 611{ 612 int i, j; 613 614 for (i = 0; i < SB_HEIGHT; i++) { 615 for (j = 0; j < SL_WIDTH; j++) 616 *lp++ = 0; 617 SKIP_NEXT_LINE(lp); 618 } 619} 620 621void 622bmd_scroll_screen(volatile uint32_t *lp, volatile uint32_t *lq, 623 int xmin, int xmax, int ymin, int ymax) 624{ 625 int i, j; 626 627 lp += ((PL_WIDTH * FB_HEIGHT) * (ymin + 1)); 628 lq += ((PL_WIDTH * FB_HEIGHT) * ymin); 629 630 for (i = 0; i < ((ymax - ymin -1) * FB_HEIGHT); i++) { 631 for (j = 0; j < SL_WIDTH; j++) { 632 *lq++ = *lp++; 633 } 634 lp += (PL_WIDTH - SL_WIDTH); 635 lq += (PL_WIDTH - SL_WIDTH); 636 } 637 638 for (i = 0; i < FB_HEIGHT; i++) { 639 for (j = 0; j < SL_WIDTH; j++) { 640 *lq++ = 0; 641 } 642 lq += (PL_WIDTH - SL_WIDTH); 643 } 644} 645