bmd.c revision 1.6 1 /* $NetBSD: bmd.c,v 1.6 2015/02/14 05:58:02 tsutsui Exp $ */
2
3 /*
4 * Copyright (c) 1992 OMRON Corporation.
5 *
6 * This code is derived from software contributed to Berkeley by
7 * OMRON Corporation.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by the University of
20 * California, Berkeley and its contributors.
21 * 4. Neither the name of the University nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 *
37 * @(#)bmd.c 8.2 (Berkeley) 8/15/93
38 */
39 /*
40 * Copyright (c) 1992, 1993
41 * The Regents of the University of California. All rights reserved.
42 *
43 * This code is derived from software contributed to Berkeley by
44 * OMRON Corporation.
45 *
46 * Redistribution and use in source and binary forms, with or without
47 * modification, are permitted provided that the following conditions
48 * are met:
49 * 1. Redistributions of source code must retain the above copyright
50 * notice, this list of conditions and the following disclaimer.
51 * 2. Redistributions in binary form must reproduce the above copyright
52 * notice, this list of conditions and the following disclaimer in the
53 * documentation and/or other materials provided with the distribution.
54 * 3. Neither the name of the University nor the names of its contributors
55 * may be used to endorse or promote products derived from this software
56 * without specific prior written permission.
57 *
58 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
59 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
60 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
61 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
62 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
63 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
64 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
65 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
66 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
67 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
68 * SUCH DAMAGE.
69 *
70 * @(#)bmd.c 8.2 (Berkeley) 8/15/93
71 */
72 /*
73
74 * bmd.c --- Bitmap-Display raw-level driver routines
75 *
76 * by A.Fujita, SEP-09-1992
77 */
78
79
80 #include <sys/param.h>
81 #include <luna68k/stand/boot/samachdep.h>
82
83 /*
84 * RFCNT register
85 */
86
87 union bmd_rfcnt {
88 struct {
89 int16_t rfc_hcnt;
90 int16_t rfc_vcnt;
91 } p;
92 uint32_t u;
93 };
94
95 #define isprint(c) ((c) >= 0x20 && (c) < 0x7f)
96
97 /*
98 * Width & Height
99 */
100
101 #define PB_WIDTH 2048 /* Plane Width (Bit) */
102 #define PB_HEIGHT 1024 /* Plane Hight (Bit) */
103 #define PL_WIDTH 64 /* Plane Width (long) */
104 #define PS_WIDTH 128 /* Plane Width (long) */
105 #define P_WIDTH 256 /* Plane Width (Byte) */
106
107 #define SB_WIDTH 1280 /* Screen Width (Bit) */
108 #define SB_HEIGHT 1024 /* Screen Hight (Bit) */
109 #define SL_WIDTH 40 /* Screen Width (Long) */
110 #define S_WIDTH 160 /* Screen Width (Byte) */
111
112 #define FB_WIDTH 12 /* Font Width (Bit) */
113 #define FB_HEIGHT 20 /* Font Hight (Bit) */
114
115
116 #define NEXT_LINE(addr) (addr + (PL_WIDTH * FB_HEIGHT))
117 #define SKIP_NEXT_LINE(addr) (addr += (PL_WIDTH - SL_WIDTH))
118
119
120 void bmd_draw_char(uint8_t *, uint8_t *, int, int, int);
121 void bmd_reverse_char(uint8_t *, uint8_t *, int, int);
122 void bmd_erase_char(uint8_t *, uint8_t *, int, int);
123 void bmd_erase_screen(volatile uint32_t *);
124 void bmd_scroll_screen(volatile uint32_t *, volatile uint32_t *,
125 int, int, int, int);
126
127
128 struct bmd_linec {
129 struct bmd_linec *bl_next;
130 struct bmd_linec *bl_prev;
131 int bl_col;
132 int bl_end;
133 uint8_t bl_line[128];
134 };
135
136 struct bmd_softc {
137 int bc_stat;
138 uint8_t *bc_raddr;
139 uint8_t *bc_waddr;
140 int bc_xmin;
141 int bc_xmax;
142 int bc_ymin;
143 int bc_ymax;
144 int bc_col;
145 int bc_row;
146 struct bmd_linec *bc_bl;
147 char bc_escseq[8];
148 char *bc_esc;
149 void (*bc_escape)(int);
150 };
151
152 #define STAT_NORMAL 0x0000
153 #define STAT_ESCAPE 0x0001
154 #define STAT_INSERT 0x0100
155
156 struct bmd_softc bmd_softc;
157 struct bmd_linec bmd_linec[52];
158
159 void bmd_escape(int);
160 void bmd_escape_0(int);
161 void bmd_escape_1(int);
162
163
164 /*
165 * Escape-Sequence
166 */
167
168 void
169 bmd_escape(int c)
170 {
171 struct bmd_softc *bp = &bmd_softc;
172
173 switch (c) {
174
175 case '[':
176 bp->bc_escape = bmd_escape_0;
177 break;
178
179 default:
180 bp->bc_stat &= ~STAT_ESCAPE;
181 bp->bc_esc = &bp->bc_escseq[0];
182 bp->bc_escape = bmd_escape;
183 break;
184 }
185 }
186
187 void
188 bmd_escape_0(int c)
189 {
190 struct bmd_softc *bp = &bmd_softc;
191 struct bmd_linec *bq = bp->bc_bl;
192
193 switch (c) {
194
195 case 'A':
196 if (bp->bc_row > bp->bc_ymin) {
197 bp->bc_row--;
198 }
199 break;
200
201 case 'C':
202 if (bq->bl_col < bp->bc_xmax - 1) {
203 bq->bl_col++;
204 }
205 break;
206
207 case 'K':
208 if (bq->bl_col < bp->bc_xmax) {
209 int col;
210 for (col = bq->bl_col; col < bp->bc_xmax; col++)
211 bmd_erase_char(bp->bc_raddr,
212 bp->bc_waddr,
213 col, bp->bc_row);
214 }
215 bq->bl_end = bq->bl_col;
216 break;
217
218 case 'H':
219 bq->bl_col = bq->bl_end = bp->bc_xmin;
220 bp->bc_row = bp->bc_ymin;
221 break;
222
223 default:
224 #if 0
225 *bp->bc_esc++ = c;
226 bp->bc_escape = bmd_escape_1;
227 return;
228 #endif
229 break;
230 }
231
232 bp->bc_stat &= ~STAT_ESCAPE;
233 bp->bc_esc = &bp->bc_escseq[0];
234 bp->bc_escape = bmd_escape;
235 }
236
237 void
238 bmd_escape_1(int c)
239 {
240 struct bmd_softc *bp = &bmd_softc;
241 struct bmd_linec *bq = bp->bc_bl;
242 int col = 0, row = 0;
243 char *p;
244
245 switch (c) {
246
247 case 'J':
248 bp->bc_stat &= ~STAT_ESCAPE;
249 bp->bc_esc = &bp->bc_escseq[0];
250 bp->bc_escape = bmd_escape;
251 break;
252
253 case 'H':
254 for (p = &bp->bc_escseq[0]; *p != ';'; p++)
255 row = (row * 10) + (*p - 0x30);
256 p++;
257 for (p = &bp->bc_escseq[0]; p != bp->bc_esc; p++)
258 col = (col * 10) + (*p - 0x30);
259
260 bq->bl_col = col + bp->bc_xmin;
261 bp->bc_row = row + bp->bc_ymin;
262
263 bp->bc_stat &= ~STAT_ESCAPE;
264 bp->bc_esc = &bp->bc_escseq[0];
265 bp->bc_escape = bmd_escape;
266 break;
267
268 default:
269 *bp->bc_esc++ = c;
270 break;
271 }
272 }
273
274
275 /*
276 * Entry Routine
277 */
278
279 void
280 bmdinit(void)
281 {
282 volatile uint32_t *bmd_rfcnt = (uint32_t *)0xB1000000;
283 volatile uint32_t *bmd_bmsel = (uint32_t *)0xB1040000;
284 struct bmd_softc *bp = &bmd_softc;
285 struct bmd_linec *bq;
286 int i;
287 union bmd_rfcnt rfcnt;
288
289 /*
290 * adjust plane position
291 */
292
293 /* plane-0 hardware address */
294 bp->bc_raddr = (uint8_t *)0xB10C0008;
295 /* common bitmap hardware address */
296 bp->bc_waddr = (uint8_t *)0xB1080008;
297
298 rfcnt.p.rfc_hcnt = 7; /* shift left 16 dot */
299 rfcnt.p.rfc_vcnt = -27; /* shift down 1 dot */
300 *bmd_rfcnt = rfcnt.u;
301
302 bp->bc_stat = STAT_NORMAL;
303
304 bp->bc_xmin = 8;
305 bp->bc_xmax = 96;
306 bp->bc_ymin = 2;
307 bp->bc_ymax = 48;
308
309 bp->bc_row = bp->bc_ymin;
310
311 for (i = bp->bc_ymin; i < bp->bc_ymax; i++) {
312 bmd_linec[i].bl_next = &bmd_linec[i + 1];
313 bmd_linec[i].bl_prev = &bmd_linec[i - 1];
314 }
315 bmd_linec[bp->bc_ymax - 1].bl_next = &bmd_linec[bp->bc_ymin];
316 bmd_linec[bp->bc_ymin].bl_prev = &bmd_linec[bp->bc_ymax - 1];
317
318 bq = bp->bc_bl = &bmd_linec[bp->bc_ymin];
319 bq->bl_col = bq->bl_end = bp->bc_xmin;
320
321 bp->bc_col = bp->bc_xmin;
322
323 bp->bc_esc = &bp->bc_escseq[0];
324 bp->bc_escape = bmd_escape;
325
326 *bmd_bmsel = 0xff; /* all planes */
327 bmd_erase_screen((uint32_t *)bp->bc_waddr); /* clear screen */
328 *bmd_bmsel = 0x01; /* 1 plane */
329
330 /* turn on cursor */
331 bmd_reverse_char(bp->bc_raddr,
332 bp->bc_waddr,
333 bq->bl_col, bp->bc_row);
334 }
335
336 void
337 bmdadjust(int16_t hcnt, int16_t vcnt)
338 {
339 volatile uint32_t *bmd_rfcnt = (uint32_t *)0xB1000000;
340 union bmd_rfcnt rfcnt;
341
342 printf("bmdadjust: hcnt = %d, vcnt = %d\n", hcnt, vcnt);
343
344 rfcnt.p.rfc_hcnt = hcnt; /* shift left 16 dot */
345 rfcnt.p.rfc_vcnt = vcnt; /* shift down 1 dot */
346
347 *bmd_rfcnt = rfcnt.u;
348 }
349
350 int
351 bmdputc(int c)
352 {
353 struct bmd_softc *bp = &bmd_softc;
354 struct bmd_linec *bq = bp->bc_bl;
355 int i;
356
357 c &= 0x7F;
358
359 /* turn off cursor */
360 bmd_reverse_char(bp->bc_raddr,
361 bp->bc_waddr,
362 bq->bl_col, bp->bc_row);
363
364 /* do escape-sequence */
365 if (bp->bc_stat & STAT_ESCAPE) {
366 *bp->bc_esc++ = c;
367 (*bp->bc_escape)(c);
368 goto done;
369 }
370
371 if (isprint(c)) {
372 bmd_draw_char(bp->bc_raddr, bp->bc_waddr,
373 bq->bl_col, bp->bc_row, c);
374 bq->bl_col++;
375 bq->bl_end++;
376 if (bq->bl_col >= bp->bc_xmax) {
377 bq->bl_col = bq->bl_end = bp->bc_xmin;
378 bp->bc_row++;
379 if (bp->bc_row >= bp->bc_ymax) {
380 bmd_scroll_screen((uint32_t *)bp->bc_raddr,
381 (uint32_t *)bp->bc_waddr,
382 bp->bc_xmin, bp->bc_xmax,
383 bp->bc_ymin, bp->bc_ymax);
384
385 bp->bc_row = bp->bc_ymax - 1;
386 }
387 }
388 } else {
389 switch (c) {
390 case 0x08: /* BS */
391 if (bq->bl_col > bp->bc_xmin) {
392 bq->bl_col--;
393 }
394 break;
395
396 case 0x09: /* HT */
397 case 0x0B: /* VT */
398 i = ((bq->bl_col / 8) + 1) * 8;
399 if (i < bp->bc_xmax) {
400 bq->bl_col = bq->bl_end = i;
401 }
402 break;
403
404 case 0x0A: /* NL */
405 bp->bc_row++;
406 if (bp->bc_row >= bp->bc_ymax) {
407 bmd_scroll_screen((uint32_t *)bp->bc_raddr,
408 (uint32_t *)bp->bc_waddr,
409 bp->bc_xmin, bp->bc_xmax,
410 bp->bc_ymin, bp->bc_ymax);
411
412 bp->bc_row = bp->bc_ymax - 1;
413 }
414 break;
415
416 case 0x0D: /* CR */
417 bq->bl_col = bp->bc_xmin;
418 break;
419
420 case 0x1B: /* ESC */
421 bp->bc_stat |= STAT_ESCAPE;
422 *bp->bc_esc++ = 0x1b;
423 break;
424
425 case 0x7F: /* DEL */
426 if (bq->bl_col > bp->bc_xmin) {
427 bq->bl_col--;
428 bmd_erase_char(bp->bc_raddr,
429 bp->bc_waddr,
430 bq->bl_col, bp->bc_row);
431 }
432 break;
433
434 default:
435 break;
436 }
437 }
438
439 done:
440 /* turn on cursor */
441 bmd_reverse_char(bp->bc_raddr,
442 bp->bc_waddr,
443 bq->bl_col, bp->bc_row);
444
445 return c;
446 }
447
448 void
449 bmdclear(void)
450 {
451 struct bmd_softc *bp = &bmd_softc;
452 struct bmd_linec *bq = bp->bc_bl;
453
454 /* clear screen */
455 bmd_erase_screen((uint32_t *)bp->bc_waddr);
456
457 bq->bl_col = bq->bl_end = bp->bc_xmin;
458 bp->bc_row = bp->bc_ymin;
459
460 /* turn on cursor */
461 bmd_reverse_char(bp->bc_raddr,
462 bp->bc_waddr,
463 bq->bl_col, bp->bc_row);
464 }
465
466
467 /*
468 * charactor operation routines
469 */
470
471 void
472 bmd_draw_char(uint8_t *raddr, uint8_t *waddr, int col, int row, int c)
473 {
474 volatile uint16_t *p, *q;
475 volatile uint32_t *lp, *lq;
476 const uint16_t *fp;
477 int i;
478
479 fp = &bmdfont[c][0];
480
481 switch (col % 4) {
482
483 case 0:
484 p = (uint16_t *)(raddr + ((row * FB_HEIGHT) << 8)
485 + ((col / 4) * 6));
486 q = (uint16_t *)(waddr + ((row * FB_HEIGHT) << 8)
487 + ((col / 4) * 6));
488 for (i = 0; i < FB_HEIGHT; i++) {
489 *q = (*p & 0x000F) | (*fp & 0xFFF0);
490 p += 128;
491 q += 128;
492 fp++;
493 }
494 break;
495
496 case 1:
497 lp = (uint32_t *)(raddr + ((row * FB_HEIGHT) << 8)
498 + ((col / 4) * 6));
499 lq = (uint32_t *)(waddr + ((row * FB_HEIGHT) << 8)
500 + ((col / 4) * 6));
501 for (i = 0; i < FB_HEIGHT; i++) {
502 *lq = (*lp & 0xFFF000FF) |
503 ((uint32_t)(*fp & 0xFFF0) << 4);
504 lp += 64;
505 lq += 64;
506 fp++;
507 }
508 break;
509
510 case 2:
511 lp = (uint32_t *)(raddr + ((row * FB_HEIGHT) << 8)
512 + ((col / 4) * 6) + 2);
513 lq = (uint32_t *)(waddr + ((row * FB_HEIGHT) << 8)
514 + ((col / 4) * 6) + 2);
515 for (i = 0; i < FB_HEIGHT; i++) {
516 *lq = (*lp & 0xFF000FFF) |
517 ((uint32_t)(*fp & 0xFFF0) << 8);
518 lp += 64;
519 lq += 64;
520 fp++;
521 }
522 break;
523
524 case 3:
525 p = (uint16_t *)(raddr + ((row * FB_HEIGHT) << 8)
526 + ((col / 4) * 6) + 4);
527 q = (uint16_t *)(waddr + ((row * FB_HEIGHT) << 8)
528 + ((col / 4) * 6) + 4);
529 for (i = 0; i < FB_HEIGHT; i++) {
530 *q = (*p & 0xF000) | ((*fp & 0xFFF0) >> 4);
531 p += 128;
532 q += 128;
533 fp++;
534 }
535 break;
536
537 default:
538 break;
539 }
540 }
541
542 void
543 bmd_reverse_char(uint8_t *raddr, uint8_t *waddr, int col, int row)
544 {
545 volatile uint16_t *p, *q;
546 volatile uint32_t *lp, *lq;
547 int i;
548
549 switch (col % 4) {
550
551 case 0:
552 p = (uint16_t *)(raddr + ((row * FB_HEIGHT) << 8)
553 + ((col / 4) * 6));
554 q = (uint16_t *)(waddr + ((row * FB_HEIGHT) << 8)
555 + ((col / 4) * 6));
556 for (i = 0; i < FB_HEIGHT; i++) {
557 *q = (*p & 0x000F) | (~(*p) & 0xFFF0);
558 p += 128;
559 q += 128;
560 }
561 break;
562
563 case 1:
564 lp = (uint32_t *)(raddr + ((row * FB_HEIGHT) << 8)
565 + ((col / 4) * 6));
566 lq = (uint32_t *)(waddr + ((row * FB_HEIGHT) << 8)
567 + ((col / 4) * 6));
568 for (i = 0; i < FB_HEIGHT; i++) {
569 *lq = (*lp & 0xFFF000FF) | (~(*lp) & 0x000FFF00);
570 lp += 64;
571 lq += 64;
572 }
573 break;
574
575 case 2:
576 lp = (uint32_t *)(raddr + ((row * FB_HEIGHT) << 8)
577 + ((col / 4) * 6) + 2);
578 lq = (uint32_t *)(waddr + ((row * FB_HEIGHT) << 8)
579 + ((col / 4) * 6) + 2);
580 for (i = 0; i < FB_HEIGHT; i++) {
581 *lq = (*lp & 0xFF000FFF) | (~(*lp) & 0x00FFF000);
582 lp += 64;
583 lq += 64;
584 }
585 break;
586
587 case 3:
588 p = (uint16_t *)(raddr + ((row * FB_HEIGHT) << 8)
589 + ((col / 4) * 6) + 4);
590 q = (uint16_t *)(waddr + ((row * FB_HEIGHT) << 8)
591 + ((col / 4) * 6) + 4);
592 for (i = 0; i < FB_HEIGHT; i++) {
593 *q = (*p & 0xF000) | (~(*p) & 0x0FFF);
594 p += 128;
595 q += 128;
596 }
597 break;
598
599 default:
600 break;
601 }
602 }
603
604 void
605 bmd_erase_char(uint8_t *raddr, uint8_t *waddr, int col, int row)
606 {
607
608 bmd_draw_char(raddr, waddr, col, row, 0);
609 }
610
611
612 /*
613 * screen operation routines
614 */
615
616 void
617 bmd_erase_screen(volatile uint32_t *lp)
618 {
619 int i, j;
620
621 for (i = 0; i < SB_HEIGHT; i++) {
622 for (j = 0; j < SL_WIDTH; j++)
623 *lp++ = 0;
624 SKIP_NEXT_LINE(lp);
625 }
626 }
627
628 void
629 bmd_scroll_screen(volatile uint32_t *lp, volatile uint32_t *lq,
630 int xmin, int xmax, int ymin, int ymax)
631 {
632 int i, j;
633
634 lp += ((PL_WIDTH * FB_HEIGHT) * (ymin + 1));
635 lq += ((PL_WIDTH * FB_HEIGHT) * ymin);
636
637 for (i = 0; i < ((ymax - ymin -1) * FB_HEIGHT); i++) {
638 for (j = 0; j < SL_WIDTH; j++) {
639 *lq++ = *lp++;
640 }
641 lp += (PL_WIDTH - SL_WIDTH);
642 lq += (PL_WIDTH - SL_WIDTH);
643 }
644
645 for (i = 0; i < FB_HEIGHT; i++) {
646 for (j = 0; j < SL_WIDTH; j++) {
647 *lq++ = 0;
648 }
649 lq += (PL_WIDTH - SL_WIDTH);
650 }
651 }
652