xref: /openbsd-src/sys/arch/luna88k/stand/boot/bmd.c (revision 684cac8db8ccc6cef5c286bbf265a3504cda0680)
1*684cac8dSaoyama /*	$OpenBSD: bmd.c,v 1.6 2023/02/15 12:43:32 aoyama Exp $	*/
296f141a8Smiod /*	$NetBSD: bmd.c,v 1.2 2013/01/20 13:35:43 tsutsui Exp $	*/
396f141a8Smiod 
496f141a8Smiod /*
596f141a8Smiod  * Copyright (c) 1992 OMRON Corporation.
696f141a8Smiod  *
796f141a8Smiod  * This code is derived from software contributed to Berkeley by
896f141a8Smiod  * OMRON Corporation.
996f141a8Smiod  *
1096f141a8Smiod  * Redistribution and use in source and binary forms, with or without
1196f141a8Smiod  * modification, are permitted provided that the following conditions
1296f141a8Smiod  * are met:
1396f141a8Smiod  * 1. Redistributions of source code must retain the above copyright
1496f141a8Smiod  *    notice, this list of conditions and the following disclaimer.
1596f141a8Smiod  * 2. Redistributions in binary form must reproduce the above copyright
1696f141a8Smiod  *    notice, this list of conditions and the following disclaimer in the
1796f141a8Smiod  *    documentation and/or other materials provided with the distribution.
1896f141a8Smiod  * 3. All advertising materials mentioning features or use of this software
1996f141a8Smiod  *    must display the following acknowledgement:
2096f141a8Smiod  *	This product includes software developed by the University of
2196f141a8Smiod  *	California, Berkeley and its contributors.
2296f141a8Smiod  * 4. Neither the name of the University nor the names of its contributors
2396f141a8Smiod  *    may be used to endorse or promote products derived from this software
2496f141a8Smiod  *    without specific prior written permission.
2596f141a8Smiod  *
2696f141a8Smiod  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2796f141a8Smiod  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2896f141a8Smiod  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2996f141a8Smiod  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
3096f141a8Smiod  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3196f141a8Smiod  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3296f141a8Smiod  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3396f141a8Smiod  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3496f141a8Smiod  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3596f141a8Smiod  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3696f141a8Smiod  * SUCH DAMAGE.
3796f141a8Smiod  *
3896f141a8Smiod  *	@(#)bmd.c	8.2 (Berkeley) 8/15/93
3996f141a8Smiod  */
4096f141a8Smiod /*
4196f141a8Smiod  * Copyright (c) 1992, 1993
4296f141a8Smiod  *	The Regents of the University of California.  All rights reserved.
4396f141a8Smiod  *
4496f141a8Smiod  * This code is derived from software contributed to Berkeley by
4596f141a8Smiod  * OMRON Corporation.
4696f141a8Smiod  *
4796f141a8Smiod  * Redistribution and use in source and binary forms, with or without
4896f141a8Smiod  * modification, are permitted provided that the following conditions
4996f141a8Smiod  * are met:
5096f141a8Smiod  * 1. Redistributions of source code must retain the above copyright
5196f141a8Smiod  *    notice, this list of conditions and the following disclaimer.
5296f141a8Smiod  * 2. Redistributions in binary form must reproduce the above copyright
5396f141a8Smiod  *    notice, this list of conditions and the following disclaimer in the
5496f141a8Smiod  *    documentation and/or other materials provided with the distribution.
5596f141a8Smiod  * 3. Neither the name of the University nor the names of its contributors
5696f141a8Smiod  *    may be used to endorse or promote products derived from this software
5796f141a8Smiod  *    without specific prior written permission.
5896f141a8Smiod  *
5996f141a8Smiod  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
6096f141a8Smiod  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
6196f141a8Smiod  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
6296f141a8Smiod  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
6396f141a8Smiod  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
6496f141a8Smiod  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
6596f141a8Smiod  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
6696f141a8Smiod  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
6796f141a8Smiod  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
6896f141a8Smiod  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
6996f141a8Smiod  * SUCH DAMAGE.
7096f141a8Smiod  *
7196f141a8Smiod  *	@(#)bmd.c	8.2 (Berkeley) 8/15/93
7296f141a8Smiod  */
7396f141a8Smiod /*
7496f141a8Smiod 
7596f141a8Smiod  * bmd.c --- Bitmap-Display raw-level driver routines
7696f141a8Smiod  *
7796f141a8Smiod  *	by A.Fujita, SEP-09-1992
7896f141a8Smiod  */
7996f141a8Smiod 
8096f141a8Smiod 
8196f141a8Smiod #include <sys/param.h>
82d2f66e2eSmiod #include <machine/board.h>
8396f141a8Smiod #include <luna88k/stand/boot/samachdep.h>
8496f141a8Smiod 
8596f141a8Smiod /*
8696f141a8Smiod  *  RFCNT register
8796f141a8Smiod  */
8896f141a8Smiod 
8996f141a8Smiod union bmd_rfcnt {
9096f141a8Smiod 	struct {
9196f141a8Smiod 		short	rfc_hcnt;
9296f141a8Smiod 		short	rfc_vcnt;
9396f141a8Smiod 	} p;
9496f141a8Smiod 	uint32_t u;
9596f141a8Smiod };
9696f141a8Smiod 
97a5011688Smiod #define isprint(c)      ((c) >= 0x20 && (c) < 0x7f)
9896f141a8Smiod 
9996f141a8Smiod /*
100a5011688Smiod  *  Width & Height
10196f141a8Smiod  */
10296f141a8Smiod 
10396f141a8Smiod #define	PB_WIDTH	2048			/* Plane Width   (Bit) */
104a5011688Smiod #define	PB_HEIGHT	1024			/* Plane Height  (Bit) */
105a5011688Smiod #define PS_WIDTH	128			/* Plane Width   (Short) */
10696f141a8Smiod #define P_WIDTH		256			/* Plane Width   (Byte) */
10796f141a8Smiod 
10896f141a8Smiod #define SB_WIDTH	1280			/* Screen Width  (Bit) */
109a5011688Smiod #define	SB_HEIGHT	1024			/* Screen Height (Bit) */
110a5011688Smiod #define SS_WIDTH	80			/* Screen Width  (Short) */
11196f141a8Smiod #define S_WIDTH		160			/* Screen Width  (Byte) */
11296f141a8Smiod 
11396f141a8Smiod #define FB_WIDTH	12			/* Font Width    (Bit) */
114a5011688Smiod #define FB_HEIGHT	20			/* Font Height   (Bit) */
11596f141a8Smiod 
11696f141a8Smiod 
117a5011688Smiod #define NEXT_LINE(addr)			((addr) + (PS_WIDTH * FB_HEIGHT))
118a5011688Smiod #define SKIP_NEXT_LINE(addr)		(addr) += (PS_WIDTH - SS_WIDTH)
11996f141a8Smiod 
12096f141a8Smiod 
12196f141a8Smiod void	bmd_draw_char(char *, char *, int, int, int);
12296f141a8Smiod void	bmd_reverse_char(char *, char *, int, int);
12396f141a8Smiod void	bmd_erase_char(char *, char *, int, int);
12496f141a8Smiod void	bmd_erase_screen(volatile u_short *);
12596f141a8Smiod void	bmd_scroll_screen(volatile u_short *, volatile u_short *,
12696f141a8Smiod 	    int, int, int, int);
12796f141a8Smiod 
12896f141a8Smiod 
12996f141a8Smiod struct bmd_linec {
13096f141a8Smiod 	struct bmd_linec *bl_next;
13196f141a8Smiod 	struct bmd_linec *bl_prev;
13296f141a8Smiod 	int	bl_col;
13396f141a8Smiod 	int	bl_end;
13496f141a8Smiod 	u_char	bl_line[128];
13596f141a8Smiod };
13696f141a8Smiod 
13796f141a8Smiod struct bmd_softc {
13896f141a8Smiod 	int	bc_stat;
13996f141a8Smiod 	char   *bc_raddr;
14096f141a8Smiod 	char   *bc_waddr;
14196f141a8Smiod 	int	bc_xmin;
14296f141a8Smiod 	int	bc_xmax;
14396f141a8Smiod 	int	bc_ymin;
14496f141a8Smiod 	int	bc_ymax;
14596f141a8Smiod 	int	bc_col;
14696f141a8Smiod 	int	bc_row;
14796f141a8Smiod 	struct bmd_linec *bc_bl;
14896f141a8Smiod 	char	bc_escseq[8];
14996f141a8Smiod 	char   *bc_esc;
15096f141a8Smiod 	void  (*bc_escape)(int);
15196f141a8Smiod };
15296f141a8Smiod 
15396f141a8Smiod #define	STAT_NORMAL	0x0000
15496f141a8Smiod #define	STAT_ESCAPE	0x0001
15596f141a8Smiod #define	STAT_INSERT	0x0100
15696f141a8Smiod 
15796f141a8Smiod struct	bmd_softc bmd_softc;
15896f141a8Smiod struct	bmd_linec bmd_linec[52];
15996f141a8Smiod 
16096f141a8Smiod void	bmd_escape(int);
16196f141a8Smiod void	bmd_escape_0(int);
16296f141a8Smiod void	bmd_escape_1(int);
16396f141a8Smiod 
16496f141a8Smiod 
16596f141a8Smiod /*
16696f141a8Smiod  * Escape-Sequence
16796f141a8Smiod  */
16896f141a8Smiod 
16996f141a8Smiod void
bmd_escape(int c)17096f141a8Smiod bmd_escape(int c)
17196f141a8Smiod {
17296f141a8Smiod 	struct bmd_softc *bp = &bmd_softc;
17396f141a8Smiod 
17496f141a8Smiod 	switch (c) {
17596f141a8Smiod 
17696f141a8Smiod 	case '[':
17796f141a8Smiod 		bp->bc_escape = bmd_escape_0;
17896f141a8Smiod 		break;
17996f141a8Smiod 
18096f141a8Smiod 	default:
18196f141a8Smiod 		bp->bc_stat &= ~STAT_ESCAPE;
18296f141a8Smiod 		bp->bc_esc = &bp->bc_escseq[0];
18396f141a8Smiod 		bp->bc_escape = bmd_escape;
18496f141a8Smiod 		break;
18596f141a8Smiod 	}
18696f141a8Smiod }
18796f141a8Smiod 
18896f141a8Smiod void
bmd_escape_0(int c)18996f141a8Smiod bmd_escape_0(int c)
19096f141a8Smiod {
19196f141a8Smiod 	struct bmd_softc *bp = &bmd_softc;
19296f141a8Smiod 	struct bmd_linec *bq = bp->bc_bl;
19396f141a8Smiod 
19496f141a8Smiod 	switch (c) {
19596f141a8Smiod 
19696f141a8Smiod 	case 'A':
19796f141a8Smiod 		if (bp->bc_row > bp->bc_ymin) {
19896f141a8Smiod 			bp->bc_row--;
19996f141a8Smiod 		}
20096f141a8Smiod 		break;
20196f141a8Smiod 
20296f141a8Smiod 	case 'C':
20396f141a8Smiod 		if (bq->bl_col < bp->bc_xmax - 1) {
20496f141a8Smiod 			bq->bl_col++;
20596f141a8Smiod 		}
20696f141a8Smiod 		break;
20796f141a8Smiod 
20896f141a8Smiod 	case 'K':
20996f141a8Smiod 		if (bq->bl_col < bp->bc_xmax) {
21096f141a8Smiod 			int col;
21196f141a8Smiod 			for (col = bq->bl_col; col < bp->bc_xmax; col++)
21296f141a8Smiod 				bmd_erase_char(bp->bc_raddr,
21396f141a8Smiod 					       bp->bc_waddr,
21496f141a8Smiod 					       col, bp->bc_row);
21596f141a8Smiod 		}
21696f141a8Smiod 		bq->bl_end = bq->bl_col;
21796f141a8Smiod 		break;
21896f141a8Smiod 
21996f141a8Smiod 	case 'H':
22096f141a8Smiod 		bq->bl_col = bq->bl_end = bp->bc_xmin;
22196f141a8Smiod 		bp->bc_row = bp->bc_ymin;
22296f141a8Smiod 		break;
22396f141a8Smiod 
22496f141a8Smiod 	default:
22596f141a8Smiod /*
22696f141a8Smiod 		*bp->bc_esc++ = c;
22796f141a8Smiod 		bp->bc_escape = bmd_escape_1;
22896f141a8Smiod 		return;
22996f141a8Smiod  */
23096f141a8Smiod 		break;
23196f141a8Smiod 	}
23296f141a8Smiod 
23396f141a8Smiod 	bp->bc_stat &= ~STAT_ESCAPE;
23496f141a8Smiod 	bp->bc_esc = &bp->bc_escseq[0];
23596f141a8Smiod 	bp->bc_escape = bmd_escape;
23696f141a8Smiod }
23796f141a8Smiod 
23896f141a8Smiod void
bmd_escape_1(int c)23996f141a8Smiod bmd_escape_1(int c)
24096f141a8Smiod {
24196f141a8Smiod 	struct bmd_softc *bp = &bmd_softc;
24296f141a8Smiod 	struct bmd_linec *bq = bp->bc_bl;
24396f141a8Smiod 	int col = 0, row = 0;
24496f141a8Smiod 	char *p;
24596f141a8Smiod 
24696f141a8Smiod 	switch (c) {
24796f141a8Smiod 
24896f141a8Smiod 	case 'J':
24996f141a8Smiod 		bp->bc_stat &= ~STAT_ESCAPE;
25096f141a8Smiod 		bp->bc_esc = &bp->bc_escseq[0];
25196f141a8Smiod 		bp->bc_escape = bmd_escape;
25296f141a8Smiod 		break;
25396f141a8Smiod 
25496f141a8Smiod 	case 'H':
25596f141a8Smiod 		for (p = &bp->bc_escseq[0]; *p != ';'; p++)
25696f141a8Smiod 			row = (row * 10) + (*p - 0x30);
25796f141a8Smiod 		p++;
25896f141a8Smiod 		for (p = &bp->bc_escseq[0]; p != bp->bc_esc; p++)
25996f141a8Smiod 			col = (col * 10) + (*p - 0x30);
26096f141a8Smiod 
26196f141a8Smiod 		bq->bl_col = col + bp->bc_xmin;
26296f141a8Smiod 		bp->bc_row = row + bp->bc_ymin;
26396f141a8Smiod 
26496f141a8Smiod 		bp->bc_stat &= ~STAT_ESCAPE;
26596f141a8Smiod 		bp->bc_esc = &bp->bc_escseq[0];
26696f141a8Smiod 		bp->bc_escape = bmd_escape;
26796f141a8Smiod 		break;
26896f141a8Smiod 
26996f141a8Smiod 	default:
27096f141a8Smiod 		*bp->bc_esc++ = c;
27196f141a8Smiod 		break;
27296f141a8Smiod 	}
27396f141a8Smiod }
27496f141a8Smiod 
27596f141a8Smiod 
27696f141a8Smiod /*
27796f141a8Smiod  * Entry Routine
27896f141a8Smiod  */
27996f141a8Smiod 
28096f141a8Smiod void
bmdinit(void)28196f141a8Smiod bmdinit(void)
28296f141a8Smiod {
283d2f66e2eSmiod 	volatile uint32_t *bmd_rfcnt = (volatile uint32_t *)BMAP_RFCNT;
284d2f66e2eSmiod 	volatile long *bmd_bmsel = (volatile long *)BMAP_BMSEL;
28596f141a8Smiod 	struct bmd_softc *bp = &bmd_softc;
28696f141a8Smiod 	struct bmd_linec *bq;
28796f141a8Smiod 	int i;
28896f141a8Smiod 	union bmd_rfcnt rfcnt;
28996f141a8Smiod 
29096f141a8Smiod 	/*
29196f141a8Smiod 	 *  adjust plane position
29296f141a8Smiod 	 */
29396f141a8Smiod 
294d2f66e2eSmiod 	bp->bc_raddr = (char *)(BMAP_BMAP0 + 8);	/* plane-0 hardware address */
295d2f66e2eSmiod 	bp->bc_waddr = (char *)(BMAP_BMP + 8);		/* common bitmap hardware address */
29696f141a8Smiod 	rfcnt.p.rfc_hcnt = 7;				/* shift left   16 dot */
29796f141a8Smiod 	rfcnt.p.rfc_vcnt = -27;				/* shift down    1 dot */
29896f141a8Smiod 	*bmd_rfcnt = rfcnt.u;
29996f141a8Smiod 
30096f141a8Smiod 	bp->bc_stat  = STAT_NORMAL;
30196f141a8Smiod 
302*684cac8dSaoyama 	bp->bc_xmin  = 12;
303*684cac8dSaoyama 	bp->bc_xmax  = 92;
30496f141a8Smiod 	bp->bc_ymin  = 2;
30596f141a8Smiod 	bp->bc_ymax  = 48;
30696f141a8Smiod 
30796f141a8Smiod 	bp->bc_row = bp->bc_ymin;
30896f141a8Smiod 
30996f141a8Smiod 	for (i = bp->bc_ymin; i < bp->bc_ymax; i++) {
31096f141a8Smiod 		bmd_linec[i].bl_next = &bmd_linec[i+1];
31196f141a8Smiod 		bmd_linec[i].bl_prev = &bmd_linec[i-1];
31296f141a8Smiod 	}
31396f141a8Smiod 	bmd_linec[bp->bc_ymax-1].bl_next = &bmd_linec[bp->bc_ymin];
31496f141a8Smiod 	bmd_linec[bp->bc_ymin].bl_prev = &bmd_linec[bp->bc_ymax-1];
31596f141a8Smiod 
31696f141a8Smiod 	bq = bp->bc_bl = &bmd_linec[bp->bc_ymin];
31796f141a8Smiod 	bq->bl_col = bq->bl_end = bp->bc_xmin;
31896f141a8Smiod 
31996f141a8Smiod 	bp->bc_col = bp->bc_xmin;
32096f141a8Smiod 
32196f141a8Smiod 	bp->bc_esc = &bp->bc_escseq[0];
32296f141a8Smiod 	bp->bc_escape = bmd_escape;
32396f141a8Smiod 
32496f141a8Smiod 	*bmd_bmsel = 0xff;				/* all planes */
32596f141a8Smiod 	bmd_erase_screen((u_short *) bp->bc_waddr);	/* clear screen */
32696f141a8Smiod 	*bmd_bmsel = 0x01;				/* 1 plane */
32796f141a8Smiod 
32896f141a8Smiod 							/* turn on  cursole */
32996f141a8Smiod 	bmd_reverse_char(bp->bc_raddr,
33096f141a8Smiod 			 bp->bc_waddr,
33196f141a8Smiod 			 bq->bl_col, bp->bc_row);
33296f141a8Smiod }
33396f141a8Smiod 
33496f141a8Smiod void
bmdadjust(short hcnt,short vcnt)33596f141a8Smiod bmdadjust(short hcnt, short vcnt)
33696f141a8Smiod {
337d2f66e2eSmiod 	volatile uint32_t *bmd_rfcnt = (volatile uint32_t *)BMAP_RFCNT;
33896f141a8Smiod 	union bmd_rfcnt rfcnt;
33996f141a8Smiod 
34096f141a8Smiod 	printf("bmdadjust: hcnt = %d, vcnt = %d\n", hcnt, vcnt);
34196f141a8Smiod 
34296f141a8Smiod 	rfcnt.p.rfc_hcnt = hcnt;		/* shift left   16 dot */
34396f141a8Smiod 	rfcnt.p.rfc_vcnt = vcnt;		/* shift down    1 dot */
34496f141a8Smiod 
34596f141a8Smiod 	*bmd_rfcnt = rfcnt.u;
34696f141a8Smiod }
34796f141a8Smiod 
34896f141a8Smiod int
bmdputc(int c)34996f141a8Smiod bmdputc(int c)
35096f141a8Smiod {
35196f141a8Smiod 	struct bmd_softc *bp = &bmd_softc;
35296f141a8Smiod 	struct bmd_linec *bq = bp->bc_bl;
35396f141a8Smiod 	int i;
35496f141a8Smiod 
35596f141a8Smiod 	c &= 0x7F;
35696f141a8Smiod 							/* turn off cursole */
35796f141a8Smiod 	bmd_reverse_char(bp->bc_raddr,
35896f141a8Smiod 			 bp->bc_waddr,
35996f141a8Smiod 			 bq->bl_col, bp->bc_row);
36096f141a8Smiod 							/* do escape-sequence */
36196f141a8Smiod 	if (bp->bc_stat & STAT_ESCAPE) {
36296f141a8Smiod 		*bp->bc_esc++ = c;
36396f141a8Smiod 		(*bp->bc_escape)(c);
36496f141a8Smiod 		goto done;
36596f141a8Smiod 	}
36696f141a8Smiod 
36796f141a8Smiod 	if (isprint(c)) {
36896f141a8Smiod 		bmd_draw_char(bp->bc_raddr, bp->bc_waddr,
36996f141a8Smiod 			      bq->bl_col, bp->bc_row, c);
37096f141a8Smiod 		bq->bl_col++;
37196f141a8Smiod 		bq->bl_end++;
37296f141a8Smiod 		if (bq->bl_col >= bp->bc_xmax) {
37396f141a8Smiod 			bq->bl_col = bq->bl_end = bp->bc_xmin;
37496f141a8Smiod 			bp->bc_row++;
37596f141a8Smiod 			if (bp->bc_row >= bp->bc_ymax) {
37696f141a8Smiod 				bmd_scroll_screen((u_short *) bp->bc_raddr,
37796f141a8Smiod 						  (u_short *) bp->bc_waddr,
37896f141a8Smiod 						  bp->bc_xmin, bp->bc_xmax,
37996f141a8Smiod 						  bp->bc_ymin, bp->bc_ymax);
38096f141a8Smiod 
38196f141a8Smiod 				bp->bc_row = bp->bc_ymax - 1;
38296f141a8Smiod 			}
38396f141a8Smiod 		}
38496f141a8Smiod 	} else {
38596f141a8Smiod 		switch (c) {
38696f141a8Smiod 		case 0x08:				/* BS */
38796f141a8Smiod 			if (bq->bl_col > bp->bc_xmin) {
38896f141a8Smiod 				bq->bl_col--;
38996f141a8Smiod 			}
39096f141a8Smiod 			break;
39196f141a8Smiod 
39296f141a8Smiod 		case 0x09:				/* HT */
39396f141a8Smiod 		case 0x0B:				/* VT */
39496f141a8Smiod 			i = ((bq->bl_col / 8) + 1) * 8;
39596f141a8Smiod 			if (i < bp->bc_xmax) {
39696f141a8Smiod 				bq->bl_col = bq->bl_end = i;
39796f141a8Smiod 			}
39896f141a8Smiod 			break;
39996f141a8Smiod 
40096f141a8Smiod 		case 0x0A:				/* NL */
40196f141a8Smiod 			bp->bc_row++;
40296f141a8Smiod 			if (bp->bc_row >= bp->bc_ymax) {
40396f141a8Smiod 				bmd_scroll_screen((u_short *) bp->bc_raddr,
40496f141a8Smiod 						  (u_short *) bp->bc_waddr,
40596f141a8Smiod 						  bp->bc_xmin, bp->bc_xmax,
40696f141a8Smiod 						  bp->bc_ymin, bp->bc_ymax);
40796f141a8Smiod 
40896f141a8Smiod 				bp->bc_row = bp->bc_ymax - 1;
40996f141a8Smiod 			}
41096f141a8Smiod 			break;
41196f141a8Smiod 
41296f141a8Smiod 		case 0x0D:				/* CR */
41396f141a8Smiod 			bq->bl_col = bp->bc_xmin;
41496f141a8Smiod 			break;
41596f141a8Smiod 
41696f141a8Smiod 		case 0x1b:				/* ESC */
41796f141a8Smiod 			bp->bc_stat |= STAT_ESCAPE;
41896f141a8Smiod 			*bp->bc_esc++ = 0x1b;
41996f141a8Smiod 			break;
42096f141a8Smiod 
42196f141a8Smiod 		case 0x7F:				/* DEL */
42296f141a8Smiod 			if (bq->bl_col > bp->bc_xmin) {
42396f141a8Smiod 				bq->bl_col--;
42496f141a8Smiod 				bmd_erase_char(bp->bc_raddr,
42596f141a8Smiod 					       bp->bc_waddr,
42696f141a8Smiod 					       bq->bl_col, bp->bc_row);
42796f141a8Smiod 			}
42896f141a8Smiod 			break;
42996f141a8Smiod 
43096f141a8Smiod 		default:
43196f141a8Smiod 			break;
43296f141a8Smiod 		}
43396f141a8Smiod 	}
43496f141a8Smiod 
43596f141a8Smiod  done:
43696f141a8Smiod 							/* turn on  cursole */
43796f141a8Smiod 	bmd_reverse_char(bp->bc_raddr,
43896f141a8Smiod 			 bp->bc_waddr,
43996f141a8Smiod 			 bq->bl_col, bp->bc_row);
44096f141a8Smiod 
44196f141a8Smiod 	return(c);
44296f141a8Smiod }
44396f141a8Smiod 
44496f141a8Smiod void
bmdclear(void)44596f141a8Smiod bmdclear(void)
44696f141a8Smiod {
44796f141a8Smiod 	struct bmd_softc *bp = &bmd_softc;
44896f141a8Smiod 	struct bmd_linec *bq = bp->bc_bl;
44996f141a8Smiod 
45096f141a8Smiod 	bmd_erase_screen((u_short *) bp->bc_waddr);	/* clear screen */
45196f141a8Smiod 
45296f141a8Smiod 	bq->bl_col = bq->bl_end = bp->bc_xmin;
45396f141a8Smiod 	bp->bc_row = bp->bc_ymin;
45496f141a8Smiod 
45596f141a8Smiod 	bmd_reverse_char(bp->bc_raddr,
45696f141a8Smiod 			 bp->bc_waddr,
45796f141a8Smiod 			 bq->bl_col, bp->bc_row);	/* turn on  cursole */
45896f141a8Smiod }
45996f141a8Smiod 
46096f141a8Smiod 
46196f141a8Smiod /*
46236fd90dcSjsg  *  character operation routines
46396f141a8Smiod  */
46496f141a8Smiod 
46596f141a8Smiod void
bmd_draw_char(char * raddr,char * waddr,int col,int row,int c)46696f141a8Smiod bmd_draw_char(char *raddr, char *waddr, int col, int row, int c)
46796f141a8Smiod {
468a5011688Smiod 	volatile u_short *p, *q;
469a5011688Smiod 	const u_short *fp;
47096f141a8Smiod 	int i;
47196f141a8Smiod 
47296f141a8Smiod 	fp = &bmdfont[c][0];
47396f141a8Smiod 
47496f141a8Smiod 	switch (col % 4) {
47596f141a8Smiod 
47696f141a8Smiod 	case 0:
477a5011688Smiod 		p = (u_short *) ( raddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ));
478a5011688Smiod 		q = (u_short *) ( waddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ));
479a5011688Smiod 		for (i = 0; i < FB_HEIGHT; i++) {
48096f141a8Smiod 			*q = (*p & 0x000F) | (*fp & 0xFFF0);
48196f141a8Smiod 			p += 128;
48296f141a8Smiod 			q += 128;
48396f141a8Smiod 			fp++;
48496f141a8Smiod 		}
48596f141a8Smiod 		break;
48696f141a8Smiod 
48796f141a8Smiod 	case 1:
488a5011688Smiod 		p = (u_short *) ( raddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ));
489a5011688Smiod 		q = (u_short *) ( waddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ));
490a5011688Smiod 		for (i = 0; i < FB_HEIGHT; i++) {
491f01b1271Smiod 			q[0] = (p[0] & 0xFFF0) | ((*fp & 0xF000) >> 12);
492f01b1271Smiod 			q[1] = (p[1] & 0x00FF) | ((*fp & 0x0FF0) << 4);
493f01b1271Smiod 			p += 128;
494f01b1271Smiod 			q += 128;
49596f141a8Smiod 			fp++;
49696f141a8Smiod 		}
49796f141a8Smiod 		break;
49896f141a8Smiod 
49996f141a8Smiod 	case 2:
500a5011688Smiod 		p = (u_short *) ( raddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 2 );
501a5011688Smiod 		q = (u_short *) ( waddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 2 );
502a5011688Smiod 		for (i = 0; i < FB_HEIGHT; i++) {
503f01b1271Smiod 			q[0] = (p[0] & 0xFF00) | ((*fp & 0xFF00) >> 8);
504f01b1271Smiod 			q[1] = (p[1] & 0x0FFF) | ((*fp & 0x00F0) << 8);
505f01b1271Smiod 			p += 128;
506f01b1271Smiod 			q += 128;
50796f141a8Smiod 			fp++;
50896f141a8Smiod 		}
50996f141a8Smiod 		break;
51096f141a8Smiod 
51196f141a8Smiod 	case 3:
512a5011688Smiod 		p = (u_short *) ( raddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 4 );
513a5011688Smiod 		q = (u_short *) ( waddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 4 );
514a5011688Smiod 		for (i = 0; i < FB_HEIGHT; i++) {
51596f141a8Smiod 			*q = (*p & 0xF000) | ((*fp & 0xFFF0) >> 4);
51696f141a8Smiod 			p += 128;
51796f141a8Smiod 			q += 128;
51896f141a8Smiod 			fp++;
51996f141a8Smiod 		}
52096f141a8Smiod 		break;
52196f141a8Smiod 
52296f141a8Smiod 	default:
52396f141a8Smiod 		break;
52496f141a8Smiod 	}
52596f141a8Smiod }
52696f141a8Smiod 
52796f141a8Smiod void
bmd_reverse_char(char * raddr,char * waddr,int col,int row)52896f141a8Smiod bmd_reverse_char(char *raddr, char *waddr, int col, int row)
52996f141a8Smiod {
53096f141a8Smiod 	volatile u_short *p, *q;
53196f141a8Smiod 	int i;
53296f141a8Smiod 
53396f141a8Smiod 	switch (col%4) {
53496f141a8Smiod 
53596f141a8Smiod 	case 0:
536a5011688Smiod 		p = (u_short *) ( raddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ));
537a5011688Smiod 		q = (u_short *) ( waddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ));
538a5011688Smiod 		for (i = 0; i < FB_HEIGHT; i++) {
53996f141a8Smiod 			*q = (*p & 0x000F) | (~(*p) & 0xFFF0);
54096f141a8Smiod 			p += 128;
54196f141a8Smiod 			q += 128;
54296f141a8Smiod 		}
54396f141a8Smiod 		break;
54496f141a8Smiod 
54596f141a8Smiod 	case 1:
546a5011688Smiod 		p = (u_short *) ( raddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ));
547a5011688Smiod 		q = (u_short *) ( waddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ));
548a5011688Smiod 		for (i = 0; i < FB_HEIGHT; i++) {
549f01b1271Smiod 			q[0] = (p[0] & 0xFFF0) | (~p[0] & 0x000F);
550f01b1271Smiod 			q[1] = (p[1] & 0x00FF) | (~p[1] & 0xFF00);
551f01b1271Smiod 			p += 128;
552f01b1271Smiod 			q += 128;
55396f141a8Smiod 		}
55496f141a8Smiod 		break;
55596f141a8Smiod 
55696f141a8Smiod 	case 2:
557a5011688Smiod 		p = (u_short *) ( raddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 2 );
558a5011688Smiod 		q = (u_short *) ( waddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 2 );
559a5011688Smiod 		for (i = 0; i < FB_HEIGHT; i++) {
560f01b1271Smiod 			q[0] = (p[0] & 0xFF00) | (~p[0] & 0x00FF);
561f01b1271Smiod 			q[1] = (p[1] & 0x0FFF) | (~p[1] & 0xF000);
562f01b1271Smiod 			p += 128;
563f01b1271Smiod 			q += 128;
56496f141a8Smiod 		}
56596f141a8Smiod 		break;
56696f141a8Smiod 
56796f141a8Smiod 	case 3:
568a5011688Smiod 		p = (u_short *) ( raddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 4 );
569a5011688Smiod 		q = (u_short *) ( waddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 4 );
570a5011688Smiod 		for (i = 0; i < FB_HEIGHT; i++) {
57196f141a8Smiod 			*q = (*p & 0xF000) | (~(*p) & 0x0FFF);
57296f141a8Smiod 			p += 128;
57396f141a8Smiod 			q += 128;
57496f141a8Smiod 		}
57596f141a8Smiod 		break;
57696f141a8Smiod 
57796f141a8Smiod 	default:
57896f141a8Smiod 		break;
57996f141a8Smiod 	}
58096f141a8Smiod }
58196f141a8Smiod 
58296f141a8Smiod void
bmd_erase_char(char * raddr,char * waddr,int col,int row)58396f141a8Smiod bmd_erase_char(char *raddr, char *waddr, int col, int row)
58496f141a8Smiod {
58596f141a8Smiod 	bmd_draw_char(raddr, waddr, col, row, 0);
58696f141a8Smiod 
58796f141a8Smiod 	return;
58896f141a8Smiod }
58996f141a8Smiod 
59096f141a8Smiod 
59196f141a8Smiod /*
59296f141a8Smiod  * screen operation routines
59396f141a8Smiod  */
59496f141a8Smiod 
59596f141a8Smiod void
bmd_erase_screen(volatile u_short * p)596f01b1271Smiod bmd_erase_screen(volatile u_short *p)
59796f141a8Smiod {
59896f141a8Smiod 	int i, j;
59996f141a8Smiod 
600a5011688Smiod 	for (i = 0; i < SB_HEIGHT; i++) {
60196f141a8Smiod 		for (j = 0; j < SS_WIDTH; j++)
602f01b1271Smiod 			*p++ = 0;
603f01b1271Smiod 		SKIP_NEXT_LINE(p);
60496f141a8Smiod 	}
60596f141a8Smiod 
60696f141a8Smiod 	return;
60796f141a8Smiod }
60896f141a8Smiod 
60996f141a8Smiod void
bmd_scroll_screen(volatile u_short * p,volatile u_short * q,int xmin,int xmax,int ymin,int ymax)610f01b1271Smiod bmd_scroll_screen(volatile u_short *p, volatile u_short *q,
61196f141a8Smiod     int xmin, int xmax, int ymin, int ymax)
61296f141a8Smiod {
61396f141a8Smiod 	int i, j;
61496f141a8Smiod 
615a5011688Smiod 	p += ((PS_WIDTH * FB_HEIGHT) * (ymin + 1));
616a5011688Smiod 	q += ((PS_WIDTH * FB_HEIGHT) *  ymin);
61796f141a8Smiod 
618a5011688Smiod 	for (i = 0; i < ((ymax - ymin -1) * FB_HEIGHT); i++) {
61996f141a8Smiod 		for (j = 0; j < SS_WIDTH; j++) {
620f01b1271Smiod 			*q++ = *p++;
62196f141a8Smiod 		}
622f01b1271Smiod 		p += (PS_WIDTH - SS_WIDTH);
623f01b1271Smiod 		q += (PS_WIDTH - SS_WIDTH);
62496f141a8Smiod 	}
62596f141a8Smiod 
626a5011688Smiod 	for (i = 0; i < FB_HEIGHT; i++) {
62796f141a8Smiod 		for (j = 0; j < SS_WIDTH; j++) {
628f01b1271Smiod 			*q++ = 0;
62996f141a8Smiod 		}
630f01b1271Smiod 		q += (PS_WIDTH - SS_WIDTH);
63196f141a8Smiod 	}
63296f141a8Smiod 
63396f141a8Smiod }
634