xref: /original-bsd/sys/luna68k/stand/bmd.c (revision 3705696b)
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.1 (Berkeley) 06/10/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 	register struct bmd_softc *bp = &bmd_softc;
228 	register struct bmd_linec *bq;
229 	register int i;
230 	struct bmd_rfcnt rfcnt;
231 
232 	/*
233 	 *  adjust plane position
234 	 */
235 
236 	bp->bc_raddr = (char *) 0xB10C0008;		/* plane-0 hardware address */
237 	bp->bc_waddr = (char *) 0xB1080008;		/* common bitmap hardware address */
238 	rfcnt.rfc_hcnt = 7;				/* shift left   16 dot */
239 	rfcnt.rfc_vcnt = -27;				/* shift down    1 dot */
240 	*bmd_rfcnt = rfcnt;
241 
242 	bp->bc_stat  = STAT_NORMAL;
243 
244 	bp->bc_xmin  = 8;
245 	bp->bc_xmax  = 96;
246 	bp->bc_ymin  = 2;
247 	bp->bc_ymax  = 48;
248 
249 	bp->bc_row = bp->bc_ymin;
250 
251 	for (i = bp->bc_ymin; i < bp->bc_ymax; i++) {
252 		bmd_linec[i].bl_next = &bmd_linec[i+1];
253 		bmd_linec[i].bl_prev = &bmd_linec[i-1];
254 	}
255 	bmd_linec[bp->bc_ymax-1].bl_next = &bmd_linec[bp->bc_ymin];
256 	bmd_linec[bp->bc_ymin].bl_prev = &bmd_linec[bp->bc_ymax-1];
257 
258 	bq = bp->bc_bl = &bmd_linec[bp->bc_ymin];
259 	bq->bl_col = bq->bl_end = bp->bc_xmin;
260 
261 	bp->bc_col = bp->bc_xmin;
262 
263 	bp->bc_esc = &bp->bc_escseq[0];
264 	bp->bc_escape = bmd_escape;
265 
266 	bmd_erase_screen((u_long *) bp->bc_waddr);	/* clear screen */
267 
268 							/* turn on  cursole */
269 	bmd_reverse_char(bp->bc_raddr,
270 			 bp->bc_waddr,
271 			 bq->bl_col, bp->bc_row);
272 }
273 
274 bmdadjust(hcnt, vcnt)
275 	short hcnt, vcnt;
276 {
277 	volatile register struct bmd_rfcnt *bmd_rfcnt = (struct bmd_rfcnt *) 0xB1000000;
278 	struct bmd_rfcnt rfcnt;
279 
280 	printf("bmdadjust: hcnt = %d, vcnt = %d\n", hcnt, vcnt);
281 
282 	rfcnt.rfc_hcnt = hcnt;			/* shift left   16 dot */
283 	rfcnt.rfc_vcnt = vcnt;			/* shift down    1 dot */
284 
285 	*bmd_rfcnt = rfcnt;
286 }
287 
288 bmdputc(c)
289 	register int c;
290 {
291 	register struct bmd_softc *bp = &bmd_softc;
292 	register struct bmd_linec *bq = bp->bc_bl;
293 	register int i;
294 
295 	c &= 0x7F;
296 							/* turn off cursole */
297 	bmd_reverse_char(bp->bc_raddr,
298 			 bp->bc_waddr,
299 			 bq->bl_col, bp->bc_row);
300 							/* do escape-sequence */
301 	if (bp->bc_stat & STAT_ESCAPE) {
302 		*bp->bc_esc++ = c;
303 		(*bp->bc_escape)(c);
304 		goto done;
305 	}
306 
307 	if (isprint(c)) {
308 		bmd_draw_char(bp->bc_raddr, bp->bc_waddr,
309 			      bq->bl_col, bp->bc_row, c);
310 		bq->bl_col++;
311 		bq->bl_end++;
312 		if (bq->bl_col >= bp->bc_xmax) {
313 			bq->bl_col = bq->bl_end = bp->bc_xmin;
314 			bp->bc_row++;
315 			if (bp->bc_row >= bp->bc_ymax) {
316 				bmd_scroll_screen((u_long *) bp->bc_raddr,
317 						  (u_long *) bp->bc_waddr,
318 						  bp->bc_xmin, bp->bc_xmax,
319 						  bp->bc_ymin, bp->bc_ymax);
320 
321 				bp->bc_row = bp->bc_ymax - 1;
322 			}
323 		}
324 	} else {
325 		switch (c) {
326 		case 0x08:				/* BS */
327 			if (bq->bl_col > bp->bc_xmin) {
328 				bq->bl_col--;
329 			}
330 			break;
331 
332 		case 0x09:				/* HT */
333 		case 0x0B:				/* VT */
334 			i = ((bq->bl_col / 8) + 1) * 8;
335 			if (i < bp->bc_xmax) {
336 				bq->bl_col = bq->bl_end = i;
337 			}
338 			break;
339 
340 		case 0x0A:				/* NL */
341 			bp->bc_row++;
342 			if (bp->bc_row >= bp->bc_ymax) {
343 				bmd_scroll_screen((u_long *) bp->bc_raddr,
344 						  (u_long *) bp->bc_waddr,
345 						  bp->bc_xmin, bp->bc_xmax,
346 						  bp->bc_ymin, bp->bc_ymax);
347 
348 				bp->bc_row = bp->bc_ymax - 1;
349 			}
350 			break;
351 
352 		case 0x0D:				/* CR */
353 			bq->bl_col = bp->bc_xmin;
354 			break;
355 
356 		case 0x1b:				/* ESC */
357 			bp->bc_stat |= STAT_ESCAPE;
358 			*bp->bc_esc++ = 0x1b;
359 			break;
360 
361 		case 0x7F:				/* DEL */
362 			if (bq->bl_col > bp->bc_xmin) {
363 				bq->bl_col--;
364 				bmd_erase_char(bp->bc_raddr,
365 					       bp->bc_waddr,
366 					       bq->bl_col, bp->bc_row);
367 			}
368 			break;
369 
370 		default:
371 			break;
372 		}
373 	}
374 
375  done:
376 							/* turn on  cursole */
377 	bmd_reverse_char(bp->bc_raddr,
378 			 bp->bc_waddr,
379 			 bq->bl_col, bp->bc_row);
380 
381 	return(c);
382 }
383 
384 bmdclear()
385 {
386 	register struct bmd_softc *bp = &bmd_softc;
387 	register struct bmd_linec *bq = bp->bc_bl;
388 
389 	bmd_erase_screen((u_long *) bp->bc_waddr);	/* clear screen */
390 
391 	bq->bl_col = bq->bl_end = bp->bc_xmin;
392 	bp->bc_row = bp->bc_ymin;
393 
394 	bmd_reverse_char(bp->bc_raddr,
395 			 bp->bc_waddr,
396 			 bq->bl_col, bp->bc_row);	/* turn on  cursole */
397 }
398 
399 
400 /*
401  *
402  */
403 
404 void
405 bmd_add_new_line()
406 {
407 }
408 
409 
410 /*
411  *  charactor operation routines
412  */
413 
414 void
415 bmd_draw_char(raddr, waddr, col, row, c)
416 	char *raddr;
417 	char *waddr;
418 	int col;
419 	int row;
420 	int c;
421 {
422 	volatile register u_short  *p,  *q, *fp;
423 	volatile register u_long  *lp, *lq;
424 	register int i;
425 
426 	fp = &bmdfont[c][0];
427 
428 	switch (col % 4) {
429 
430 	case 0:
431 		p = (u_short *) ( raddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 ));
432 		q = (u_short *) ( waddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 ));
433 		for (i = 0; i < FB_HIGHT; i++) {
434 			*q = (*p & 0x000F) | (*fp & 0xFFF0);
435 			p += 128;
436 			q += 128;
437 			fp++;
438 		}
439 		break;
440 
441 	case 1:
442 		lp = (u_long *) ( raddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 ));
443 		lq = (u_long *) ( waddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 ));
444 		for (i = 0; i < FB_HIGHT; i++) {
445 			*lq = (*lp & 0xFFF000FF) | ((u_long)(*fp & 0xFFF0) << 4);
446 			lp += 64;
447 			lq += 64;
448 			fp++;
449 		}
450 		break;
451 
452 	case 2:
453 		lp = (u_long *) ( raddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 2 );
454 		lq = (u_long *) ( waddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 2 );
455 		for (i = 0; i < FB_HIGHT; i++) {
456 			*lq = (*lp & 0xFF000FFF) | ((u_long)(*fp & 0xFFF0) << 8);
457 			lp += 64;
458 			lq += 64;
459 			fp++;
460 		}
461 		break;
462 
463 	case 3:
464 		p = (u_short *) ( raddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 4 );
465 		q = (u_short *) ( waddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 4 );
466 		for (i = 0; i < FB_HIGHT; i++) {
467 			*q = (*p & 0xF000) | ((*fp & 0xFFF0) >> 4);
468 			p += 128;
469 			q += 128;
470 			fp++;
471 		}
472 		break;
473 
474 	default:
475 		break;
476 	}
477 }
478 
479 void
480 bmd_reverse_char(raddr, waddr, col, row)
481 	char *raddr;
482 	char *waddr;
483 	int col;
484 	int row;
485 {
486 	volatile register u_short  *p,  *q,  us;
487 	volatile register u_long  *lp, *lq,  ul;
488 	register int i;
489 
490 	switch (col%4) {
491 
492 	case 0:
493 		p = (u_short *) ( raddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 ));
494 		q = (u_short *) ( waddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 ));
495 		for (i = 0; i < FB_HIGHT; i++) {
496 			*q = (*p & 0x000F) | (~(*p) & 0xFFF0);
497 			p += 128;
498 			q += 128;
499 		}
500 		break;
501 
502 	case 1:
503 		lp = (u_long *) ( raddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 ));
504 		lq = (u_long *) ( waddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 ));
505 		for (i = 0; i < FB_HIGHT; i++) {
506 			*lq = (*lp & 0xFFF000FF) | (~(*lp) & 0x000FFF00);
507 			lp += 64;
508 			lq += 64;
509 		}
510 		break;
511 
512 	case 2:
513 		lp = (u_long *) ( raddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 2 );
514 		lq = (u_long *) ( waddr + (( row * FB_HIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 2 );
515 		for (i = 0; i < FB_HIGHT; i++) {
516 			*lq = (*lp & 0xFF000FFF) | (~(*lp) & 0x00FFF000);
517 			lp += 64;
518 			lq += 64;
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) | (~(*p) & 0x0FFF);
527 			p += 128;
528 			q += 128;
529 		}
530 		break;
531 
532 	default:
533 		break;
534 	}
535 }
536 
537 void
538 bmd_erase_char(raddr, waddr, col, row)
539 	char *raddr;
540 	char *waddr;
541 	int col;
542 	int row;
543 {
544 	bmd_draw_char(raddr, waddr, col, row, 0);
545 
546 	return;
547 }
548 
549 
550 /*
551  * screen operation routines
552  */
553 
554 void
555 bmd_erase_screen(lp)
556 	volatile register u_long *lp;
557 {
558 	register int i, j;
559 
560 	for (i = 0; i < SB_HIGHT; i++) {
561 		for (j = 0; j < SL_WIDTH; j++)
562 			*lp++ = 0;
563 		SKIP_NEXT_LINE(lp);
564 	}
565 
566 	return;
567 }
568 
569 void
570 bmd_scroll_screen(lp, lq, xmin, xmax, ymin, ymax)
571 	volatile register u_long *lp;
572 	volatile register u_long *lq;
573 	int xmin, xmax, ymin, ymax;
574 {
575 	register int i, j;
576 
577 	lp += ((PL_WIDTH * FB_HIGHT) * (ymin + 1));
578 	lq += ((PL_WIDTH * FB_HIGHT) *  ymin);
579 
580 	for (i = 0; i < ((ymax - ymin -1) * FB_HIGHT); i++) {
581 		for (j = 0; j < SL_WIDTH; j++) {
582 			*lq++ = *lp++;
583 		}
584 		lp += (PL_WIDTH - SL_WIDTH);
585 		lq += (PL_WIDTH - SL_WIDTH);
586 	}
587 
588 	for (i = 0; i < FB_HIGHT; i++) {
589 		for (j = 0; j < SL_WIDTH; j++) {
590 			*lq++ = 0;
591 		}
592 		lq += (PL_WIDTH - SL_WIDTH);
593 	}
594 
595 }
596