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.2 (Berkeley) 08/15/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 volatile register long *bmd_bmsel = (long *)0xB1040000; 228 register struct bmd_softc *bp = &bmd_softc; 229 register struct bmd_linec *bq; 230 register int i; 231 struct bmd_rfcnt rfcnt; 232 233 /* 234 * adjust plane position 235 */ 236 237 bp->bc_raddr = (char *) 0xB10C0008; /* plane-0 hardware address */ 238 bp->bc_waddr = (char *) 0xB1080008; /* common bitmap hardware address */ 239 rfcnt.rfc_hcnt = 7; /* shift left 16 dot */ 240 rfcnt.rfc_vcnt = -27; /* shift down 1 dot */ 241 *bmd_rfcnt = rfcnt; 242 243 bp->bc_stat = STAT_NORMAL; 244 245 bp->bc_xmin = 8; 246 bp->bc_xmax = 96; 247 bp->bc_ymin = 2; 248 bp->bc_ymax = 48; 249 250 bp->bc_row = bp->bc_ymin; 251 252 for (i = bp->bc_ymin; i < bp->bc_ymax; i++) { 253 bmd_linec[i].bl_next = &bmd_linec[i+1]; 254 bmd_linec[i].bl_prev = &bmd_linec[i-1]; 255 } 256 bmd_linec[bp->bc_ymax-1].bl_next = &bmd_linec[bp->bc_ymin]; 257 bmd_linec[bp->bc_ymin].bl_prev = &bmd_linec[bp->bc_ymax-1]; 258 259 bq = bp->bc_bl = &bmd_linec[bp->bc_ymin]; 260 bq->bl_col = bq->bl_end = bp->bc_xmin; 261 262 bp->bc_col = bp->bc_xmin; 263 264 bp->bc_esc = &bp->bc_escseq[0]; 265 bp->bc_escape = bmd_escape; 266 267 *bmd_bmsel = 0xff; /* all planes */ 268 bmd_erase_screen((u_long *) bp->bc_waddr); /* clear screen */ 269 *bmd_bmsel = 0x01; /* 1 plane */ 270 271 /* turn on cursole */ 272 bmd_reverse_char(bp->bc_raddr, 273 bp->bc_waddr, 274 bq->bl_col, bp->bc_row); 275 } 276 277 bmdadjust(hcnt, vcnt) 278 short hcnt, vcnt; 279 { 280 volatile register struct bmd_rfcnt *bmd_rfcnt = (struct bmd_rfcnt *) 0xB1000000; 281 struct bmd_rfcnt rfcnt; 282 283 printf("bmdadjust: hcnt = %d, vcnt = %d\n", hcnt, vcnt); 284 285 rfcnt.rfc_hcnt = hcnt; /* shift left 16 dot */ 286 rfcnt.rfc_vcnt = vcnt; /* shift down 1 dot */ 287 288 *bmd_rfcnt = rfcnt; 289 } 290 291 bmdputc(c) 292 register int c; 293 { 294 register struct bmd_softc *bp = &bmd_softc; 295 register struct bmd_linec *bq = bp->bc_bl; 296 register int i; 297 298 c &= 0x7F; 299 /* turn off cursole */ 300 bmd_reverse_char(bp->bc_raddr, 301 bp->bc_waddr, 302 bq->bl_col, bp->bc_row); 303 /* do escape-sequence */ 304 if (bp->bc_stat & STAT_ESCAPE) { 305 *bp->bc_esc++ = c; 306 (*bp->bc_escape)(c); 307 goto done; 308 } 309 310 if (isprint(c)) { 311 bmd_draw_char(bp->bc_raddr, bp->bc_waddr, 312 bq->bl_col, bp->bc_row, c); 313 bq->bl_col++; 314 bq->bl_end++; 315 if (bq->bl_col >= bp->bc_xmax) { 316 bq->bl_col = bq->bl_end = bp->bc_xmin; 317 bp->bc_row++; 318 if (bp->bc_row >= bp->bc_ymax) { 319 bmd_scroll_screen((u_long *) bp->bc_raddr, 320 (u_long *) bp->bc_waddr, 321 bp->bc_xmin, bp->bc_xmax, 322 bp->bc_ymin, bp->bc_ymax); 323 324 bp->bc_row = bp->bc_ymax - 1; 325 } 326 } 327 } else { 328 switch (c) { 329 case 0x08: /* BS */ 330 if (bq->bl_col > bp->bc_xmin) { 331 bq->bl_col--; 332 } 333 break; 334 335 case 0x09: /* HT */ 336 case 0x0B: /* VT */ 337 i = ((bq->bl_col / 8) + 1) * 8; 338 if (i < bp->bc_xmax) { 339 bq->bl_col = bq->bl_end = i; 340 } 341 break; 342 343 case 0x0A: /* NL */ 344 bp->bc_row++; 345 if (bp->bc_row >= bp->bc_ymax) { 346 bmd_scroll_screen((u_long *) bp->bc_raddr, 347 (u_long *) bp->bc_waddr, 348 bp->bc_xmin, bp->bc_xmax, 349 bp->bc_ymin, bp->bc_ymax); 350 351 bp->bc_row = bp->bc_ymax - 1; 352 } 353 break; 354 355 case 0x0D: /* CR */ 356 bq->bl_col = bp->bc_xmin; 357 break; 358 359 case 0x1b: /* ESC */ 360 bp->bc_stat |= STAT_ESCAPE; 361 *bp->bc_esc++ = 0x1b; 362 break; 363 364 case 0x7F: /* DEL */ 365 if (bq->bl_col > bp->bc_xmin) { 366 bq->bl_col--; 367 bmd_erase_char(bp->bc_raddr, 368 bp->bc_waddr, 369 bq->bl_col, bp->bc_row); 370 } 371 break; 372 373 default: 374 break; 375 } 376 } 377 378 done: 379 /* turn on cursole */ 380 bmd_reverse_char(bp->bc_raddr, 381 bp->bc_waddr, 382 bq->bl_col, bp->bc_row); 383 384 return(c); 385 } 386 387 bmdclear() 388 { 389 register struct bmd_softc *bp = &bmd_softc; 390 register struct bmd_linec *bq = bp->bc_bl; 391 392 bmd_erase_screen((u_long *) bp->bc_waddr); /* clear screen */ 393 394 bq->bl_col = bq->bl_end = bp->bc_xmin; 395 bp->bc_row = bp->bc_ymin; 396 397 bmd_reverse_char(bp->bc_raddr, 398 bp->bc_waddr, 399 bq->bl_col, bp->bc_row); /* turn on cursole */ 400 } 401 402 403 /* 404 * 405 */ 406 407 void 408 bmd_add_new_line() 409 { 410 } 411 412 413 /* 414 * charactor operation routines 415 */ 416 417 void 418 bmd_draw_char(raddr, waddr, col, row, c) 419 char *raddr; 420 char *waddr; 421 int col; 422 int row; 423 int c; 424 { 425 volatile register u_short *p, *q, *fp; 426 volatile register u_long *lp, *lq; 427 register int i; 428 429 fp = &bmdfont[c][0]; 430 431 switch (col % 4) { 432 433 case 0: 434 p = (u_short *) ( raddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 )); 435 q = (u_short *) ( waddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 )); 436 for (i = 0; i < FB_HIGHT; i++) { 437 *q = (*p & 0x000F) | (*fp & 0xFFF0); 438 p += 128; 439 q += 128; 440 fp++; 441 } 442 break; 443 444 case 1: 445 lp = (u_long *) ( raddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 )); 446 lq = (u_long *) ( waddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 )); 447 for (i = 0; i < FB_HIGHT; i++) { 448 *lq = (*lp & 0xFFF000FF) | ((u_long)(*fp & 0xFFF0) << 4); 449 lp += 64; 450 lq += 64; 451 fp++; 452 } 453 break; 454 455 case 2: 456 lp = (u_long *) ( raddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 2 ); 457 lq = (u_long *) ( waddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 2 ); 458 for (i = 0; i < FB_HIGHT; i++) { 459 *lq = (*lp & 0xFF000FFF) | ((u_long)(*fp & 0xFFF0) << 8); 460 lp += 64; 461 lq += 64; 462 fp++; 463 } 464 break; 465 466 case 3: 467 p = (u_short *) ( raddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 4 ); 468 q = (u_short *) ( waddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 4 ); 469 for (i = 0; i < FB_HIGHT; i++) { 470 *q = (*p & 0xF000) | ((*fp & 0xFFF0) >> 4); 471 p += 128; 472 q += 128; 473 fp++; 474 } 475 break; 476 477 default: 478 break; 479 } 480 } 481 482 void 483 bmd_reverse_char(raddr, waddr, col, row) 484 char *raddr; 485 char *waddr; 486 int col; 487 int row; 488 { 489 volatile register u_short *p, *q, us; 490 volatile register u_long *lp, *lq, ul; 491 register int i; 492 493 switch (col%4) { 494 495 case 0: 496 p = (u_short *) ( raddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 )); 497 q = (u_short *) ( waddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 )); 498 for (i = 0; i < FB_HIGHT; i++) { 499 *q = (*p & 0x000F) | (~(*p) & 0xFFF0); 500 p += 128; 501 q += 128; 502 } 503 break; 504 505 case 1: 506 lp = (u_long *) ( raddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 )); 507 lq = (u_long *) ( waddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 )); 508 for (i = 0; i < FB_HIGHT; i++) { 509 *lq = (*lp & 0xFFF000FF) | (~(*lp) & 0x000FFF00); 510 lp += 64; 511 lq += 64; 512 } 513 break; 514 515 case 2: 516 lp = (u_long *) ( raddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 2 ); 517 lq = (u_long *) ( waddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 2 ); 518 for (i = 0; i < FB_HIGHT; i++) { 519 *lq = (*lp & 0xFF000FFF) | (~(*lp) & 0x00FFF000); 520 lp += 64; 521 lq += 64; 522 } 523 break; 524 525 case 3: 526 p = (u_short *) ( raddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 4 ); 527 q = (u_short *) ( waddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 4 ); 528 for (i = 0; i < FB_HIGHT; i++) { 529 *q = (*p & 0xF000) | (~(*p) & 0x0FFF); 530 p += 128; 531 q += 128; 532 } 533 break; 534 535 default: 536 break; 537 } 538 } 539 540 void 541 bmd_erase_char(raddr, waddr, col, row) 542 char *raddr; 543 char *waddr; 544 int col; 545 int row; 546 { 547 bmd_draw_char(raddr, waddr, col, row, 0); 548 549 return; 550 } 551 552 553 /* 554 * screen operation routines 555 */ 556 557 void 558 bmd_erase_screen(lp) 559 volatile register u_long *lp; 560 { 561 register int i, j; 562 563 for (i = 0; i < SB_HIGHT; i++) { 564 for (j = 0; j < SL_WIDTH; j++) 565 *lp++ = 0; 566 SKIP_NEXT_LINE(lp); 567 } 568 569 return; 570 } 571 572 void 573 bmd_scroll_screen(lp, lq, xmin, xmax, ymin, ymax) 574 volatile register u_long *lp; 575 volatile register u_long *lq; 576 int xmin, xmax, ymin, ymax; 577 { 578 register int i, j; 579 580 lp += ((PL_WIDTH * FB_HIGHT) * (ymin + 1)); 581 lq += ((PL_WIDTH * FB_HIGHT) * ymin); 582 583 for (i = 0; i < ((ymax - ymin -1) * FB_HIGHT); i++) { 584 for (j = 0; j < SL_WIDTH; j++) { 585 *lq++ = *lp++; 586 } 587 lp += (PL_WIDTH - SL_WIDTH); 588 lq += (PL_WIDTH - SL_WIDTH); 589 } 590 591 for (i = 0; i < FB_HIGHT; i++) { 592 for (j = 0; j < SL_WIDTH; j++) { 593 *lq++ = 0; 594 } 595 lq += (PL_WIDTH - SL_WIDTH); 596 } 597 598 } 599