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