bmd.c revision 1.1
1/*	$NetBSD: bmd.c,v 1.1 2013/01/05 17:44:24 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 <sys/systm.h>
82#include <luna68k/stand/boot/samachdep.h>
83
84#define isprint(c)	( c < 0x20 ? 0 : 1)
85
86/*
87 *  RFCNT register
88 */
89
90union bmd_rfcnt {
91	struct {
92		short	rfc_hcnt;
93		short	rfc_vcnt;
94	} p;
95	uint32_t u;
96};
97
98
99/*
100 *  Width & Hight
101 */
102
103#define	PB_WIDTH	2048				/* Plane Width   (Bit) */
104#define	PB_HIGHT	1024				/* Plane Hight   (Bit) */
105#define PL_WIDTH	64				/* Plane Width  (long) */
106#define PS_WIDTH	128				/* Plane Width  (long) */
107#define P_WIDTH		256				/* Plane Width  (Byte) */
108
109#define SB_WIDTH	1280				/* Screen Width  (Bit) */
110#define	SB_HIGHT	1024				/* Screen Hight  (Bit) */
111#define SL_WIDTH	40				/* Screen Width (Long) */
112#define S_WIDTH		160				/* Screen Width (Byte) */
113
114#define FB_WIDTH	12				/* Font Width    (Bit) */
115#define FB_HIGHT	20				/* Font Hight    (Bit) */
116
117
118#define NEXT_LINE(addr)				( addr +  (PL_WIDTH * FB_HIGHT) )
119#define SKIP_NEXT_LINE(addr)			( addr += (PL_WIDTH - SL_WIDTH) )
120
121
122void	bmd_add_new_line(void);
123
124void	bmd_draw_char(char *, char *, int, int, int);
125void	bmd_reverse_char(char *, char *, int, int);
126void	bmd_erase_char(char *, char *, int, int);
127void	bmd_erase_screen(volatile u_long *);
128void	bmd_scroll_screen(volatile u_long *, volatile u_long *,
129	    int, int, int, int);
130
131
132struct bmd_linec {
133	struct bmd_linec *bl_next;
134	struct bmd_linec *bl_prev;
135	int	bl_col;
136	int	bl_end;
137	u_char	bl_line[128];
138};
139
140struct bmd_softc {
141	int	bc_stat;
142	char   *bc_raddr;
143	char   *bc_waddr;
144	int	bc_xmin;
145	int	bc_xmax;
146	int	bc_ymin;
147	int	bc_ymax;
148	int	bc_col;
149	int	bc_row;
150	struct bmd_linec *bc_bl;
151	char	bc_escseq[8];
152	char   *bc_esc;
153	void  (*bc_escape)(int);
154};
155
156#define	STAT_NORMAL	0x0000
157#define	STAT_ESCAPE	0x0001
158#define	STAT_INSERT	0x0100
159
160struct	bmd_softc bmd_softc;
161struct	bmd_linec bmd_linec[52];
162
163void	bmd_escape(int);
164void	bmd_escape_0(int);
165void	bmd_escape_1(int);
166
167
168/*
169 * Escape-Sequence
170 */
171
172void
173bmd_escape(int c)
174{
175	struct bmd_softc *bp = &bmd_softc;
176
177	switch (c) {
178
179	case '[':
180		bp->bc_escape = bmd_escape_0;
181		break;
182
183	default:
184		bp->bc_stat &= ~STAT_ESCAPE;
185		bp->bc_esc = &bp->bc_escseq[0];
186		bp->bc_escape = bmd_escape;
187		break;
188	}
189}
190
191void
192bmd_escape_0(int c)
193{
194	struct bmd_softc *bp = &bmd_softc;
195	struct bmd_linec *bq = bp->bc_bl;
196
197	switch (c) {
198
199	case 'A':
200		if (bp->bc_row > bp->bc_ymin) {
201			bp->bc_row--;
202		}
203		break;
204
205	case 'C':
206		if (bq->bl_col < bp->bc_xmax - 1) {
207			bq->bl_col++;
208		}
209		break;
210
211	case 'K':
212		if (bq->bl_col < bp->bc_xmax) {
213			int col;
214			for (col = bq->bl_col; col < bp->bc_xmax; col++)
215				bmd_erase_char(bp->bc_raddr,
216					       bp->bc_waddr,
217					       col, bp->bc_row);
218		}
219		bq->bl_end = bq->bl_col;
220		break;
221
222	case 'H':
223		bq->bl_col = bq->bl_end = bp->bc_xmin;
224		bp->bc_row = bp->bc_ymin;
225		break;
226
227	default:
228/*
229		*bp->bc_esc++ = c;
230		bp->bc_escape = bmd_escape_1;
231		return;
232 */
233		break;
234	}
235
236	bp->bc_stat &= ~STAT_ESCAPE;
237	bp->bc_esc = &bp->bc_escseq[0];
238	bp->bc_escape = bmd_escape;
239}
240
241void
242bmd_escape_1(int c)
243{
244	struct bmd_softc *bp = &bmd_softc;
245	struct bmd_linec *bq = bp->bc_bl;
246	int col = 0, row = 0;
247	char *p;
248
249	switch (c) {
250
251	case 'J':
252		bp->bc_stat &= ~STAT_ESCAPE;
253		bp->bc_esc = &bp->bc_escseq[0];
254		bp->bc_escape = bmd_escape;
255		break;
256
257	case 'H':
258		for (p = &bp->bc_escseq[0]; *p != ';'; p++)
259			row = (row * 10) + (*p - 0x30);
260		p++;
261		for (p = &bp->bc_escseq[0]; p != bp->bc_esc; p++)
262			col = (col * 10) + (*p - 0x30);
263
264		bq->bl_col = col + bp->bc_xmin;
265		bp->bc_row = row + bp->bc_ymin;
266
267		bp->bc_stat &= ~STAT_ESCAPE;
268		bp->bc_esc = &bp->bc_escseq[0];
269		bp->bc_escape = bmd_escape;
270		break;
271
272	default:
273		*bp->bc_esc++ = c;
274		break;
275	}
276}
277
278
279/*
280 * Entry Routine
281 */
282
283void
284bmdinit(void)
285{
286	volatile uint32_t *bmd_rfcnt = (uint32_t *) 0xB1000000;
287	volatile long *bmd_bmsel = (long *)0xB1040000;
288	struct bmd_softc *bp = &bmd_softc;
289	struct bmd_linec *bq;
290	int i;
291	union bmd_rfcnt rfcnt;
292
293	/*
294	 *  adjust plane position
295	 */
296
297	bp->bc_raddr = (char *) 0xB10C0008;		/* plane-0 hardware address */
298	bp->bc_waddr = (char *) 0xB1080008;		/* common bitmap hardware address */
299	rfcnt.p.rfc_hcnt = 7;				/* shift left   16 dot */
300	rfcnt.p.rfc_vcnt = -27;				/* shift down    1 dot */
301	*bmd_rfcnt = rfcnt.u;
302
303	bp->bc_stat  = STAT_NORMAL;
304
305	bp->bc_xmin  = 8;
306	bp->bc_xmax  = 96;
307	bp->bc_ymin  = 2;
308	bp->bc_ymax  = 48;
309
310	bp->bc_row = bp->bc_ymin;
311
312	for (i = bp->bc_ymin; i < bp->bc_ymax; i++) {
313		bmd_linec[i].bl_next = &bmd_linec[i+1];
314		bmd_linec[i].bl_prev = &bmd_linec[i-1];
315	}
316	bmd_linec[bp->bc_ymax-1].bl_next = &bmd_linec[bp->bc_ymin];
317	bmd_linec[bp->bc_ymin].bl_prev = &bmd_linec[bp->bc_ymax-1];
318
319	bq = bp->bc_bl = &bmd_linec[bp->bc_ymin];
320	bq->bl_col = bq->bl_end = bp->bc_xmin;
321
322	bp->bc_col = bp->bc_xmin;
323
324	bp->bc_esc = &bp->bc_escseq[0];
325	bp->bc_escape = bmd_escape;
326
327	*bmd_bmsel = 0xff;				/* all planes */
328	bmd_erase_screen((u_long *) bp->bc_waddr);	/* clear screen */
329	*bmd_bmsel = 0x01;				/* 1 plane */
330
331							/* turn on  cursole */
332	bmd_reverse_char(bp->bc_raddr,
333			 bp->bc_waddr,
334			 bq->bl_col, bp->bc_row);
335}
336
337void
338bmdadjust(short hcnt, short vcnt)
339{
340	volatile uint32_t *bmd_rfcnt = (uint32_t *) 0xB1000000;
341	union bmd_rfcnt rfcnt;
342
343	printf("bmdadjust: hcnt = %d, vcnt = %d\n", hcnt, vcnt);
344
345	rfcnt.p.rfc_hcnt = hcnt;		/* shift left   16 dot */
346	rfcnt.p.rfc_vcnt = vcnt;		/* shift down    1 dot */
347
348	*bmd_rfcnt = rfcnt.u;
349}
350
351int
352bmdputc(int c)
353{
354	struct bmd_softc *bp = &bmd_softc;
355	struct bmd_linec *bq = bp->bc_bl;
356	int i;
357
358	c &= 0x7F;
359							/* turn off cursole */
360	bmd_reverse_char(bp->bc_raddr,
361			 bp->bc_waddr,
362			 bq->bl_col, bp->bc_row);
363							/* do escape-sequence */
364	if (bp->bc_stat & STAT_ESCAPE) {
365		*bp->bc_esc++ = c;
366		(*bp->bc_escape)(c);
367		goto done;
368	}
369
370	if (isprint(c)) {
371		bmd_draw_char(bp->bc_raddr, bp->bc_waddr,
372			      bq->bl_col, bp->bc_row, c);
373		bq->bl_col++;
374		bq->bl_end++;
375		if (bq->bl_col >= bp->bc_xmax) {
376			bq->bl_col = bq->bl_end = bp->bc_xmin;
377			bp->bc_row++;
378			if (bp->bc_row >= bp->bc_ymax) {
379				bmd_scroll_screen((u_long *) bp->bc_raddr,
380						  (u_long *) bp->bc_waddr,
381						  bp->bc_xmin, bp->bc_xmax,
382						  bp->bc_ymin, bp->bc_ymax);
383
384				bp->bc_row = bp->bc_ymax - 1;
385			}
386		}
387	} else {
388		switch (c) {
389		case 0x08:				/* BS */
390			if (bq->bl_col > bp->bc_xmin) {
391				bq->bl_col--;
392			}
393			break;
394
395		case 0x09:				/* HT */
396		case 0x0B:				/* VT */
397			i = ((bq->bl_col / 8) + 1) * 8;
398			if (i < bp->bc_xmax) {
399				bq->bl_col = bq->bl_end = i;
400			}
401			break;
402
403		case 0x0A:				/* NL */
404			bp->bc_row++;
405			if (bp->bc_row >= bp->bc_ymax) {
406				bmd_scroll_screen((u_long *) bp->bc_raddr,
407						  (u_long *) bp->bc_waddr,
408						  bp->bc_xmin, bp->bc_xmax,
409						  bp->bc_ymin, bp->bc_ymax);
410
411				bp->bc_row = bp->bc_ymax - 1;
412			}
413			break;
414
415		case 0x0D:				/* CR */
416			bq->bl_col = bp->bc_xmin;
417			break;
418
419		case 0x1b:				/* ESC */
420			bp->bc_stat |= STAT_ESCAPE;
421			*bp->bc_esc++ = 0x1b;
422			break;
423
424		case 0x7F:				/* DEL */
425			if (bq->bl_col > bp->bc_xmin) {
426				bq->bl_col--;
427				bmd_erase_char(bp->bc_raddr,
428					       bp->bc_waddr,
429					       bq->bl_col, bp->bc_row);
430			}
431			break;
432
433		default:
434			break;
435		}
436	}
437
438 done:
439							/* turn on  cursole */
440	bmd_reverse_char(bp->bc_raddr,
441			 bp->bc_waddr,
442			 bq->bl_col, bp->bc_row);
443
444	return(c);
445}
446
447void
448bmdclear(void)
449{
450	struct bmd_softc *bp = &bmd_softc;
451	struct bmd_linec *bq = bp->bc_bl;
452
453	bmd_erase_screen((u_long *) bp->bc_waddr);	/* clear screen */
454
455	bq->bl_col = bq->bl_end = bp->bc_xmin;
456	bp->bc_row = bp->bc_ymin;
457
458	bmd_reverse_char(bp->bc_raddr,
459			 bp->bc_waddr,
460			 bq->bl_col, bp->bc_row);	/* turn on  cursole */
461}
462
463
464/*
465 *
466 */
467
468void
469bmd_add_new_line(void)
470{
471}
472
473
474/*
475 *  charactor operation routines
476 */
477
478void
479bmd_draw_char(char *raddr, char *waddr, int col, int row, int c)
480{
481	volatile u_short  *p,  *q, *fp;
482	volatile u_long  *lp, *lq;
483	int i;
484
485	fp = &bmdfont[c][0];
486
487	switch (col % 4) {
488
489	case 0:
490		p = (u_short *) ( raddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 ));
491		q = (u_short *) ( waddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 ));
492		for (i = 0; i < FB_HIGHT; i++) {
493			*q = (*p & 0x000F) | (*fp & 0xFFF0);
494			p += 128;
495			q += 128;
496			fp++;
497		}
498		break;
499
500	case 1:
501		lp = (u_long *) ( raddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 ));
502		lq = (u_long *) ( waddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 ));
503		for (i = 0; i < FB_HIGHT; i++) {
504			*lq = (*lp & 0xFFF000FF) | ((u_long)(*fp & 0xFFF0) << 4);
505			lp += 64;
506			lq += 64;
507			fp++;
508		}
509		break;
510
511	case 2:
512		lp = (u_long *) ( raddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 2 );
513		lq = (u_long *) ( waddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 2 );
514		for (i = 0; i < FB_HIGHT; i++) {
515			*lq = (*lp & 0xFF000FFF) | ((u_long)(*fp & 0xFFF0) << 8);
516			lp += 64;
517			lq += 64;
518			fp++;
519		}
520		break;
521
522	case 3:
523		p = (u_short *) ( raddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 4 );
524		q = (u_short *) ( waddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 4 );
525		for (i = 0; i < FB_HIGHT; i++) {
526			*q = (*p & 0xF000) | ((*fp & 0xFFF0) >> 4);
527			p += 128;
528			q += 128;
529			fp++;
530		}
531		break;
532
533	default:
534		break;
535	}
536}
537
538void
539bmd_reverse_char(char *raddr, char *waddr, int col, int row)
540{
541	volatile u_short  *p,  *q;
542	volatile u_long  *lp, *lq;
543	int i;
544
545	switch (col%4) {
546
547	case 0:
548		p = (u_short *) ( raddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 ));
549		q = (u_short *) ( waddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 ));
550		for (i = 0; i < FB_HIGHT; i++) {
551			*q = (*p & 0x000F) | (~(*p) & 0xFFF0);
552			p += 128;
553			q += 128;
554		}
555		break;
556
557	case 1:
558		lp = (u_long *) ( raddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 ));
559		lq = (u_long *) ( waddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 ));
560		for (i = 0; i < FB_HIGHT; i++) {
561			*lq = (*lp & 0xFFF000FF) | (~(*lp) & 0x000FFF00);
562			lp += 64;
563			lq += 64;
564		}
565		break;
566
567	case 2:
568		lp = (u_long *) ( raddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 2 );
569		lq = (u_long *) ( waddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 2 );
570		for (i = 0; i < FB_HIGHT; i++) {
571			*lq = (*lp & 0xFF000FFF) | (~(*lp) & 0x00FFF000);
572			lp += 64;
573			lq += 64;
574		}
575		break;
576
577	case 3:
578		p = (u_short *) ( raddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 4 );
579		q = (u_short *) ( waddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 4 );
580		for (i = 0; i < FB_HIGHT; i++) {
581			*q = (*p & 0xF000) | (~(*p) & 0x0FFF);
582			p += 128;
583			q += 128;
584		}
585		break;
586
587	default:
588		break;
589	}
590}
591
592void
593bmd_erase_char(char *raddr, char *waddr, int col, int row)
594{
595	bmd_draw_char(raddr, waddr, col, row, 0);
596
597	return;
598}
599
600
601/*
602 * screen operation routines
603 */
604
605void
606bmd_erase_screen(volatile u_long *lp)
607{
608	int i, j;
609
610	for (i = 0; i < SB_HIGHT; i++) {
611		for (j = 0; j < SL_WIDTH; j++)
612			*lp++ = 0;
613		SKIP_NEXT_LINE(lp);
614	}
615
616	return;
617}
618
619void
620bmd_scroll_screen(volatile u_long *lp, volatile u_long *lq,
621    int xmin, int xmax, int ymin, int ymax)
622{
623	int i, j;
624
625	lp += ((PL_WIDTH * FB_HIGHT) * (ymin + 1));
626	lq += ((PL_WIDTH * FB_HIGHT) *  ymin);
627
628	for (i = 0; i < ((ymax - ymin -1) * FB_HIGHT); i++) {
629		for (j = 0; j < SL_WIDTH; j++) {
630			*lq++ = *lp++;
631		}
632		lp += (PL_WIDTH - SL_WIDTH);
633		lq += (PL_WIDTH - SL_WIDTH);
634	}
635
636	for (i = 0; i < FB_HIGHT; i++) {
637		for (j = 0; j < SL_WIDTH; j++) {
638			*lq++ = 0;
639		}
640		lq += (PL_WIDTH - SL_WIDTH);
641	}
642
643}
644