1 /* $NetBSD: pcdisplay_subr.c,v 1.33 2007/07/28 20:28:56 mjf Exp $ */
4 * Copyright (c) 1995, 1996 Carnegie-Mellon University.
7 * Author: Chris G. Demetriou
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.
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.
19 * Carnegie Mellon requests users of this software to return to
21 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
22 * School of Computer Science
23 * Carnegie Mellon University
24 * Pittsburgh PA 15213-3890
26 * any improvements or extensions that they make and grant Carnegie the
27 * rights to redistribute these changes.
30 #include <sys/cdefs.h>
31 __KERNEL_RCSID(0, "$NetBSD: pcdisplay_subr.c,v 1.33 2007/07/28 20:28:56 mjf Exp $");
33 #include "opt_wsmsgattrs.h" /* for WSDISPLAY_CUSTOM_OUTPUT */
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/device.h>
40 #include <dev/ic/mc6845reg.h>
41 #include <dev/ic/pcdisplayvar.h>
42 #include <dev/wscons/wsconsio.h>
44 #include <dev/wscons/wsdisplayvar.h>
47 pcdisplay_cursor_init(struct pcdisplayscreen
*scr
, int existing
)
49 #ifdef PCDISPLAY_SOFTCURSOR
51 bus_space_handle_t memh
;
54 pcdisplay_6845_write(scr
->hdl
, curstart
, 0x10);
55 pcdisplay_6845_write(scr
->hdl
, curend
, 0x10);
59 * This is the first screen. At this point, scr->mem is NULL
60 * (no backing store), so we can't use pcdisplay_cursor() to
63 memt
= scr
->hdl
->ph_memt
;
64 memh
= scr
->hdl
->ph_memh
;
65 off
= (scr
->cursorrow
* scr
->type
->ncols
+ scr
->cursorcol
) * 2
68 scr
->cursortmp
= bus_space_read_2(memt
, memh
, off
);
69 bus_space_write_2(memt
, memh
, off
, scr
->cursortmp
^ 0x7700);
74 * Firmware might not have initialized the cursor shape. Make
75 * sure there's something we can see.
76 * Don't touch the hardware if this is not the first screen.
79 pcdisplay_6845_write(scr
->hdl
, curstart
,
80 scr
->type
->fontheight
- 2);
81 pcdisplay_6845_write(scr
->hdl
, curend
,
82 scr
->type
->fontheight
- 1);
89 pcdisplay_cursor(void *id
, int on
, int row
, int col
)
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
;
97 /* Remove old cursor image */
99 off
= scr
->cursorrow
* scr
->type
->ncols
+ scr
->cursorcol
;
101 bus_space_write_2(memt
, memh
, scr
->dispoffset
+ off
* 2,
104 scr
->mem
[off
] = scr
->cursortmp
;
107 scr
->cursorrow
= row
;
108 scr
->cursorcol
= col
;
110 if ((scr
->cursoron
= on
) == 0)
113 off
= (scr
->cursorrow
* scr
->type
->ncols
+ scr
->cursorcol
);
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);
119 scr
->cursortmp
= scr
->mem
[off
];
120 scr
->mem
[off
] = scr
->cursortmp
^ 0x7700;
122 #else /* PCDISPLAY_SOFTCURSOR */
123 struct pcdisplayscreen
*scr
= id
;
126 scr
->cursorrow
= row
;
127 scr
->cursorcol
= col
;
134 pos
= scr
->dispoffset
/ 2
135 + row
* scr
->type
->ncols
+ col
;
137 pcdisplay_6845_write(scr
->hdl
, cursorh
, pos
>> 8);
138 pcdisplay_6845_write(scr
->hdl
, cursorl
, pos
);
140 #endif /* PCDISPLAY_SOFTCURSOR */
145 pcdisplay_mapchar_simple(void *id
, int uni
)
150 return (1); /* XXX ??? smiley */
155 pcdisplay_putchar(void *id
, int row
, int col
, unsigned int c
, long attr
)
157 struct pcdisplayscreen
*scr
= id
;
158 bus_space_tag_t memt
= scr
->hdl
->ph_memt
;
159 bus_space_handle_t memh
= scr
->hdl
->ph_memh
;
162 off
= row
* scr
->type
->ncols
+ col
;
164 /* check for bogus row and column sizes */
165 if (__predict_false(off
>= (scr
->type
->ncols
* scr
->type
->nrows
)))
169 bus_space_write_2(memt
, memh
, scr
->dispoffset
+ off
* 2,
172 scr
->mem
[off
] = c
| (attr
<< 8);
174 scr
->visibleoffset
= scr
->dispoffset
;
178 pcdisplay_copycols(void *id
, int row
, int srccol
, int dstcol
, int ncols
)
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
;
185 srcoff
= dstoff
= row
* scr
->type
->ncols
;
190 bus_space_copy_region_2(memt
, memh
,
191 scr
->dispoffset
+ srcoff
* 2,
192 memh
, scr
->dispoffset
+ dstoff
* 2,
195 memcpy(&scr
->mem
[dstoff
], &scr
->mem
[srcoff
], ncols
* 2);
199 pcdisplay_erasecols(void *id
, int row
, int startcol
, int ncols
, long fillattr
)
201 struct pcdisplayscreen
*scr
= id
;
202 bus_space_tag_t memt
= scr
->hdl
->ph_memt
;
203 bus_space_handle_t memh
= scr
->hdl
->ph_memh
;
208 off
= row
* scr
->type
->ncols
+ startcol
;
210 val
= (fillattr
<< 8) | ' ';
213 bus_space_set_region_2(memt
, memh
, scr
->dispoffset
+ off
* 2,
216 for (i
= 0; i
< ncols
; i
++)
217 scr
->mem
[off
+ i
] = val
;
221 pcdisplay_copyrows(void *id
, int srcrow
, int dstrow
, int nrows
)
223 struct pcdisplayscreen
*scr
= id
;
224 bus_space_tag_t memt
= scr
->hdl
->ph_memt
;
225 bus_space_handle_t memh
= scr
->hdl
->ph_memh
;
226 int ncols
= scr
->type
->ncols
;
227 bus_size_t srcoff
, dstoff
;
229 srcoff
= srcrow
* ncols
+ 0;
230 dstoff
= dstrow
* ncols
+ 0;
233 bus_space_copy_region_2(memt
, memh
,
234 scr
->dispoffset
+ srcoff
* 2,
235 memh
, scr
->dispoffset
+ dstoff
* 2,
238 memcpy(&scr
->mem
[dstoff
], &scr
->mem
[srcoff
],
243 pcdisplay_eraserows(void *id
, int startrow
, int nrows
, long fillattr
)
245 struct pcdisplayscreen
*scr
= id
;
246 bus_space_tag_t memt
= scr
->hdl
->ph_memt
;
247 bus_space_handle_t memh
= scr
->hdl
->ph_memh
;
248 bus_size_t off
, count
;
252 off
= startrow
* scr
->type
->ncols
;
253 count
= nrows
* scr
->type
->ncols
;
255 val
= (fillattr
<< 8) | ' ';
258 bus_space_set_region_2(memt
, memh
, scr
->dispoffset
+ off
* 2,
261 for (i
= 0; i
< count
; i
++)
262 scr
->mem
[off
+ i
] = val
;
265 #ifdef WSDISPLAY_CUSTOM_OUTPUT
267 pcdisplay_replaceattr(void *id
, long oldattr
, long newattr
)
269 struct pcdisplayscreen
*scr
= id
;
270 bus_space_tag_t memt
= scr
->hdl
->ph_memt
;
271 bus_space_handle_t memh
= scr
->hdl
->ph_memh
;
276 for (off
= 0; off
< scr
->type
->nrows
* scr
->type
->ncols
;
278 chardata
= bus_space_read_2(memt
, memh
,
279 scr
->dispoffset
+ off
* 2);
280 if ((long)(chardata
>> 8) == oldattr
)
281 bus_space_write_2(memt
, memh
,
282 scr
->dispoffset
+ off
* 2,
283 ((u_int16_t
)(newattr
<< 8)) |
284 (chardata
& 0x00FF));
287 for (off
= 0; off
< scr
->type
->nrows
* scr
->type
->ncols
;
289 chardata
= scr
->mem
[off
];
290 if ((long)(chardata
>> 8) == oldattr
)
291 scr
->mem
[off
] = ((u_int16_t
)(newattr
<< 8)) |
295 #endif /* WSDISPLAY_CUSTOM_OUTPUT */
298 pcdisplay_getwschar(struct pcdisplayscreen
*scr
, struct wsdisplay_char
*wschar
)
304 KASSERT(scr
!= NULL
&& wschar
!= NULL
);
306 off
= wschar
->row
* scr
->type
->ncols
+ wschar
->col
;
307 if (off
>= scr
->type
->ncols
* scr
->type
->nrows
)
311 chardata
= bus_space_read_2(scr
->hdl
->ph_memt
,
312 scr
->hdl
->ph_memh
, scr
->dispoffset
+ off
* 2);
314 chardata
= scr
->mem
[off
];
316 wschar
->letter
= (chardata
& 0x00FF);
318 attrbyte
= (chardata
& 0xFF00) >> 8;
319 if ((attrbyte
& 0x08)) wschar
->flags
|= WSDISPLAY_CHAR_BRIGHT
;
320 if ((attrbyte
& 0x80)) wschar
->flags
|= WSDISPLAY_CHAR_BLINK
;
321 wschar
->foreground
= attrbyte
& 0x07;
322 wschar
->background
= (attrbyte
>> 4) & 0x07;
328 pcdisplay_putwschar(struct pcdisplayscreen
*scr
, struct wsdisplay_char
*wschar
)
334 KASSERT(scr
!= NULL
&& wschar
!= NULL
);
336 off
= wschar
->row
* scr
->type
->ncols
+ wschar
->col
;
337 if (off
>= (scr
->type
->ncols
* scr
->type
->nrows
))
340 attrbyte
= wschar
->background
& 0x07;
341 if (wschar
->flags
& WSDISPLAY_CHAR_BLINK
) attrbyte
|= 0x08;
343 attrbyte
|= wschar
->foreground
& 0x07;
344 if (wschar
->flags
& WSDISPLAY_CHAR_BRIGHT
) attrbyte
|= 0x08;
345 chardata
= (attrbyte
<< 8) | wschar
->letter
;
348 bus_space_write_2(scr
->hdl
->ph_memt
, scr
->hdl
->ph_memh
,
349 scr
->dispoffset
+ off
* 2, chardata
);
351 scr
->mem
[off
] = chardata
;