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