xref: /original-bsd/sys/luna68k/stand/bmd.c (revision 0fa75f0e)
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
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
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
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 
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 
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 
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 
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
408 bmd_add_new_line()
409 {
410 }
411 
412 
413 /*
414  *  charactor operation routines
415  */
416 
417 void
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
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
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
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
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