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