vga.c revision 1.2 1 1.2 drochner /* $NetBSD: vga.c,v 1.2 1998/04/07 16:35:42 drochner Exp $ */
2 1.1 drochner
3 1.1 drochner /*
4 1.1 drochner * Copyright (c) 1995, 1996 Carnegie-Mellon University.
5 1.1 drochner * All rights reserved.
6 1.1 drochner *
7 1.1 drochner * Author: Chris G. Demetriou
8 1.1 drochner *
9 1.1 drochner * Permission to use, copy, modify and distribute this software and
10 1.1 drochner * its documentation is hereby granted, provided that both the copyright
11 1.1 drochner * notice and this permission notice appear in all copies of the
12 1.1 drochner * software, derivative works or modified versions, and any portions
13 1.1 drochner * thereof, and that both notices appear in supporting documentation.
14 1.1 drochner *
15 1.1 drochner * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
16 1.1 drochner * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
17 1.1 drochner * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
18 1.1 drochner *
19 1.1 drochner * Carnegie Mellon requests users of this software to return to
20 1.1 drochner *
21 1.1 drochner * Software Distribution Coordinator or Software.Distribution (at) CS.CMU.EDU
22 1.1 drochner * School of Computer Science
23 1.1 drochner * Carnegie Mellon University
24 1.1 drochner * Pittsburgh PA 15213-3890
25 1.1 drochner *
26 1.1 drochner * any improvements or extensions that they make and grant Carnegie the
27 1.1 drochner * rights to redistribute these changes.
28 1.1 drochner */
29 1.1 drochner
30 1.1 drochner #include <sys/param.h>
31 1.1 drochner #include <sys/systm.h>
32 1.1 drochner #include <sys/kernel.h>
33 1.1 drochner #include <sys/device.h>
34 1.1 drochner #include <sys/malloc.h>
35 1.1 drochner #include <sys/queue.h>
36 1.1 drochner #include <machine/bus.h>
37 1.1 drochner
38 1.1 drochner #include <dev/isa/isavar.h>
39 1.1 drochner #include <dev/isa/isareg.h>
40 1.1 drochner
41 1.1 drochner #include <dev/wscons/wsdisplayvar.h>
42 1.1 drochner #include <dev/wscons/wsconsio.h>
43 1.1 drochner
44 1.1 drochner #include <dev/ic/vgareg.h>
45 1.1 drochner #include <dev/ic/vgavar.h>
46 1.1 drochner
47 1.1 drochner struct vgascreen {
48 1.1 drochner LIST_ENTRY(vgascreen) next;
49 1.1 drochner
50 1.1 drochner struct vga_config *cfg;
51 1.1 drochner
52 1.1 drochner const struct wsscreen_descr *type;
53 1.1 drochner
54 1.1 drochner u_int16_t *mem; /* backing store for contents */
55 1.1 drochner /* videostate */
56 1.1 drochner int fontset;
57 1.1 drochner /* font data */
58 1.1 drochner /* palette */
59 1.1 drochner
60 1.1 drochner int cursoron; /* cursor displayed? */
61 1.1 drochner int vc_ccol, vc_crow; /* current cursor position */
62 1.1 drochner
63 1.1 drochner char vc_so; /* in standout mode? */
64 1.1 drochner char vc_at; /* normal attributes */
65 1.1 drochner char vc_so_at; /* standout attributes */
66 1.1 drochner };
67 1.1 drochner
68 1.1 drochner struct vga_config {
69 1.1 drochner struct vga_handle hdl;
70 1.1 drochner
71 1.1 drochner int nscreens;
72 1.1 drochner LIST_HEAD(, vgascreen) screens;
73 1.1 drochner struct vgascreen *active; /* current display */
74 1.1 drochner };
75 1.1 drochner
76 1.1 drochner static int vgaconsole, vga_console_type, vga_console_attached;
77 1.1 drochner static struct vgascreen vga_console_screen;
78 1.1 drochner static struct vga_config vga_console_vc;
79 1.1 drochner
80 1.1 drochner void vga_init_screen __P((struct vgascreen *, const struct wsscreen_descr *,
81 1.1 drochner int));
82 1.1 drochner void vga_init __P((struct vga_config *, bus_space_tag_t,
83 1.1 drochner bus_space_tag_t));
84 1.1 drochner
85 1.1 drochner static void vga_cursor __P((void *, int, int, int));
86 1.1 drochner static void vga_putstr __P((void *, int, int, char *, int));
87 1.1 drochner static void vga_copycols __P((void *, int, int, int,int));
88 1.1 drochner static void vga_erasecols __P((void *, int, int, int));
89 1.1 drochner static void vga_copyrows __P((void *, int, int, int));
90 1.1 drochner static void vga_eraserows __P((void *, int, int));
91 1.1 drochner
92 1.1 drochner const struct wsdisplay_emulops vga_emulops = {
93 1.1 drochner vga_cursor,
94 1.1 drochner vga_putstr,
95 1.1 drochner vga_copycols,
96 1.1 drochner vga_erasecols,
97 1.1 drochner vga_copyrows,
98 1.1 drochner vga_eraserows,
99 1.1 drochner };
100 1.1 drochner
101 1.1 drochner const struct wsscreen_descr vga_stdscreen = {
102 1.1 drochner "80x25", 80, 25,
103 1.1 drochner &vga_emulops,
104 1.1 drochner 8, 16
105 1.1 drochner };
106 1.1 drochner
107 1.1 drochner const struct wsscreen_descr vga_50lscreen = {
108 1.1 drochner "80x50", 80, 50,
109 1.1 drochner &vga_emulops,
110 1.1 drochner 8, 8
111 1.1 drochner };
112 1.1 drochner
113 1.2 drochner const struct wsscreen_descr *_vga_scrlist[] = {
114 1.1 drochner &vga_stdscreen,
115 1.1 drochner &vga_50lscreen,
116 1.1 drochner /* XXX other formats, graphics screen? */
117 1.1 drochner };
118 1.1 drochner
119 1.1 drochner struct wsscreen_list vga_screenlist = {
120 1.2 drochner sizeof(_vga_scrlist) / sizeof(struct wsscreen_descr *), _vga_scrlist
121 1.1 drochner };
122 1.1 drochner
123 1.1 drochner static int vga_ioctl __P((void *, u_long, caddr_t, int, struct proc *));
124 1.1 drochner static int vga_mmap __P((void *, off_t, int));
125 1.1 drochner static int vga_alloc_screen __P((void *, const struct wsscreen_descr *,
126 1.1 drochner void **, int *, int *));
127 1.1 drochner static void vga_free_screen __P((void *, void *));
128 1.1 drochner static void vga_show_screen __P((void *, void *));
129 1.1 drochner static int vga_load_font __P((void *, void *, int, int, int, void *));
130 1.1 drochner
131 1.1 drochner const struct wsdisplay_accessops vga_accessops = {
132 1.1 drochner vga_ioctl,
133 1.1 drochner vga_mmap,
134 1.1 drochner vga_alloc_screen,
135 1.1 drochner vga_free_screen,
136 1.1 drochner vga_show_screen,
137 1.1 drochner vga_load_font
138 1.1 drochner };
139 1.1 drochner
140 1.1 drochner /*
141 1.1 drochner * The following functions implement back-end configuration grabbing
142 1.1 drochner * and attachment.
143 1.1 drochner */
144 1.1 drochner int
145 1.1 drochner vga_common_probe(iot, memt)
146 1.1 drochner bus_space_tag_t iot, memt;
147 1.1 drochner {
148 1.1 drochner bus_space_handle_t ioh_vga, ioh_6845, memh;
149 1.1 drochner u_int8_t mor;
150 1.1 drochner u_int16_t vgadata;
151 1.1 drochner int gotio_vga, gotio_6845, gotmem, mono, rv;
152 1.1 drochner int dispoffset;
153 1.1 drochner
154 1.1 drochner gotio_vga = gotio_6845 = gotmem = rv = 0;
155 1.1 drochner
156 1.1 drochner if (bus_space_map(iot, 0x3c0, 0x10, 0, &ioh_vga))
157 1.1 drochner goto bad;
158 1.1 drochner gotio_vga = 1;
159 1.1 drochner
160 1.1 drochner /* read "misc output register" */
161 1.1 drochner mor = bus_space_read_1(iot, ioh_vga, 0xc);
162 1.1 drochner mono = !(mor & 1);
163 1.1 drochner
164 1.1 drochner if (bus_space_map(iot, (mono ? 0x3b0 : 0x3d0), 0x10, 0, &ioh_6845))
165 1.1 drochner goto bad;
166 1.1 drochner gotio_6845 = 1;
167 1.1 drochner
168 1.1 drochner if (bus_space_map(memt, 0xa0000, 0x20000, 0, &memh))
169 1.1 drochner goto bad;
170 1.1 drochner gotmem = 1;
171 1.1 drochner
172 1.1 drochner dispoffset = (mono ? 0x10000 : 0x18000);
173 1.1 drochner
174 1.1 drochner vgadata = bus_space_read_2(memt, memh, dispoffset);
175 1.1 drochner bus_space_write_2(memt, memh, dispoffset, 0xa55a);
176 1.1 drochner rv = (bus_space_read_2(memt, memh, dispoffset) == 0xa55a);
177 1.1 drochner bus_space_write_2(memt, memh, dispoffset, vgadata);
178 1.1 drochner
179 1.1 drochner bad:
180 1.1 drochner if (gotio_vga)
181 1.1 drochner bus_space_unmap(iot, ioh_vga, 0x10);
182 1.1 drochner if (gotio_6845)
183 1.1 drochner bus_space_unmap(iot, ioh_6845, 0x10);
184 1.1 drochner if (gotmem)
185 1.1 drochner bus_space_unmap(memt, memh, 0x20000);
186 1.1 drochner
187 1.1 drochner return (rv);
188 1.1 drochner }
189 1.1 drochner
190 1.1 drochner void
191 1.1 drochner vga_init_screen(scr, type, existing)
192 1.1 drochner struct vgascreen *scr;
193 1.1 drochner const struct wsscreen_descr *type;
194 1.1 drochner int existing;
195 1.1 drochner {
196 1.1 drochner struct vga_config *vc = scr->cfg;
197 1.1 drochner int cpos = 0;
198 1.1 drochner
199 1.1 drochner scr->type = type;
200 1.1 drochner
201 1.1 drochner if (existing) {
202 1.1 drochner cpos = vga_6845_read(&vc->hdl, cursorh) << 8;
203 1.1 drochner cpos |= vga_6845_read(&vc->hdl, cursorl);
204 1.1 drochner
205 1.1 drochner /* make sure we have a valid cursor position */
206 1.1 drochner if (cpos < 0 || cpos >= type->nrows * type->ncols)
207 1.1 drochner cpos = 0;
208 1.1 drochner }
209 1.1 drochner
210 1.1 drochner scr->vc_crow = cpos / type->ncols;
211 1.1 drochner scr->vc_ccol = cpos % type->ncols;
212 1.1 drochner
213 1.1 drochner scr->vc_so = 0;
214 1.1 drochner #ifdef __alpha__
215 1.1 drochner /*
216 1.1 drochner * XXX DEC HAS SWITCHED THE CODES FOR BLUE AND RED!!!
217 1.1 drochner * XXX Therefore, though the comments say "blue bg", the code uses
218 1.1 drochner * XXX the value for a red background!
219 1.1 drochner */
220 1.1 drochner scr->vc_at = 0x40 | 0x0f; /* blue bg|white fg */
221 1.1 drochner scr->vc_so_at = 0x40 | 0x0f | 0x80; /* blue bg|white fg|blink */
222 1.1 drochner #else
223 1.1 drochner scr->vc_at = 0x00 | 0xf; /* black bg|white fg */
224 1.1 drochner scr->vc_so_at = 0x00 | 0xf | 0x80; /* black bg|white fg|blink */
225 1.1 drochner #endif
226 1.1 drochner
227 1.1 drochner scr->mem = NULL;
228 1.1 drochner if (type == &vga_stdscreen) /* XXX do it better! */
229 1.1 drochner scr->fontset = 0;
230 1.1 drochner else
231 1.1 drochner scr->fontset = 1;
232 1.1 drochner
233 1.1 drochner vc->nscreens++;
234 1.1 drochner LIST_INSERT_HEAD(&vc->screens, scr, next);
235 1.1 drochner }
236 1.1 drochner
237 1.1 drochner void
238 1.1 drochner vga_init(vc, iot, memt)
239 1.1 drochner struct vga_config *vc;
240 1.1 drochner bus_space_tag_t iot, memt;
241 1.1 drochner {
242 1.1 drochner struct vga_handle *vh = &vc->hdl;
243 1.1 drochner u_int8_t mor;
244 1.1 drochner
245 1.1 drochner vh->vh_iot = iot;
246 1.1 drochner vh->vh_memt = memt;
247 1.1 drochner
248 1.1 drochner if (bus_space_map(vh->vh_iot, 0x3c0, 0x10, 0, &vh->vh_ioh_vga))
249 1.1 drochner panic("vga_common_setup: couldn't map vga io");
250 1.1 drochner
251 1.1 drochner /* read "misc output register" */
252 1.1 drochner mor = bus_space_read_1(vh->vh_iot, vh->vh_ioh_vga, 0xc);
253 1.1 drochner vh->mono = !(mor & 1);
254 1.1 drochner
255 1.1 drochner if (bus_space_map(vh->vh_iot, (vh->mono ? 0x3b0 : 0x3d0), 0x10, 0,
256 1.1 drochner &vh->vh_ioh_6845))
257 1.1 drochner panic("vga_common_setup: couldn't map 6845 io");
258 1.1 drochner
259 1.1 drochner if (bus_space_map(vh->vh_memt, 0xa0000, 0x20000, 0, &vh->vh_allmemh))
260 1.1 drochner panic("vga_common_setup: couldn't map memory");
261 1.1 drochner
262 1.1 drochner if (bus_space_subregion(vh->vh_memt, vh->vh_allmemh,
263 1.1 drochner (vh->mono ? 0x10000 : 0x18000), 0x8000,
264 1.1 drochner &vh->vh_memh))
265 1.1 drochner panic("vga_common_setup: mem subrange failed");
266 1.1 drochner
267 1.1 drochner vc->nscreens = 0;
268 1.1 drochner LIST_INIT(&vc->screens);
269 1.1 drochner vc->active = NULL;
270 1.1 drochner }
271 1.1 drochner
272 1.1 drochner void
273 1.1 drochner vga_common_attach(self, iot, memt, type)
274 1.1 drochner struct device *self;
275 1.1 drochner bus_space_tag_t iot, memt;
276 1.1 drochner int type;
277 1.1 drochner {
278 1.1 drochner int console;
279 1.1 drochner struct vga_config *vc;
280 1.1 drochner struct wsemuldisplaydev_attach_args aa;
281 1.1 drochner
282 1.1 drochner console = vga_is_console(iot, type);
283 1.1 drochner
284 1.1 drochner if (console) {
285 1.1 drochner vc = &vga_console_vc;
286 1.1 drochner vga_console_attached = 1;
287 1.1 drochner } else {
288 1.1 drochner vc = malloc(sizeof(struct vga_config), M_DEVBUF, M_WAITOK);
289 1.1 drochner vga_init(vc, iot, memt);
290 1.1 drochner }
291 1.1 drochner
292 1.1 drochner aa.console = console;
293 1.1 drochner aa.scrdata = &vga_screenlist;
294 1.1 drochner aa.accessops = &vga_accessops;
295 1.1 drochner aa.accesscookie = vc;
296 1.1 drochner
297 1.1 drochner config_found(self, &aa, wsemuldisplaydevprint);
298 1.1 drochner }
299 1.1 drochner
300 1.1 drochner int
301 1.1 drochner vga_cnattach(iot, memt, type, check)
302 1.1 drochner bus_space_tag_t iot, memt;
303 1.1 drochner int type, check;
304 1.1 drochner {
305 1.1 drochner if (check && !vga_common_probe(iot, memt))
306 1.1 drochner return (ENXIO);
307 1.1 drochner
308 1.1 drochner /* set up bus-independent VGA configuration */
309 1.1 drochner vga_init(&vga_console_vc, iot, memt);
310 1.1 drochner vga_console_screen.cfg = &vga_console_vc;
311 1.1 drochner vga_init_screen(&vga_console_screen, &vga_stdscreen, 1);
312 1.1 drochner
313 1.1 drochner vga_console_vc.active = &vga_console_screen;
314 1.1 drochner
315 1.1 drochner wsdisplay_cnattach(&vga_stdscreen, &vga_console_screen,
316 1.1 drochner vga_console_screen.vc_ccol,
317 1.1 drochner vga_console_screen.vc_crow);
318 1.1 drochner
319 1.1 drochner vgaconsole = 1;
320 1.1 drochner vga_console_type = type;
321 1.1 drochner return (0);
322 1.1 drochner }
323 1.1 drochner
324 1.1 drochner int
325 1.1 drochner vga_is_console(iot, type)
326 1.1 drochner bus_space_tag_t iot;
327 1.1 drochner int type;
328 1.1 drochner {
329 1.1 drochner if (vgaconsole &&
330 1.1 drochner !vga_console_attached &&
331 1.1 drochner iot == vga_console_vc.hdl.vh_iot &&
332 1.1 drochner (vga_console_type == -1 || (type == vga_console_type)))
333 1.1 drochner return (1);
334 1.1 drochner return (0);
335 1.1 drochner }
336 1.1 drochner
337 1.1 drochner int
338 1.1 drochner vga_ioctl(v, cmd, data, flag, p)
339 1.1 drochner void *v;
340 1.1 drochner u_long cmd;
341 1.1 drochner caddr_t data;
342 1.1 drochner int flag;
343 1.1 drochner struct proc *p;
344 1.1 drochner {
345 1.1 drochner #if 0
346 1.1 drochner struct vga_config *vc = v;
347 1.1 drochner #endif
348 1.1 drochner
349 1.1 drochner switch (cmd) {
350 1.1 drochner #if 0
351 1.1 drochner case WSDISPLAYIO_GTYPE:
352 1.1 drochner *(int *)data = vc->vc_type;
353 1.1 drochner /* XXX should get detailed hardware information here */
354 1.1 drochner return 0;
355 1.1 drochner #endif
356 1.1 drochner case WSDISPLAYIO_GINFO:
357 1.1 drochner case WSDISPLAYIO_GETCMAP:
358 1.1 drochner case WSDISPLAYIO_PUTCMAP:
359 1.1 drochner case WSDISPLAYIO_GVIDEO:
360 1.1 drochner case WSDISPLAYIO_SVIDEO:
361 1.1 drochner case WSDISPLAYIO_GCURPOS:
362 1.1 drochner case WSDISPLAYIO_SCURPOS:
363 1.1 drochner case WSDISPLAYIO_GCURMAX:
364 1.1 drochner case WSDISPLAYIO_GCURSOR:
365 1.1 drochner case WSDISPLAYIO_SCURSOR:
366 1.1 drochner /* NONE of these operations are by the generic VGA driver. */
367 1.1 drochner return ENOTTY;
368 1.1 drochner }
369 1.1 drochner return -1;
370 1.1 drochner }
371 1.1 drochner
372 1.1 drochner static int
373 1.1 drochner vga_mmap(v, offset, prot)
374 1.1 drochner void *v;
375 1.1 drochner off_t offset;
376 1.1 drochner int prot;
377 1.1 drochner {
378 1.1 drochner
379 1.1 drochner /* XXX */
380 1.1 drochner return -1;
381 1.1 drochner }
382 1.1 drochner
383 1.1 drochner int
384 1.1 drochner vga_alloc_screen(v, type, cookiep, curxp, curyp)
385 1.1 drochner void *v;
386 1.1 drochner const struct wsscreen_descr *type;
387 1.1 drochner void **cookiep;
388 1.1 drochner int *curxp, *curyp;
389 1.1 drochner {
390 1.1 drochner struct vga_config *vc = v;
391 1.1 drochner struct vgascreen *scr;
392 1.1 drochner
393 1.1 drochner if (vc->nscreens == 1) {
394 1.1 drochner /*
395 1.1 drochner * When allocating the second screen, get backing store
396 1.1 drochner * for the first one too.
397 1.1 drochner * XXX We could be more clever and use video RAM.
398 1.1 drochner */
399 1.1 drochner vc->screens.lh_first->mem =
400 1.1 drochner malloc(type->ncols * type->nrows * 2, M_DEVBUF, M_WAITOK);
401 1.1 drochner }
402 1.1 drochner
403 1.1 drochner scr = malloc(sizeof(struct vgascreen), M_DEVBUF, M_WAITOK);
404 1.1 drochner scr->cfg = vc;
405 1.1 drochner vga_init_screen(scr, type, vc->nscreens == 0);
406 1.1 drochner
407 1.1 drochner if (vc->nscreens == 1)
408 1.1 drochner vc->active = scr;
409 1.1 drochner else {
410 1.1 drochner scr->mem = malloc(type->ncols * type->nrows * 2,
411 1.1 drochner M_DEVBUF, M_WAITOK);
412 1.1 drochner vga_eraserows(scr, 0, type->nrows);
413 1.1 drochner }
414 1.1 drochner
415 1.1 drochner *cookiep = scr;
416 1.1 drochner *curxp = scr->vc_ccol;
417 1.1 drochner *curyp = scr->vc_crow;
418 1.1 drochner
419 1.1 drochner return (0);
420 1.1 drochner }
421 1.1 drochner
422 1.1 drochner void
423 1.1 drochner vga_free_screen(v, cookie)
424 1.1 drochner void *v;
425 1.1 drochner void *cookie;
426 1.1 drochner {
427 1.1 drochner struct vgascreen *vs = cookie;
428 1.1 drochner
429 1.1 drochner LIST_REMOVE(vs, next);
430 1.1 drochner if (vs != &vga_console_screen)
431 1.1 drochner free(vs, M_DEVBUF);
432 1.1 drochner else
433 1.1 drochner panic("vga_free_screen: console");
434 1.1 drochner }
435 1.1 drochner
436 1.1 drochner void
437 1.1 drochner vga_show_screen(v, cookie)
438 1.1 drochner void *v;
439 1.1 drochner void *cookie;
440 1.1 drochner {
441 1.1 drochner struct vgascreen *scr = cookie;
442 1.1 drochner struct vga_config *vc = scr->cfg;
443 1.1 drochner struct vga_handle *vh = &vc->hdl;
444 1.1 drochner const struct wsscreen_descr *type = scr->type;
445 1.1 drochner int i, row, col, pos;
446 1.1 drochner
447 1.1 drochner if (scr == vc->active)
448 1.1 drochner return;
449 1.1 drochner
450 1.1 drochner for (i = 0; i < vc->active->type->ncols * vc->active->type->nrows; i++)
451 1.1 drochner vc->active->mem[i] = bus_space_read_2(vh->vh_memt, vh->vh_memh,
452 1.1 drochner i * 2);
453 1.1 drochner
454 1.1 drochner if (vc->active->type != type)
455 1.1 drochner vga_setscreentype(&vc->hdl, type);
456 1.1 drochner if (vc->active->fontset != scr->fontset)
457 1.1 drochner vga_setfontset(&vc->hdl, scr->fontset);
458 1.1 drochner /* swich colours */
459 1.1 drochner
460 1.1 drochner for (i = 0; i < type->ncols * type->nrows; i++)
461 1.1 drochner bus_space_write_2(vh->vh_memt, vh->vh_memh, i * 2, scr->mem[i]);
462 1.1 drochner
463 1.1 drochner col = scr->vc_ccol;
464 1.1 drochner row = scr->vc_crow;
465 1.1 drochner
466 1.1 drochner if (!scr->cursoron) {
467 1.1 drochner /* XXX disable cursor how??? */
468 1.1 drochner row = col = -1;
469 1.1 drochner }
470 1.1 drochner
471 1.1 drochner pos = row * type->ncols + col;
472 1.1 drochner
473 1.1 drochner vga_6845_write(vh, cursorh, pos >> 8);
474 1.1 drochner vga_6845_write(vh, cursorl, pos);
475 1.1 drochner
476 1.1 drochner vc->active = scr;
477 1.1 drochner }
478 1.1 drochner
479 1.1 drochner static int
480 1.1 drochner vga_load_font(v, cookie, first, num, stride, data)
481 1.1 drochner void *v;
482 1.1 drochner void *cookie;
483 1.1 drochner int first, num, stride;
484 1.1 drochner void *data;
485 1.1 drochner {
486 1.1 drochner struct vgascreen *scr = cookie;
487 1.1 drochner struct vga_config *vc = scr->cfg;
488 1.1 drochner
489 1.1 drochner if (stride != 1)
490 1.1 drochner return (EINVAL); /* XXX 1 byte per line */
491 1.1 drochner
492 1.1 drochner vga_loadchars(&vc->hdl, scr->fontset, first, num,
493 1.1 drochner scr->type->fontheight, data);
494 1.1 drochner return (0);
495 1.1 drochner }
496 1.1 drochner
497 1.1 drochner /*
498 1.1 drochner * The following functions implement the MI ANSI terminal emulation on
499 1.1 drochner * a VGA display.
500 1.1 drochner */
501 1.1 drochner static void
502 1.1 drochner vga_cursor(id, on, row, col)
503 1.1 drochner void *id;
504 1.1 drochner int on, row, col;
505 1.1 drochner {
506 1.1 drochner struct vgascreen *scr = id;
507 1.1 drochner struct vga_config *vc = scr->cfg;
508 1.1 drochner int pos;
509 1.1 drochner
510 1.1 drochner #if 0
511 1.1 drochner printf("vga_cursor: %d %d\n", row, col);
512 1.1 drochner #endif
513 1.1 drochner scr->vc_crow = row;
514 1.1 drochner scr->vc_ccol = col;
515 1.1 drochner scr->cursoron = on;
516 1.1 drochner
517 1.1 drochner if (scr == vc->active) {
518 1.1 drochner if (!on) {
519 1.1 drochner /* XXX disable cursor how??? */
520 1.1 drochner row = col = -1;
521 1.1 drochner }
522 1.1 drochner
523 1.1 drochner pos = row * scr->type->ncols + col;
524 1.1 drochner
525 1.1 drochner vga_6845_write(&vc->hdl, cursorh, pos >> 8);
526 1.1 drochner vga_6845_write(&vc->hdl, cursorl, pos);
527 1.1 drochner }
528 1.1 drochner }
529 1.1 drochner
530 1.1 drochner static void
531 1.1 drochner vga_putstr(id, row, col, cp, len)
532 1.1 drochner void *id;
533 1.1 drochner int row, col;
534 1.1 drochner char *cp;
535 1.1 drochner int len;
536 1.1 drochner {
537 1.1 drochner struct vgascreen *scr = id;
538 1.1 drochner struct vga_config *vc = scr->cfg;
539 1.1 drochner bus_space_tag_t memt = vc->hdl.vh_memt;
540 1.1 drochner bus_space_handle_t memh = vc->hdl.vh_memh;
541 1.1 drochner int i, off;
542 1.1 drochner char attr;
543 1.1 drochner
544 1.1 drochner off = row * scr->type->ncols + col;
545 1.1 drochner attr = (scr->vc_so ? scr->vc_so_at : scr->vc_at);
546 1.1 drochner
547 1.1 drochner if (scr == vc->active) {
548 1.1 drochner off *= 2;
549 1.1 drochner
550 1.1 drochner for (i = 0; i < len; i++, cp++, off += 2) {
551 1.1 drochner bus_space_write_1(memt, memh, off, *cp);
552 1.1 drochner bus_space_write_1(memt, memh, off + 1, attr);
553 1.1 drochner }
554 1.1 drochner } else {
555 1.1 drochner u_int16_t *m = &scr->mem[off];
556 1.1 drochner
557 1.1 drochner for (i = 0; i < len; i++, cp++)
558 1.1 drochner *m++ = *cp | (attr << 8);
559 1.1 drochner }
560 1.1 drochner }
561 1.1 drochner
562 1.1 drochner static void
563 1.1 drochner vga_copycols(id, row, srccol, dstcol, ncols)
564 1.1 drochner void *id;
565 1.1 drochner int row, srccol, dstcol, ncols;
566 1.1 drochner {
567 1.1 drochner struct vgascreen *scr = id;
568 1.1 drochner struct vga_config *vc = scr->cfg;
569 1.1 drochner bus_space_tag_t memt = vc->hdl.vh_memt;
570 1.1 drochner bus_space_handle_t memh = vc->hdl.vh_memh;
571 1.1 drochner bus_size_t srcoff, dstoff;
572 1.1 drochner
573 1.1 drochner srcoff = dstoff = row * scr->type->ncols;
574 1.1 drochner srcoff += srccol;
575 1.1 drochner dstoff += dstcol;
576 1.1 drochner
577 1.1 drochner if (scr == vc->active)
578 1.1 drochner bus_space_copy_region_2(memt, memh, srcoff * 2,
579 1.1 drochner memh, dstoff * 2, ncols);
580 1.1 drochner else
581 1.1 drochner bcopy(&scr->mem[srcoff], &scr->mem[dstoff], ncols * 2);
582 1.1 drochner }
583 1.1 drochner
584 1.1 drochner static void
585 1.1 drochner vga_erasecols(id, row, startcol, ncols)
586 1.1 drochner void *id;
587 1.1 drochner int row, startcol, ncols;
588 1.1 drochner {
589 1.1 drochner struct vgascreen *scr = id;
590 1.1 drochner struct vga_config *vc = scr->cfg;
591 1.1 drochner bus_space_tag_t memt = vc->hdl.vh_memt;
592 1.1 drochner bus_space_handle_t memh = vc->hdl.vh_memh;
593 1.1 drochner bus_size_t off;
594 1.1 drochner u_int16_t val;
595 1.1 drochner int i;
596 1.1 drochner
597 1.1 drochner off = row * scr->type->ncols + startcol;
598 1.1 drochner
599 1.1 drochner val = (scr->vc_at << 8) | ' ';
600 1.1 drochner
601 1.1 drochner if (scr == vc->active)
602 1.1 drochner bus_space_set_region_2(memt, memh, off * 2, val, ncols);
603 1.1 drochner else
604 1.1 drochner for (i = 0; i < ncols; i++)
605 1.1 drochner scr->mem[off + i] = val;
606 1.1 drochner }
607 1.1 drochner
608 1.1 drochner static void
609 1.1 drochner vga_copyrows(id, srcrow, dstrow, nrows)
610 1.1 drochner void *id;
611 1.1 drochner int srcrow, dstrow, nrows;
612 1.1 drochner {
613 1.1 drochner struct vgascreen *scr = id;
614 1.1 drochner struct vga_config *vc = scr->cfg;
615 1.1 drochner bus_space_tag_t memt = vc->hdl.vh_memt;
616 1.1 drochner bus_space_handle_t memh = vc->hdl.vh_memh;
617 1.1 drochner const struct wsscreen_descr *type = scr->type;
618 1.1 drochner bus_size_t srcoff, dstoff;
619 1.1 drochner
620 1.1 drochner srcoff = srcrow * type->ncols + 0;
621 1.1 drochner dstoff = dstrow * type->ncols + 0;
622 1.1 drochner
623 1.1 drochner if (scr == vc->active)
624 1.1 drochner bus_space_copy_region_2(memt, memh, srcoff * 2,
625 1.1 drochner memh, dstoff * 2, nrows * type->ncols);
626 1.1 drochner else
627 1.1 drochner bcopy(&scr->mem[srcoff], &scr->mem[dstoff],
628 1.1 drochner nrows * type->ncols * 2);
629 1.1 drochner }
630 1.1 drochner
631 1.1 drochner static void
632 1.1 drochner vga_eraserows(id, startrow, nrows)
633 1.1 drochner void *id;
634 1.1 drochner int startrow, nrows;
635 1.1 drochner {
636 1.1 drochner struct vgascreen *scr = id;
637 1.1 drochner struct vga_config *vc = scr->cfg;
638 1.1 drochner bus_space_tag_t memt = vc->hdl.vh_memt;
639 1.1 drochner bus_space_handle_t memh = vc->hdl.vh_memh;
640 1.1 drochner bus_size_t off, count;
641 1.1 drochner u_int16_t val;
642 1.1 drochner int i;
643 1.1 drochner
644 1.1 drochner off = startrow * scr->type->ncols;
645 1.1 drochner count = nrows * scr->type->ncols;
646 1.1 drochner
647 1.1 drochner val = (scr->vc_at << 8) | ' ';
648 1.1 drochner
649 1.1 drochner if (scr == vc->active)
650 1.1 drochner bus_space_set_region_2(memt, memh, off * 2, val, count);
651 1.1 drochner else
652 1.1 drochner for (i = 0; i < count; i++)
653 1.1 drochner scr->mem[off + i] = val;
654 1.1 drochner }
655