xref: /openbsd-src/sys/dev/ic/pcdisplay_subr.c (revision a28daedfc357b214be5c701aa8ba8adb29a7f1c2)
1 /* $OpenBSD: pcdisplay_subr.c,v 1.7 2006/11/29 19:11:15 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 void
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;
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 #else 	/* PCDISPLAY_SOFTCURSOR */
123 	struct pcdisplayscreen *scr = id;
124 	int pos;
125 
126 	scr->vc_crow = row;
127 	scr->vc_ccol = col;
128 	scr->cursoron = on;
129 
130 	if (scr->active) {
131 		if (!on)
132 			pos = 0x1010;
133 		else
134 			pos = scr->dispoffset / 2
135 				+ row * scr->type->ncols + col;
136 
137 		pcdisplay_6845_write(scr->hdl, cursorh, pos >> 8);
138 		pcdisplay_6845_write(scr->hdl, cursorl, pos);
139 	}
140 #endif	/* PCDISPLAY_SOFTCURSOR */
141 }
142 
143 #if 0
144 unsigned int
145 pcdisplay_mapchar_simple(id, uni)
146 	void *id;
147 	int uni;
148 {
149 	if (uni < 128)
150 		return (uni);
151 
152 	return (1); /* XXX ??? smiley */
153 }
154 #endif
155 
156 void
157 pcdisplay_putchar(id, row, col, c, attr)
158 	void *id;
159 	int row, col;
160 	u_int c;
161 	long attr;
162 {
163 	struct pcdisplayscreen *scr = id;
164 	bus_space_tag_t memt = scr->hdl->ph_memt;
165 	bus_space_handle_t memh = scr->hdl->ph_memh;
166 	int off;
167 
168 	off = row * scr->type->ncols + col;
169 
170 	if (scr->active)
171 		bus_space_write_2(memt, memh, scr->dispoffset + off * 2,
172 				  c | (attr << 8));
173 	else
174 		scr->mem[off] = c | (attr << 8);
175 }
176 
177 int
178 pcdisplay_getchar(id, row, col, cell)
179 	void *id;
180 	int row, col;
181 	struct wsdisplay_charcell *cell;
182 {
183 	struct pcdisplayscreen *scr = id;
184 	bus_space_tag_t memt = scr->hdl->ph_memt;
185 	bus_space_handle_t memh = scr->hdl->ph_memh;
186 	int off;
187 	u_int16_t data;
188 
189 	off = row * scr->type->ncols + col;
190 	/* XXX bounds check? */
191 
192 	if (scr->active)
193 		data = (bus_space_read_2(memt, memh,
194 					scr->dispoffset + off * 2));
195 	else
196 		data = (scr->mem[off]);
197 
198 	cell->uc = data & 0xff;
199 	cell->attr = data >> 8;
200 
201 	return (0);
202 }
203 
204 void
205 pcdisplay_copycols(id, row, srccol, dstcol, ncols)
206 	void *id;
207 	int row, srccol, dstcol, ncols;
208 {
209 	struct pcdisplayscreen *scr = id;
210 	bus_space_tag_t memt = scr->hdl->ph_memt;
211 	bus_space_handle_t memh = scr->hdl->ph_memh;
212 	bus_size_t srcoff, dstoff;
213 
214 	srcoff = dstoff = row * scr->type->ncols;
215 	srcoff += srccol;
216 	dstoff += dstcol;
217 
218 	if (scr->active)
219 		bus_space_copy_2(memt, memh,
220 					scr->dispoffset + srcoff * 2,
221 					memh, scr->dispoffset + dstoff * 2,
222 					ncols);
223 	else
224 		bcopy(&scr->mem[srcoff], &scr->mem[dstoff], ncols * 2);
225 }
226 
227 void
228 pcdisplay_erasecols(id, row, startcol, ncols, fillattr)
229 	void *id;
230 	int row, startcol, ncols;
231 	long fillattr;
232 {
233 	struct pcdisplayscreen *scr = id;
234 	bus_space_tag_t memt = scr->hdl->ph_memt;
235 	bus_space_handle_t memh = scr->hdl->ph_memh;
236 	bus_size_t off;
237 	u_int16_t val;
238 	int i;
239 
240 	off = row * scr->type->ncols + startcol;
241 
242 	val = (fillattr << 8) | ' ';
243 
244 	if (scr->active)
245 		bus_space_set_region_2(memt, memh, scr->dispoffset + off * 2,
246 				       val, ncols);
247 	else
248 		for (i = 0; i < ncols; i++)
249 			scr->mem[off + i] = val;
250 }
251 
252 void
253 pcdisplay_copyrows(id, srcrow, dstrow, nrows)
254 	void *id;
255 	int srcrow, dstrow, nrows;
256 {
257 	struct pcdisplayscreen *scr = id;
258 	bus_space_tag_t memt = scr->hdl->ph_memt;
259 	bus_space_handle_t memh = scr->hdl->ph_memh;
260 	int ncols = scr->type->ncols;
261 	bus_size_t srcoff, dstoff;
262 
263 	srcoff = srcrow * ncols + 0;
264 	dstoff = dstrow * ncols + 0;
265 
266 	if (scr->active)
267 		bus_space_copy_2(memt, memh,
268 					scr->dispoffset + srcoff * 2,
269 					memh, scr->dispoffset + dstoff * 2,
270 					nrows * ncols);
271 	else
272 		bcopy(&scr->mem[srcoff], &scr->mem[dstoff],
273 		      nrows * ncols * 2);
274 }
275 
276 void
277 pcdisplay_eraserows(id, startrow, nrows, fillattr)
278 	void *id;
279 	int startrow, nrows;
280 	long fillattr;
281 {
282 	struct pcdisplayscreen *scr = id;
283 	bus_space_tag_t memt = scr->hdl->ph_memt;
284 	bus_space_handle_t memh = scr->hdl->ph_memh;
285 	bus_size_t off, count, n;
286 	u_int16_t val;
287 
288 	off = startrow * scr->type->ncols;
289 	count = nrows * scr->type->ncols;
290 
291 	val = (fillattr << 8) | ' ';
292 
293 	if (scr->active)
294 		bus_space_set_region_2(memt, memh, scr->dispoffset + off * 2,
295 				       val, count);
296 	else
297 		for (n = 0; n < count; n++)
298 			scr->mem[off + n] = val;
299 }
300