Home | History | Annotate | Line # | Download | only in ic
pcdisplay_subr.c revision 1.19
      1 /* $NetBSD: pcdisplay_subr.c,v 1.19 2001/09/04 17:14:49 drochner Exp $ */
      2 
      3 /*
      4  * Copyright (c) 1995, 1996 Carnegie-Mellon University.
      5  * All rights reserved.
      6  *
      7  * Author: Chris G. Demetriou
      8  *
      9  * Permission to use, copy, modify and distribute this software and
     10  * its documentation is hereby granted, provided that both the copyright
     11  * notice and this permission notice appear in all copies of the
     12  * software, derivative works or modified versions, and any portions
     13  * thereof, and that both notices appear in supporting documentation.
     14  *
     15  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
     16  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
     17  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
     18  *
     19  * Carnegie Mellon requests users of this software to return to
     20  *
     21  *  Software Distribution Coordinator  or  Software.Distribution (at) CS.CMU.EDU
     22  *  School of Computer Science
     23  *  Carnegie Mellon University
     24  *  Pittsburgh PA 15213-3890
     25  *
     26  * any improvements or extensions that they make and grant Carnegie the
     27  * rights to redistribute these changes.
     28  */
     29 
     30 #include <sys/param.h>
     31 #include <sys/systm.h>
     32 #include <sys/device.h>
     33 #include <machine/bus.h>
     34 
     35 #include <dev/ic/mc6845reg.h>
     36 #include <dev/ic/pcdisplayvar.h>
     37 
     38 #include <dev/wscons/wsdisplayvar.h>
     39 
     40 void
     41 pcdisplay_cursor_init(scr, existing)
     42 	struct pcdisplayscreen *scr;
     43 	int existing;
     44 {
     45 #ifdef PCDISPLAY_SOFTCURSOR
     46 	bus_space_tag_t memt;
     47 	bus_space_handle_t memh;
     48 	int off;
     49 
     50 	pcdisplay_6845_write(scr->hdl, curstart, 0x10);
     51 	pcdisplay_6845_write(scr->hdl, curend, 0x10);
     52 
     53 	if (existing) {
     54 		/*
     55 		 * This is the first screen. At this point, scr->mem is NULL
     56 		 * (no backing store), so we can't use pcdisplay_cursor() to
     57 		 * do this.
     58 		 */
     59 		memt = scr->hdl->ph_memt;
     60 		memh = scr->hdl->ph_memh;
     61 		off = (scr->vc_crow * scr->type->ncols + scr->vc_ccol) * 2 +
     62 		    scr->dispoffset;
     63 
     64 		scr->cursortmp = bus_space_read_2(memt, memh, off);
     65 		bus_space_write_2(memt, memh, off, scr->cursortmp ^ 0x7700);
     66 	} else
     67 		scr->cursortmp = 0;
     68 #else
     69 	/*
     70 	 * Firmware might not have initialized the cursor shape.  Make
     71 	 * sure there's something we can see.
     72 	 * Don't touch the hardware if this is not the first screen.
     73 	 */
     74 	if (existing) {
     75 		pcdisplay_6845_write(scr->hdl, curstart,
     76 				     scr->type->fontheight - 2);
     77 		pcdisplay_6845_write(scr->hdl, curend,
     78 				     scr->type->fontheight - 1);
     79 	}
     80 #endif
     81 	scr->cursoron = 1;
     82 }
     83 
     84 void
     85 pcdisplay_cursor(id, on, row, col)
     86 	void *id;
     87 	int on, row, col;
     88 {
     89 #ifdef PCDISPLAY_SOFTCURSOR
     90 	struct pcdisplayscreen *scr = id;
     91 	bus_space_tag_t memt = scr->hdl->ph_memt;
     92 	bus_space_handle_t memh = scr->hdl->ph_memh;
     93 	int off;
     94 
     95 	/* Remove old cursor image */
     96 	if (scr->cursoron) {
     97 		off = scr->vc_crow * scr->type->ncols + scr->vc_ccol;
     98 		if (scr->active)
     99 			bus_space_write_2(memt, memh, scr->dispoffset + off * 2,
    100 			    scr->cursortmp);
    101 		else
    102 			scr->mem[off] = scr->cursortmp;
    103 	}
    104 
    105 	scr->vc_crow = row;
    106 	scr->vc_ccol = col;
    107 
    108 	if ((scr->cursoron = on) == 0)
    109 		return;
    110 
    111 	off = (scr->vc_crow * scr->type->ncols + scr->vc_ccol);
    112 	if (scr->active) {
    113 		off = off * 2 + scr->dispoffset;
    114 		scr->cursortmp = bus_space_read_2(memt, memh, off);
    115 		bus_space_write_2(memt, memh, off, scr->cursortmp ^ 0x7700);
    116 	} else {
    117 		scr->cursortmp = scr->mem[off];
    118 		scr->mem[off] = scr->cursortmp ^ 0x7700;
    119 	}
    120 #else 	/* PCDISPLAY_SOFTCURSOR */
    121 	struct pcdisplayscreen *scr = id;
    122 	int pos;
    123 
    124 	scr->vc_crow = row;
    125 	scr->vc_ccol = col;
    126 	scr->cursoron = on;
    127 
    128 	if (scr->active) {
    129 		if (!on)
    130 			pos = 0x3fff;
    131 		else
    132 			pos = scr->dispoffset / 2
    133 				+ row * scr->type->ncols + col;
    134 
    135 		pcdisplay_6845_write(scr->hdl, cursorh, pos >> 8);
    136 		pcdisplay_6845_write(scr->hdl, cursorl, pos);
    137 	}
    138 #endif	/* PCDISPLAY_SOFTCURSOR */
    139 }
    140 
    141 #if 0
    142 unsigned int
    143 pcdisplay_mapchar_simple(id, uni)
    144 	void *id;
    145 	int uni;
    146 {
    147 	if (uni < 128)
    148 		return (uni);
    149 
    150 	return (1); /* XXX ??? smiley */
    151 }
    152 #endif
    153 
    154 void
    155 pcdisplay_putchar(id, row, col, c, attr)
    156 	void *id;
    157 	int row, col;
    158 	u_int c;
    159 	long attr;
    160 {
    161 	struct pcdisplayscreen *scr = id;
    162 	bus_space_tag_t memt = scr->hdl->ph_memt;
    163 	bus_space_handle_t memh = scr->hdl->ph_memh;
    164 	int off;
    165 
    166 	off = row * scr->type->ncols + col;
    167 
    168 	if (scr->active)
    169 		bus_space_write_2(memt, memh, scr->dispoffset + off * 2,
    170 				  c | (attr << 8));
    171 	else
    172 		scr->mem[off] = c | (attr << 8);
    173 }
    174 
    175 void
    176 pcdisplay_copycols(id, row, srccol, dstcol, ncols)
    177 	void *id;
    178 	int row, srccol, dstcol, ncols;
    179 {
    180 	struct pcdisplayscreen *scr = id;
    181 	bus_space_tag_t memt = scr->hdl->ph_memt;
    182 	bus_space_handle_t memh = scr->hdl->ph_memh;
    183 	bus_size_t srcoff, dstoff;
    184 
    185 	srcoff = dstoff = row * scr->type->ncols;
    186 	srcoff += srccol;
    187 	dstoff += dstcol;
    188 
    189 	if (scr->active)
    190 		bus_space_copy_region_2(memt, memh,
    191 					scr->dispoffset + srcoff * 2,
    192 					memh, scr->dispoffset + dstoff * 2,
    193 					ncols);
    194 	else
    195 		memcpy(&scr->mem[dstoff], &scr->mem[srcoff], ncols * 2);
    196 }
    197 
    198 void
    199 pcdisplay_erasecols(id, row, startcol, ncols, fillattr)
    200 	void *id;
    201 	int row, startcol, ncols;
    202 	long fillattr;
    203 {
    204 	struct pcdisplayscreen *scr = id;
    205 	bus_space_tag_t memt = scr->hdl->ph_memt;
    206 	bus_space_handle_t memh = scr->hdl->ph_memh;
    207 	bus_size_t off;
    208 	u_int16_t val;
    209 	int i;
    210 
    211 	off = row * scr->type->ncols + startcol;
    212 
    213 	val = (fillattr << 8) | ' ';
    214 
    215 	if (scr->active)
    216 		bus_space_set_region_2(memt, memh, scr->dispoffset + off * 2,
    217 				       val, ncols);
    218 	else
    219 		for (i = 0; i < ncols; i++)
    220 			scr->mem[off + i] = val;
    221 }
    222 
    223 void
    224 pcdisplay_copyrows(id, srcrow, dstrow, nrows)
    225 	void *id;
    226 	int srcrow, dstrow, nrows;
    227 {
    228 	struct pcdisplayscreen *scr = id;
    229 	bus_space_tag_t memt = scr->hdl->ph_memt;
    230 	bus_space_handle_t memh = scr->hdl->ph_memh;
    231 	int ncols = scr->type->ncols;
    232 	bus_size_t srcoff, dstoff;
    233 
    234 	srcoff = srcrow * ncols + 0;
    235 	dstoff = dstrow * ncols + 0;
    236 
    237 	if (scr->active)
    238 		bus_space_copy_region_2(memt, memh,
    239 					scr->dispoffset + srcoff * 2,
    240 					memh, scr->dispoffset + dstoff * 2,
    241 					nrows * ncols);
    242 	else
    243 		memcpy(&scr->mem[dstoff], &scr->mem[srcoff],
    244 		      nrows * ncols * 2);
    245 }
    246 
    247 void
    248 pcdisplay_eraserows(id, startrow, nrows, fillattr)
    249 	void *id;
    250 	int startrow, nrows;
    251 	long fillattr;
    252 {
    253 	struct pcdisplayscreen *scr = id;
    254 	bus_space_tag_t memt = scr->hdl->ph_memt;
    255 	bus_space_handle_t memh = scr->hdl->ph_memh;
    256 	bus_size_t off, count;
    257 	u_int16_t val;
    258 	int i;
    259 
    260 	off = startrow * scr->type->ncols;
    261 	count = nrows * scr->type->ncols;
    262 
    263 	val = (fillattr << 8) | ' ';
    264 
    265 	if (scr->active)
    266 		bus_space_set_region_2(memt, memh, scr->dispoffset + off * 2,
    267 				       val, count);
    268 	else
    269 		for (i = 0; i < count; i++)
    270 			scr->mem[off + i] = val;
    271 }
    272