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