Home | History | Annotate | Line # | Download | only in rcons
rcons_kern.c revision 1.3
      1 /*	$NetBSD: rcons_kern.c,v 1.3 1995/11/29 22:09:23 pk Exp $ */
      2 
      3 /*
      4  * Copyright (c) 1991, 1993
      5  *	The Regents of the University of California.  All rights reserved.
      6  *
      7  * This software was developed by the Computer Systems Engineering group
      8  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
      9  * contributed to Berkeley.
     10  *
     11  * All advertising materials mentioning features or use of this software
     12  * must display the following acknowledgement:
     13  *	This product includes software developed by the University of
     14  *	California, Lawrence Berkeley Laboratory.
     15  *
     16  * Redistribution and use in source and binary forms, with or without
     17  * modification, are permitted provided that the following conditions
     18  * are met:
     19  * 1. Redistributions of source code must retain the above copyright
     20  *    notice, this list of conditions and the following disclaimer.
     21  * 2. Redistributions in binary form must reproduce the above copyright
     22  *    notice, this list of conditions and the following disclaimer in the
     23  *    documentation and/or other materials provided with the distribution.
     24  * 3. All advertising materials mentioning features or use of this software
     25  *    must display the following acknowledgement:
     26  *	This product includes software developed by the University of
     27  *	California, Berkeley and its contributors.
     28  * 4. Neither the name of the University nor the names of its contributors
     29  *    may be used to endorse or promote products derived from this software
     30  *    without specific prior written permission.
     31  *
     32  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     33  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     34  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     35  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     36  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     37  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     38  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     39  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     40  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     41  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     42  * SUCH DAMAGE.
     43  *
     44  *	@(#)rcons_kern.c	8.1 (Berkeley) 6/11/93
     45  */
     46 
     47 #include <sys/param.h>
     48 #include <sys/device.h>
     49 #include <sys/kernel.h>
     50 #include <sys/systm.h>
     51 #include <sys/ioctl.h>
     52 #include <sys/tty.h>
     53 #include <dev/rcons/raster.h>
     54 #include <dev/rcons/rcons.h>
     55 
     56 extern struct tty *fbconstty;
     57 
     58 static void rcons_belltmr(void *);
     59 
     60 #include "rcons_subr.h"
     61 
     62 static struct rconsole *mydevicep;
     63 
     64 void
     65 rcons_cnputc(c)
     66 	int c;
     67 {
     68 	char buf[1];
     69 
     70 	if (c == '\n')
     71 		rcons_puts(mydevicep, "\r\n", 2);
     72 	else {
     73 		buf[0] = c;
     74 		rcons_puts(mydevicep, buf, 1);
     75 	}
     76 }
     77 
     78 static void
     79 rcons_output(tp)
     80 	register struct tty *tp;
     81 {
     82 	register int s, n, i;
     83 	char buf[OBUFSIZ];
     84 
     85 	s = spltty();
     86 	if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP)) {
     87 		splx(s);
     88 		return;
     89 	}
     90 	tp->t_state |= TS_BUSY;
     91 	splx(s);
     92 	n = q_to_b(&tp->t_outq, buf, sizeof(buf));
     93 	rcons_puts(mydevicep, buf, n);
     94 
     95 	s = spltty();
     96 	tp->t_state &= ~TS_BUSY;
     97 	/* Come back if there's more to do */
     98 	if (tp->t_outq.c_cc) {
     99 		tp->t_state |= TS_TIMEOUT;
    100 		timeout(ttrstrt, tp, 1);
    101 	}
    102 	if (tp->t_outq.c_cc <= tp->t_lowat) {
    103 		if (tp->t_state&TS_ASLEEP) {
    104 			tp->t_state &= ~TS_ASLEEP;
    105 			wakeup((caddr_t)&tp->t_outq);
    106 		}
    107 		selwakeup(&tp->t_wsel);
    108 	}
    109 	splx(s);
    110 }
    111 
    112 /* Ring the console bell */
    113 void
    114 rcons_bell(rc)
    115 	register struct rconsole *rc;
    116 {
    117 	register int i, s;
    118 
    119 	if (rc->rc_bits & FB_VISBELL) {
    120 		/* invert the screen twice */
    121 		for (i = 0; i < 2; ++i)
    122 			raster_op(rc->rc_sp, 0, 0,
    123 			    rc->rc_sp->width, rc->rc_sp->height,
    124 			    RAS_INVERT, (struct raster *) 0, 0, 0);
    125 	}
    126 
    127 	s = splhigh();
    128 	if (rc->rc_belldepth++) {
    129 		if (rc->rc_belldepth > 3)
    130 			rc->rc_belldepth = 3;
    131 		splx(s);
    132 	} else {
    133 		rc->rc_ringing = 1;
    134 		splx(s);
    135 		(*rc->rc_bell)(1);
    136 		/* XXX Chris doesn't like the following divide */
    137 		timeout(rcons_belltmr, rc, hz/10);
    138 	}
    139 }
    140 
    141 /* Bell timer service routine */
    142 static void
    143 rcons_belltmr(p)
    144 	void *p;
    145 {
    146 	register struct rconsole *rc = p;
    147 	register int s = splhigh(), i;
    148 
    149 	if (rc->rc_ringing) {
    150 		rc->rc_ringing = 0;
    151 		i = --rc->rc_belldepth;
    152 		splx(s);
    153 		(*rc->rc_bell)(0);
    154 		if (i != 0)
    155 			/* XXX Chris doesn't like the following divide */
    156 			timeout(rcons_belltmr, rc, hz/30);
    157 	} else {
    158 		rc->rc_ringing = 1;
    159 		splx(s);
    160 		(*rc->rc_bell)(1);
    161 		timeout(rcons_belltmr, rc, hz/10);
    162 	}
    163 }
    164 
    165 void
    166 rcons_init(rc)
    167 	register struct rconsole *rc;
    168 {
    169 	/* XXX this should go away */
    170 	static struct raster xxxraster;
    171 	register struct raster *rp = rc->rc_sp = &xxxraster;
    172 	register struct winsize *ws;
    173 	register int i;
    174 	static int row, col;
    175 
    176 	mydevicep = rc;
    177 
    178 	/* XXX mostly duplicates of data in other places */
    179 	rp->width = rc->rc_width;
    180 	rp->height = rc->rc_height;
    181 	rp->depth = rc->rc_depth;
    182 	if (rc->rc_linebytes & 0x3) {
    183 		printf("rcons_init: linebytes assumption botched (0x%x)\n",
    184 		    rc->rc_linebytes);
    185 		return;
    186 	}
    187 	rp->linelongs = rc->rc_linebytes >> 2;
    188 	rp->pixels = (u_int32_t *)rc->rc_pixels;
    189 
    190 	rc->rc_ras_blank = RAS_CLEAR;
    191 
    192 	/* Impose upper bounds on rc_max{row,col} */
    193 	i = rc->rc_height / rc->rc_font->height;
    194 	if (rc->rc_maxrow > i)
    195 		rc->rc_maxrow = i;
    196 	i = rc->rc_width / rc->rc_font->width;
    197 	if (rc->rc_maxcol > i)
    198 		rc->rc_maxcol = i;
    199 
    200 	/* Let the system know how big the console is */
    201 	ws = &fbconstty->t_winsize;
    202 	ws->ws_row = rc->rc_maxrow;
    203 	ws->ws_col = rc->rc_maxcol;
    204 	ws->ws_xpixel = rc->rc_width;
    205 	ws->ws_ypixel = rc->rc_height;
    206 
    207 	/* Center emulator screen (but align x origin to 32 bits) */
    208 	rc->rc_xorigin =
    209 	    ((rc->rc_width - rc->rc_maxcol * rc->rc_font->width) / 2) & ~0x1f;
    210 	rc->rc_yorigin =
    211 	    (rc->rc_height - rc->rc_maxrow * rc->rc_font->height) / 2;
    212 
    213 	/* Emulator width and height used for scrolling */
    214 	rc->rc_emuwidth = rc->rc_maxcol * rc->rc_font->width;
    215 	if (rc->rc_emuwidth & 0x1f) {
    216 		/* Pad to 32 bits */
    217 		i = (rc->rc_emuwidth + 0x1f) & ~0x1f;
    218 		/* Make sure emulator width isn't too wide */
    219 		if (rc->rc_xorigin + i <= rc->rc_width)
    220 			rc->rc_emuwidth = i;
    221 	}
    222 	rc->rc_emuheight = rc->rc_maxrow * rc->rc_font->height;
    223 
    224 #ifdef RASTERCONS_WONB
    225 	rc->rc_ras_blank = RAS_NOT(rc->rc_ras_blank);
    226 	rc->rc_bits |= FB_INVERT;
    227 #endif
    228 
    229 	if (rc->rc_row == NULL || rc->rc_col == NULL) {
    230 		/*
    231 		 * No address passed; use private copies
    232 		 * go to LL corner and scroll.
    233 		 */
    234 		rc->rc_row = &row;
    235 		rc->rc_col = &col;
    236 		row = rc->rc_maxrow;
    237 		col = 0;
    238 #if 0
    239 		rcons_clear2eop(rc);	/* clear the display */
    240 #endif
    241 		rcons_scroll(rc, 1);
    242 		rcons_cursor(rc);	/* and draw the initial cursor */
    243 	} else {
    244 		/* Prom emulator cursor is currently visible */
    245 		rc->rc_bits |= FB_CURSOR;
    246 	}
    247 
    248 	/* Initialization done; hook us up */
    249 	fbconstty->t_oproc = rcons_output;
    250 	/*fbconstty->t_stop = (void (*)()) nullop;*/
    251 }
    252