1 /* 2 * Copyright (c) 1992 OMRON Corporation. 3 * Copyright (c) 1992, 1993 4 * The Regents of the University of California. All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * OMRON Corporation. 8 * 9 * %sccs.include.redist.c% 10 * 11 * @(#)bmd.c 8.1 (Berkeley) 06/10/93 12 */ 13 /* 14 15 * bmd.c --- Bitmap-Display raw-level driver routines 16 * 17 * by A.Fujita, SEP-09-1992 18 */ 19 20 21 #include <sys/param.h> 22 #include <sys/systm.h> 23 24 extern u_short bmdfont[][20]; 25 26 #define isprint(c) ( c < 0x20 ? 0 : 1) 27 28 /* 29 * RFCNT register 30 */ 31 32 struct bmd_rfcnt { 33 short rfc_hcnt; 34 short rfc_vcnt; 35 }; 36 37 38 /* 39 * Width & Hight 40 */ 41 42 #define PB_WIDTH 2048 /* Plane Width (Bit) */ 43 #define PB_HIGHT 1024 /* Plane Hight (Bit) */ 44 #define PL_WIDTH 64 /* Plane Width (long) */ 45 #define PS_WIDTH 128 /* Plane Width (long) */ 46 #define P_WIDTH 256 /* Plane Width (Byte) */ 47 48 #define SB_WIDTH 1280 /* Screen Width (Bit) */ 49 #define SB_HIGHT 1024 /* Screen Hight (Bit) */ 50 #define SL_WIDTH 40 /* Screen Width (Long) */ 51 #define S_WIDTH 160 /* Screen Width (Byte) */ 52 53 #define FB_WIDTH 12 /* Font Width (Bit) */ 54 #define FB_HIGHT 20 /* Font Hight (Bit) */ 55 56 57 #define NEXT_LINE(addr) ( addr + (PL_WIDTH * FB_HIGHT) ) 58 #define SKIP_NEXT_LINE(addr) ( addr += (PL_WIDTH - SL_WIDTH) ) 59 60 61 void bmd_add_new_line(); 62 63 void bmd_draw_char(); 64 void bmd_reverse_char(); 65 void bmd_erase_char(); 66 void bmd_erase_screen(); 67 void bmd_scroll_screen(); 68 69 70 struct bmd_linec { 71 struct bmd_linec *bl_next; 72 struct bmd_linec *bl_prev; 73 int bl_col; 74 int bl_end; 75 u_char bl_line[128]; 76 }; 77 78 struct bmd_softc { 79 int bc_stat; 80 char *bc_raddr; 81 char *bc_waddr; 82 int bc_xmin; 83 int bc_xmax; 84 int bc_ymin; 85 int bc_ymax; 86 int bc_col; 87 int bc_row; 88 struct bmd_linec *bc_bl; 89 char bc_escseq[8]; 90 char *bc_esc; 91 void (*bc_escape)(); 92 }; 93 94 #define STAT_NORMAL 0x0000 95 #define STAT_ESCAPE 0x0001 96 #define STAT_INSERT 0x0100 97 98 struct bmd_softc bmd_softc; 99 struct bmd_linec bmd_linec[52]; 100 101 void bmd_escape(); 102 void bmd_escape_0(); 103 void bmd_escape_1(); 104 105 106 /* 107 * Escape-Sequence 108 */ 109 110 void 111 bmd_escape(c) 112 int c; 113 { 114 register struct bmd_softc *bp = &bmd_softc; 115 116 switch (c) { 117 118 case '[': 119 bp->bc_escape = bmd_escape_0; 120 break; 121 122 default: 123 bp->bc_stat &= ~STAT_ESCAPE; 124 bp->bc_esc = &bp->bc_escseq[0]; 125 bp->bc_escape = bmd_escape; 126 break; 127 } 128 } 129 130 void 131 bmd_escape_0(c) 132 int c; 133 { 134 register struct bmd_softc *bp = &bmd_softc; 135 register struct bmd_linec *bq = bp->bc_bl; 136 137 switch (c) { 138 139 case 'A': 140 if (bp->bc_row > bp->bc_ymin) { 141 bp->bc_row--; 142 } 143 break; 144 145 case 'C': 146 if (bq->bl_col < bp->bc_xmax - 1) { 147 bq->bl_col++; 148 } 149 break; 150 151 case 'K': 152 if (bq->bl_col < bp->bc_xmax) { 153 register int col; 154 for (col = bq->bl_col; col < bp->bc_xmax; col++) 155 bmd_erase_char(bp->bc_raddr, 156 bp->bc_waddr, 157 col, bp->bc_row); 158 } 159 bq->bl_end = bq->bl_col; 160 break; 161 162 case 'H': 163 bq->bl_col = bq->bl_end = bp->bc_xmin; 164 bp->bc_row = bp->bc_ymin; 165 break; 166 167 default: 168 /* 169 *bp->bc_esc++ = c; 170 bp->bc_escape = bmd_escape_1; 171 return; 172 */ 173 break; 174 } 175 176 bp->bc_stat &= ~STAT_ESCAPE; 177 bp->bc_esc = &bp->bc_escseq[0]; 178 bp->bc_escape = bmd_escape; 179 } 180 181 void 182 bmd_escape_1(c) 183 int c; 184 { 185 register struct bmd_softc *bp = &bmd_softc; 186 register struct bmd_linec *bq = bp->bc_bl; 187 register int col = 0, row = 0; 188 register char *p; 189 190 switch (c) { 191 192 case 'J': 193 bp->bc_stat &= ~STAT_ESCAPE; 194 bp->bc_esc = &bp->bc_escseq[0]; 195 bp->bc_escape = bmd_escape; 196 break; 197 198 case 'H': 199 for (p = &bp->bc_escseq[0]; *p != ';'; p++) 200 row = (row * 10) + (*p - 0x30); 201 p++; 202 for (p = &bp->bc_escseq[0]; p != bp->bc_esc; p++) 203 col = (col * 10) + (*p - 0x30); 204 205 bq->bl_col = col + bp->bc_xmin; 206 bp->bc_row = row + bp->bc_ymin; 207 208 bp->bc_stat &= ~STAT_ESCAPE; 209 bp->bc_esc = &bp->bc_escseq[0]; 210 bp->bc_escape = bmd_escape; 211 break; 212 213 default: 214 *bp->bc_esc++ = c; 215 break; 216 } 217 } 218 219 220 /* 221 * Entry Routine 222 */ 223 224 bmdinit() 225 { 226 volatile register struct bmd_rfcnt *bmd_rfcnt = (struct bmd_rfcnt *) 0xB1000000; 227 register struct bmd_softc *bp = &bmd_softc; 228 register struct bmd_linec *bq; 229 register int i; 230 struct bmd_rfcnt rfcnt; 231 232 /* 233 * adjust plane position 234 */ 235 236 bp->bc_raddr = (char *) 0xB10C0008; /* plane-0 hardware address */ 237 bp->bc_waddr = (char *) 0xB1080008; /* common bitmap hardware address */ 238 rfcnt.rfc_hcnt = 7; /* shift left 16 dot */ 239 rfcnt.rfc_vcnt = -27; /* shift down 1 dot */ 240 *bmd_rfcnt = rfcnt; 241 242 bp->bc_stat = STAT_NORMAL; 243 244 bp->bc_xmin = 8; 245 bp->bc_xmax = 96; 246 bp->bc_ymin = 2; 247 bp->bc_ymax = 48; 248 249 bp->bc_row = bp->bc_ymin; 250 251 for (i = bp->bc_ymin; i < bp->bc_ymax; i++) { 252 bmd_linec[i].bl_next = &bmd_linec[i+1]; 253 bmd_linec[i].bl_prev = &bmd_linec[i-1]; 254 } 255 bmd_linec[bp->bc_ymax-1].bl_next = &bmd_linec[bp->bc_ymin]; 256 bmd_linec[bp->bc_ymin].bl_prev = &bmd_linec[bp->bc_ymax-1]; 257 258 bq = bp->bc_bl = &bmd_linec[bp->bc_ymin]; 259 bq->bl_col = bq->bl_end = bp->bc_xmin; 260 261 bp->bc_col = bp->bc_xmin; 262 263 bp->bc_esc = &bp->bc_escseq[0]; 264 bp->bc_escape = bmd_escape; 265 266 bmd_erase_screen((u_long *) bp->bc_waddr); /* clear screen */ 267 268 /* turn on cursole */ 269 bmd_reverse_char(bp->bc_raddr, 270 bp->bc_waddr, 271 bq->bl_col, bp->bc_row); 272 } 273 274 bmdadjust(hcnt, vcnt) 275 short hcnt, vcnt; 276 { 277 volatile register struct bmd_rfcnt *bmd_rfcnt = (struct bmd_rfcnt *) 0xB1000000; 278 struct bmd_rfcnt rfcnt; 279 280 printf("bmdadjust: hcnt = %d, vcnt = %d\n", hcnt, vcnt); 281 282 rfcnt.rfc_hcnt = hcnt; /* shift left 16 dot */ 283 rfcnt.rfc_vcnt = vcnt; /* shift down 1 dot */ 284 285 *bmd_rfcnt = rfcnt; 286 } 287 288 bmdputc(c) 289 register int c; 290 { 291 register struct bmd_softc *bp = &bmd_softc; 292 register struct bmd_linec *bq = bp->bc_bl; 293 register int i; 294 295 c &= 0x7F; 296 /* turn off cursole */ 297 bmd_reverse_char(bp->bc_raddr, 298 bp->bc_waddr, 299 bq->bl_col, bp->bc_row); 300 /* do escape-sequence */ 301 if (bp->bc_stat & STAT_ESCAPE) { 302 *bp->bc_esc++ = c; 303 (*bp->bc_escape)(c); 304 goto done; 305 } 306 307 if (isprint(c)) { 308 bmd_draw_char(bp->bc_raddr, bp->bc_waddr, 309 bq->bl_col, bp->bc_row, c); 310 bq->bl_col++; 311 bq->bl_end++; 312 if (bq->bl_col >= bp->bc_xmax) { 313 bq->bl_col = bq->bl_end = bp->bc_xmin; 314 bp->bc_row++; 315 if (bp->bc_row >= bp->bc_ymax) { 316 bmd_scroll_screen((u_long *) bp->bc_raddr, 317 (u_long *) bp->bc_waddr, 318 bp->bc_xmin, bp->bc_xmax, 319 bp->bc_ymin, bp->bc_ymax); 320 321 bp->bc_row = bp->bc_ymax - 1; 322 } 323 } 324 } else { 325 switch (c) { 326 case 0x08: /* BS */ 327 if (bq->bl_col > bp->bc_xmin) { 328 bq->bl_col--; 329 } 330 break; 331 332 case 0x09: /* HT */ 333 case 0x0B: /* VT */ 334 i = ((bq->bl_col / 8) + 1) * 8; 335 if (i < bp->bc_xmax) { 336 bq->bl_col = bq->bl_end = i; 337 } 338 break; 339 340 case 0x0A: /* NL */ 341 bp->bc_row++; 342 if (bp->bc_row >= bp->bc_ymax) { 343 bmd_scroll_screen((u_long *) bp->bc_raddr, 344 (u_long *) bp->bc_waddr, 345 bp->bc_xmin, bp->bc_xmax, 346 bp->bc_ymin, bp->bc_ymax); 347 348 bp->bc_row = bp->bc_ymax - 1; 349 } 350 break; 351 352 case 0x0D: /* CR */ 353 bq->bl_col = bp->bc_xmin; 354 break; 355 356 case 0x1b: /* ESC */ 357 bp->bc_stat |= STAT_ESCAPE; 358 *bp->bc_esc++ = 0x1b; 359 break; 360 361 case 0x7F: /* DEL */ 362 if (bq->bl_col > bp->bc_xmin) { 363 bq->bl_col--; 364 bmd_erase_char(bp->bc_raddr, 365 bp->bc_waddr, 366 bq->bl_col, bp->bc_row); 367 } 368 break; 369 370 default: 371 break; 372 } 373 } 374 375 done: 376 /* turn on cursole */ 377 bmd_reverse_char(bp->bc_raddr, 378 bp->bc_waddr, 379 bq->bl_col, bp->bc_row); 380 381 return(c); 382 } 383 384 bmdclear() 385 { 386 register struct bmd_softc *bp = &bmd_softc; 387 register struct bmd_linec *bq = bp->bc_bl; 388 389 bmd_erase_screen((u_long *) bp->bc_waddr); /* clear screen */ 390 391 bq->bl_col = bq->bl_end = bp->bc_xmin; 392 bp->bc_row = bp->bc_ymin; 393 394 bmd_reverse_char(bp->bc_raddr, 395 bp->bc_waddr, 396 bq->bl_col, bp->bc_row); /* turn on cursole */ 397 } 398 399 400 /* 401 * 402 */ 403 404 void 405 bmd_add_new_line() 406 { 407 } 408 409 410 /* 411 * charactor operation routines 412 */ 413 414 void 415 bmd_draw_char(raddr, waddr, col, row, c) 416 char *raddr; 417 char *waddr; 418 int col; 419 int row; 420 int c; 421 { 422 volatile register u_short *p, *q, *fp; 423 volatile register u_long *lp, *lq; 424 register int i; 425 426 fp = &bmdfont[c][0]; 427 428 switch (col % 4) { 429 430 case 0: 431 p = (u_short *) ( raddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 )); 432 q = (u_short *) ( waddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 )); 433 for (i = 0; i < FB_HIGHT; i++) { 434 *q = (*p & 0x000F) | (*fp & 0xFFF0); 435 p += 128; 436 q += 128; 437 fp++; 438 } 439 break; 440 441 case 1: 442 lp = (u_long *) ( raddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 )); 443 lq = (u_long *) ( waddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 )); 444 for (i = 0; i < FB_HIGHT; i++) { 445 *lq = (*lp & 0xFFF000FF) | ((u_long)(*fp & 0xFFF0) << 4); 446 lp += 64; 447 lq += 64; 448 fp++; 449 } 450 break; 451 452 case 2: 453 lp = (u_long *) ( raddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 2 ); 454 lq = (u_long *) ( waddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 2 ); 455 for (i = 0; i < FB_HIGHT; i++) { 456 *lq = (*lp & 0xFF000FFF) | ((u_long)(*fp & 0xFFF0) << 8); 457 lp += 64; 458 lq += 64; 459 fp++; 460 } 461 break; 462 463 case 3: 464 p = (u_short *) ( raddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 4 ); 465 q = (u_short *) ( waddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 4 ); 466 for (i = 0; i < FB_HIGHT; i++) { 467 *q = (*p & 0xF000) | ((*fp & 0xFFF0) >> 4); 468 p += 128; 469 q += 128; 470 fp++; 471 } 472 break; 473 474 default: 475 break; 476 } 477 } 478 479 void 480 bmd_reverse_char(raddr, waddr, col, row) 481 char *raddr; 482 char *waddr; 483 int col; 484 int row; 485 { 486 volatile register u_short *p, *q, us; 487 volatile register u_long *lp, *lq, ul; 488 register int i; 489 490 switch (col%4) { 491 492 case 0: 493 p = (u_short *) ( raddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 )); 494 q = (u_short *) ( waddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 )); 495 for (i = 0; i < FB_HIGHT; i++) { 496 *q = (*p & 0x000F) | (~(*p) & 0xFFF0); 497 p += 128; 498 q += 128; 499 } 500 break; 501 502 case 1: 503 lp = (u_long *) ( raddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 )); 504 lq = (u_long *) ( waddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 )); 505 for (i = 0; i < FB_HIGHT; i++) { 506 *lq = (*lp & 0xFFF000FF) | (~(*lp) & 0x000FFF00); 507 lp += 64; 508 lq += 64; 509 } 510 break; 511 512 case 2: 513 lp = (u_long *) ( raddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 2 ); 514 lq = (u_long *) ( waddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 2 ); 515 for (i = 0; i < FB_HIGHT; i++) { 516 *lq = (*lp & 0xFF000FFF) | (~(*lp) & 0x00FFF000); 517 lp += 64; 518 lq += 64; 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) | (~(*p) & 0x0FFF); 527 p += 128; 528 q += 128; 529 } 530 break; 531 532 default: 533 break; 534 } 535 } 536 537 void 538 bmd_erase_char(raddr, waddr, col, row) 539 char *raddr; 540 char *waddr; 541 int col; 542 int row; 543 { 544 bmd_draw_char(raddr, waddr, col, row, 0); 545 546 return; 547 } 548 549 550 /* 551 * screen operation routines 552 */ 553 554 void 555 bmd_erase_screen(lp) 556 volatile register u_long *lp; 557 { 558 register int i, j; 559 560 for (i = 0; i < SB_HIGHT; i++) { 561 for (j = 0; j < SL_WIDTH; j++) 562 *lp++ = 0; 563 SKIP_NEXT_LINE(lp); 564 } 565 566 return; 567 } 568 569 void 570 bmd_scroll_screen(lp, lq, xmin, xmax, ymin, ymax) 571 volatile register u_long *lp; 572 volatile register u_long *lq; 573 int xmin, xmax, ymin, ymax; 574 { 575 register int i, j; 576 577 lp += ((PL_WIDTH * FB_HIGHT) * (ymin + 1)); 578 lq += ((PL_WIDTH * FB_HIGHT) * ymin); 579 580 for (i = 0; i < ((ymax - ymin -1) * FB_HIGHT); i++) { 581 for (j = 0; j < SL_WIDTH; j++) { 582 *lq++ = *lp++; 583 } 584 lp += (PL_WIDTH - SL_WIDTH); 585 lq += (PL_WIDTH - SL_WIDTH); 586 } 587 588 for (i = 0; i < FB_HIGHT; i++) { 589 for (j = 0; j < SL_WIDTH; j++) { 590 *lq++ = 0; 591 } 592 lq += (PL_WIDTH - SL_WIDTH); 593 } 594 595 } 596