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