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
bmd_escape(c)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
bmd_escape_0(c)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
bmd_escape_1(c)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
bmdinit()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
bmdadjust(hcnt,vcnt)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
bmdputc(c)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
bmdclear()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
bmd_add_new_line()408 bmd_add_new_line()
409 {
410 }
411
412
413 /*
414 * charactor operation routines
415 */
416
417 void
bmd_draw_char(raddr,waddr,col,row,c)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
bmd_reverse_char(raddr,waddr,col,row)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
bmd_erase_char(raddr,waddr,col,row)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
bmd_erase_screen(lp)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
bmd_scroll_screen(lp,lq,xmin,xmax,ymin,ymax)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