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