pm.c revision 1.1.2.10 1 /* $NetBSD: pm.c,v 1.1.2.10 1999/03/30 01:10:05 nisimura Exp $ */
2
3 /*
4 * Copyright (c) 1998 Tohru Nishimura. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by Tohru Nishimura
17 * for the NetBSD Project.
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
34
35 __KERNEL_RCSID(0, "$Id: pm.c,v 1.1.2.10 1999/03/30 01:10:05 nisimura Exp $");
36
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/kernel.h>
40 #include <sys/device.h>
41 #include <sys/malloc.h>
42 #include <sys/buf.h>
43 #include <sys/ioctl.h>
44 #include <vm/vm.h>
45 #include <uvm/uvm_extern.h>
46
47 #include <dev/rcons/raster.h>
48 #include <dev/wscons/wsconsio.h>
49 #include <dev/wscons/wscons_raster.h>
50 #include <dev/wscons/wsdisplayvar.h>
51
52 #include <machine/cpu.h>
53 #include <pmax/ibus/ibusvar.h>
54
55 extern void kn01_wbflush __P((void));
56
57 struct pccreg {
58 #define _HALF_(xxx) u_int16_t xxx; unsigned : 16
59 _HALF_(pcc_cmdr); /* cursor command register */
60 _HALF_(pcc_xpos); /* cursor X position */
61 _HALF_(pcc_ypos); /* cursor Y position */
62 _HALF_(pcc_xmin1); /* region 1 top edge */
63 _HALF_(pcc_xmax1); /* region 1 bottom edge */
64 _HALF_(pcc_ymin1); /* region 1 top edge */
65 _HALF_(pcc_ymax1); /* region 1 bottom edge */
66 unsigned : 32; /* unused */
67 unsigned : 32; /* unused */
68 unsigned : 32; /* unused */
69 unsigned : 32; /* unused */
70 _HALF_(pcc_xmin2); /* region 2 top edge */
71 _HALF_(pcc_xmax2); /* region 2 bottom edge */
72 _HALF_(pcc_ymin2); /* region 2 top edge */
73 _HALF_(pcc_ymax2); /* region 2 bottom edge */
74 _HALF_(pcc_memory); /* cursor sprite pattern load */
75 #undef _HALF_
76 };
77
78 #define PCC_ENPA 0000001
79 #define PCC_FOPA 0000002
80 #define PCC_ENPB 0000004
81 #define PCC_FOPB 0000010
82 #define PCC_XHAIR 0000020
83 #define PCC_XHCLP 0000040
84 #define PCC_XHCL1 0000100
85 #define PCC_XHWID 0000200
86 #define PCC_ENRG1 0000400
87 #define PCC_FORG1 0001000
88 #define PCC_ENRG2 0002000
89 #define PCC_FORG2 0004000
90 #define PCC_LODSA 0010000
91 #define PCC_VBHI 0020000
92 #define PCC_HSHI 0040000
93 #define PCC_TEST 0100000
94
95 struct bt478reg {
96 #define _BYTE_(yyy) u_int8_t yyy; unsigned : 24
97 _BYTE_(bt_mapWA); /* address register (color map write) */
98 _BYTE_(bt_map); /* color map */
99 _BYTE_(bt_mask); /* pixel read mask */
100 _BYTE_(bt_mapRA); /* address register (color map read) */
101 _BYTE_(bt_overWA); /* address register (overlay map write) */
102 _BYTE_(bt_over); /* overlay map */
103 unsigned : 32; /* unused */
104 _BYTE_(bt_overRA); /* address register (overlay map read) */
105 #undef _BYTE_
106 };
107
108 struct fb_devconfig {
109 vaddr_t dc_vaddr; /* memory space virtual base address */
110 paddr_t dc_paddr; /* memory space physical base address */
111 vsize_t dc_size; /* size of slot memory */
112 int dc_wid; /* width of frame buffer */
113 int dc_ht; /* height of frame buffer */
114 int dc_depth; /* depth, bits per pixel */
115 int dc_rowbytes; /* bytes in a FB scan line */
116 vaddr_t dc_videobase; /* base of flat frame buffer */
117 struct raster dc_raster; /* raster description */
118 struct rcons dc_rcons; /* raster blitter control info */
119 int dc_blanked; /* currently has video disabled */
120 };
121
122 struct hwcmap {
123 #define CMAP_SIZE 256 /* 256 R/G/B entries */
124 u_int8_t r[CMAP_SIZE];
125 u_int8_t g[CMAP_SIZE];
126 u_int8_t b[CMAP_SIZE];
127 };
128
129 struct hwcursor {
130 struct wsdisplay_curpos cc_pos;
131 struct wsdisplay_curpos cc_hot;
132 struct wsdisplay_curpos cc_size;
133 #define CURSOR_MAX_SIZE 16
134 u_int8_t cc_color[6];
135 u_int32_t cc_image[16 + 16];
136 };
137
138 struct pm_softc {
139 struct device sc_dev;
140 struct fb_devconfig *sc_dc; /* device configuration */
141 struct hwcmap sc_cmap; /* software copy of colormap */
142 struct hwcursor sc_cursor; /* software copy of cursor */
143 /* no sc_change field because pm does not emit interrupt */
144 int nscreens;
145 short magic_x, magic_y; /* cursor location offset */
146 #define PCC_MAGIC_X 212
147 #define PCC_MAGIC_Y 34
148
149 struct pccreg *sc_pcc;
150 struct bt478reg *sc_vdac;
151 u_int16_t sc_pcccmdr; /* software copy of PCC cmdr */
152 };
153
154 int pmmatch __P((struct device *, struct cfdata *, void *));
155 void pmattach __P((struct device *, struct device *, void *));
156
157 struct cfattach pm_ca = {
158 sizeof(struct pm_softc), pmmatch, pmattach,
159 };
160
161 void pm_getdevconfig __P((u_int32_t, struct fb_devconfig *));
162 struct fb_devconfig pm_console_dc;
163 caddr_t pm_consaddr;
164
165 struct wsdisplay_emulops pm_emulops = {
166 rcons_cursor,
167 rcons_mapchar,
168 rcons_putchar,
169 rcons_copycols,
170 rcons_erasecols,
171 rcons_copyrows,
172 rcons_eraserows,
173 rcons_alloc_attr
174 };
175
176 struct wsscreen_descr pm_stdscreen = {
177 "std",
178 0, 0, /* will be filled in -- XXX shouldn't, it's global */
179 &pm_emulops,
180 0, 0,
181 0
182 };
183
184 const struct wsscreen_descr *_pm_scrlist[] = {
185 &pm_stdscreen,
186 };
187
188 struct wsscreen_list pm_screenlist = {
189 sizeof(_pm_scrlist) / sizeof(struct wsscreen_descr *), _pm_scrlist
190 };
191
192 int pmioctl __P((void *, u_long, caddr_t, int, struct proc *));
193 int pmmmap __P((void *, off_t, int));
194
195 int pm_alloc_screen __P((void *, const struct wsscreen_descr *,
196 void **, int *, int *, long *));
197 void pm_free_screen __P((void *, void *));
198 void pm_show_screen __P((void *, void *));
199
200 struct wsdisplay_accessops pm_accessops = {
201 pmioctl,
202 pmmmap,
203 pm_alloc_screen,
204 pm_free_screen,
205 pm_show_screen,
206 0 /* load_font */
207 };
208
209 int pm_cnattach __P((u_int32_t));
210 void pminit __P((struct fb_devconfig *));
211 void pm_screenblank __P((struct pm_softc *));
212
213 static int set_cmap __P((struct pm_softc *, struct wsdisplay_cmap *));
214 static int get_cmap __P((struct pm_softc *, struct wsdisplay_cmap *));
215 static int set_cursor __P((struct pm_softc *, struct wsdisplay_cursor *));
216 static int get_cursor __P((struct pm_softc *, struct wsdisplay_cursor *));
217 static void set_curpos __P((struct pm_softc *, struct wsdisplay_curpos *));
218 void bt478_loadcmap __P((struct pm_softc *));
219 void bt478_load_curcmap __P((struct pm_softc *));
220 void pcc_load_curshape __P((struct pm_softc *));
221 void pcc_set_curpos __P((struct pm_softc *));
222 void pcc_show_cursor __P((struct pm_softc *, int));
223
224 #define KN01_SYS_PCC 0x11100000
225 #define KN01_SYS_BT478 0x11200000
226 #define KN01_SYS_PMASK 0x10000000
227 #define KN01_SYS_CSR 0x1e000000
228 #define KN01_CSR_MONO 0x0800
229
230 int
231 pmmatch(parent, match, aux)
232 struct device *parent;
233 struct cfdata *match;
234 void *aux;
235 {
236 struct ibus_attach_args *ia = aux;
237
238 if (strcmp("pm", ia->ia_name))
239 return (0);
240 if (badaddr((char *)ia->ia_addr, 4))
241 return (0);
242 return (1);
243 }
244
245 void
246 pm_getdevconfig(dense_addr, dc)
247 u_int32_t dense_addr;
248 struct fb_devconfig *dc;
249 {
250 struct raster *rap;
251 struct rcons *rcp;
252 u_int16_t *p = (void *)MIPS_PHYS_TO_KSEG1(KN01_SYS_CSR);
253 int i;
254
255 dc->dc_wid = 1024;
256 dc->dc_ht = 864;
257 dc->dc_depth = (*p & KN01_CSR_MONO) ? 1 : 8;
258 dc->dc_rowbytes = (dc->dc_depth == 8) ? 1024 : 1024 / 8;
259 dc->dc_videobase = dense_addr;
260 dc->dc_blanked = 0;
261
262 dc->dc_vaddr = dense_addr;
263 dc->dc_paddr = MIPS_KSEG1_TO_PHYS(dc->dc_vaddr);
264 dc->dc_size = (dc->dc_depth == 8) ? 0x100000 : 0x40000;
265
266 /* initialize colormap and cursor resource */
267 pminit(dc);
268
269 /* clear the screen */
270 for (i = 0; i < dc->dc_ht * dc->dc_rowbytes; i += sizeof(u_int32_t))
271 *(u_int32_t *)(dc->dc_videobase + i) = 0;
272
273 /* initialize the raster */
274 rap = &dc->dc_raster;
275 rap->width = dc->dc_wid;
276 rap->height = dc->dc_ht;
277 rap->depth = dc->dc_depth;
278 rap->linelongs = dc->dc_rowbytes / sizeof(u_int32_t);
279 rap->pixels = (u_int32_t *)dc->dc_videobase;
280
281 /* initialize the raster console blitter */
282 rcp = &dc->dc_rcons;
283 rcp->rc_sp = rap;
284 rcp->rc_crow = rcp->rc_ccol = -1;
285 rcp->rc_crowp = &rcp->rc_crow;
286 rcp->rc_ccolp = &rcp->rc_ccol;
287 rcons_init(rcp, 34, 80);
288
289 pm_stdscreen.nrows = dc->dc_rcons.rc_maxrow;
290 pm_stdscreen.ncols = dc->dc_rcons.rc_maxcol;
291 }
292
293 void
294 pmattach(parent, self, aux)
295 struct device *parent, *self;
296 void *aux;
297 {
298 struct pm_softc *sc = (struct pm_softc *)self;
299 struct ibus_attach_args *ia = aux;
300 struct wsemuldisplaydev_attach_args waa;
301 struct hwcmap *cm;
302 int console, i;
303
304 console = ((caddr_t)ia->ia_addr == pm_consaddr);
305 if (console) {
306 sc->sc_dc = &pm_console_dc;
307 sc->nscreens = 1;
308 }
309 else {
310 sc->sc_dc = (struct fb_devconfig *)
311 malloc(sizeof(struct fb_devconfig), M_DEVBUF, M_WAITOK);
312 pm_getdevconfig(ia->ia_addr, sc->sc_dc);
313 }
314 printf(": %d x %d, %dbpp\n", sc->sc_dc->dc_wid, sc->sc_dc->dc_ht,
315 sc->sc_dc->dc_depth);
316
317 cm = &sc->sc_cmap;
318 cm->r[0] = cm->g[0] = cm->b[0] = 0;
319 for (i = 1; i < CMAP_SIZE; i++) {
320 cm->r[i] = cm->g[i] = cm->b[i] = 0xff;
321 }
322 sc->magic_x = PCC_MAGIC_X;
323 sc->magic_y = PCC_MAGIC_Y;
324 sc->sc_pcc = (void *)MIPS_PHYS_TO_KSEG1(KN01_SYS_PCC);
325 sc->sc_vdac = (void *)MIPS_PHYS_TO_KSEG1(KN01_SYS_BT478);
326 sc->sc_pcccmdr = 0;
327
328 /* pm emits no interrupt */
329
330 waa.console = console;
331 waa.scrdata = &pm_screenlist;
332 waa.accessops = &pm_accessops;
333 waa.accesscookie = sc;
334
335 config_found(self, &waa, wsemuldisplaydevprint);
336 }
337
338 int
339 pmioctl(v, cmd, data, flag, p)
340 void *v;
341 u_long cmd;
342 caddr_t data;
343 int flag;
344 struct proc *p;
345 {
346 struct pm_softc *sc = v;
347 struct fb_devconfig *dc = sc->sc_dc;
348 int turnoff, error;
349
350 switch (cmd) {
351 case WSDISPLAYIO_GTYPE:
352 *(u_int *)data = (dc->dc_depth == 8)
353 ? WSDISPLAY_TYPE_PM_COLOR : WSDISPLAY_TYPE_PM_MONO;
354 return (0);
355
356 case WSDISPLAYIO_GINFO:
357 #define wsd_fbip ((struct wsdisplay_fbinfo *)data)
358 wsd_fbip->height = sc->sc_dc->dc_ht;
359 wsd_fbip->width = sc->sc_dc->dc_wid;
360 wsd_fbip->depth = sc->sc_dc->dc_depth;
361 wsd_fbip->cmsize = CMAP_SIZE;
362 #undef fbt
363 return (0);
364
365 case WSDISPLAYIO_GETCMAP:
366 return get_cmap(sc, (struct wsdisplay_cmap *)data);
367
368 case WSDISPLAYIO_PUTCMAP:
369 error = set_cmap(sc, (struct wsdisplay_cmap *)data);
370 if (error == 0)
371 bt478_loadcmap(sc);
372 return (error);
373
374 case WSDISPLAYIO_SVIDEO:
375 turnoff = *(int *)data == WSDISPLAYIO_VIDEO_OFF;
376 if ((dc->dc_blanked == 0) ^ turnoff) {
377 dc->dc_blanked = turnoff;
378 pm_screenblank(sc);
379 }
380 return (0);
381
382 case WSDISPLAYIO_GVIDEO:
383 *(u_int *)data = dc->dc_blanked ?
384 WSDISPLAYIO_VIDEO_OFF : WSDISPLAYIO_VIDEO_ON;
385 return (0);
386
387 case WSDISPLAYIO_GCURPOS:
388 *(struct wsdisplay_curpos *)data = sc->sc_cursor.cc_pos;
389 return (0);
390
391 case WSDISPLAYIO_SCURPOS:
392 set_curpos(sc, (struct wsdisplay_curpos *)data);
393 pcc_set_curpos(sc);
394 return (0);
395
396 case WSDISPLAYIO_GCURMAX:
397 ((struct wsdisplay_curpos *)data)->x =
398 ((struct wsdisplay_curpos *)data)->y = CURSOR_MAX_SIZE;
399 return (0);
400
401 case WSDISPLAYIO_GCURSOR:
402 return get_cursor(sc, (struct wsdisplay_cursor *)data);
403
404 case WSDISPLAYIO_SCURSOR:
405 return set_cursor(sc, (struct wsdisplay_cursor *)data);
406 }
407 return ENOTTY;
408 }
409
410 int
411 pmmmap(v, offset, prot)
412 void *v;
413 off_t offset;
414 int prot;
415 {
416 struct pm_softc *sc = v;
417
418 if (offset >= sc->sc_dc->dc_size)
419 return -1;
420 return mips_btop(sc->sc_dc->dc_paddr + offset);
421 }
422
423 int
424 pm_alloc_screen(v, type, cookiep, curxp, curyp, attrp)
425 void *v;
426 const struct wsscreen_descr *type;
427 void **cookiep;
428 int *curxp, *curyp;
429 long *attrp;
430 {
431 struct pm_softc *sc = v;
432 long defattr;
433
434 if (sc->nscreens > 0)
435 return (ENOMEM);
436
437 *cookiep = &sc->sc_dc->dc_rcons; /* one and only for now */
438 *curxp = 0;
439 *curyp = 0;
440 rcons_alloc_attr(&sc->sc_dc->dc_rcons, 0, 0, 0, &defattr);
441 *attrp = defattr;
442 sc->nscreens++;
443 return (0);
444 }
445
446 void
447 pm_free_screen(v, cookie)
448 void *v;
449 void *cookie;
450 {
451 struct pm_softc *sc = v;
452
453 if (sc->sc_dc == &pm_console_dc)
454 panic("pm_free_screen: console");
455
456 sc->nscreens--;
457 }
458
459 void
460 pm_show_screen(v, cookie)
461 void *v;
462 void *cookie;
463 {
464 }
465
466 int
467 pm_cnattach(addr)
468 u_int32_t addr;
469 {
470 struct fb_devconfig *dcp = &pm_console_dc;
471 long defattr;
472
473 if (badaddr((char *)addr, 4))
474 return (0);
475
476 pm_getdevconfig(addr, dcp);
477 rcons_alloc_attr(&dcp->dc_rcons, 0, 0, 0, &defattr);
478 wsdisplay_cnattach(&pm_stdscreen, &dcp->dc_rcons,
479 0, 0, defattr);
480
481 pm_consaddr = (caddr_t)addr;
482 return (1);
483 }
484
485 void
486 pminit(dc)
487 struct fb_devconfig *dc;
488 {
489 int i;
490 volatile struct bt478reg *vdac =
491 (void *)MIPS_PHYS_TO_KSEG1(KN01_SYS_BT478);
492 volatile struct pccreg *pcc =
493 (void *)MIPS_PHYS_TO_KSEG1(KN01_SYS_PCC);
494
495 pcc->pcc_cmdr = PCC_FOPB | PCC_VBHI;
496
497 *(volatile u_int8_t *)MIPS_PHYS_TO_KSEG1(KN01_SYS_PMASK) = 0xff;
498
499 vdac->bt_mapWA = 0; kn01_wbflush();
500 vdac->bt_map = 0; kn01_wbflush();
501 vdac->bt_map = 0; kn01_wbflush();
502 vdac->bt_map = 0; kn01_wbflush();
503 for (i = 1; i < CMAP_SIZE; i++) {
504 vdac->bt_mapWA = i; kn01_wbflush();
505 vdac->bt_map = 0xff; kn01_wbflush();
506 vdac->bt_map = 0xff; kn01_wbflush();
507 vdac->bt_map = 0xff; kn01_wbflush();
508 }
509 }
510
511 void
512 pm_screenblank(sc)
513 struct pm_softc *sc;
514 {
515 #if 0 /* XXX later XXX */
516 struct fb_devconfig *dc = sc->sc_dc;
517
518 if (dc->dc_blanked) {
519 /* blank screen */
520 /* turnoff hardware cursor */
521 }
522 else {
523 /* restore current colormap */
524 /* turnon hardware cursor */
525 }
526 #endif
527 }
528
529 static int
530 get_cmap(sc, p)
531 struct pm_softc *sc;
532 struct wsdisplay_cmap *p;
533 {
534 u_int index = p->index, count = p->count;
535
536 if (index >= CMAP_SIZE || (index + count) > CMAP_SIZE)
537 return (EINVAL);
538
539 if (!uvm_useracc(p->red, count, B_WRITE) ||
540 !uvm_useracc(p->green, count, B_WRITE) ||
541 !uvm_useracc(p->blue, count, B_WRITE))
542 return (EFAULT);
543
544 copyout(&sc->sc_cmap.r[index], p->red, count);
545 copyout(&sc->sc_cmap.r[index], p->green, count);
546 copyout(&sc->sc_cmap.r[index], p->blue, count);
547
548 return (0);
549 }
550
551 static int
552 set_cmap(sc, p)
553 struct pm_softc *sc;
554 struct wsdisplay_cmap *p;
555 {
556 u_int index = p->index, count = p->count;
557
558 if (index >= CMAP_SIZE || (index + count) > CMAP_SIZE)
559 return (EINVAL);
560
561 if (!uvm_useracc(p->red, count, B_READ) ||
562 !uvm_useracc(p->green, count, B_READ) ||
563 !uvm_useracc(p->blue, count, B_READ))
564 return (EFAULT);
565
566 copyin(p->red, &sc->sc_cmap.r[index], count);
567 copyin(p->green, &sc->sc_cmap.g[index], count);
568 copyin(p->blue, &sc->sc_cmap.b[index], count);
569
570 return (0);
571 }
572
573 static int
574 set_cursor(sc, p)
575 struct pm_softc *sc;
576 struct wsdisplay_cursor *p;
577 {
578 #define cc (&sc->sc_cursor)
579 int v, index, count;
580
581 v = p->which;
582 if (v & WSDISPLAY_CURSOR_DOCMAP) {
583 index = p->cmap.index;
584 count = p->cmap.count;
585 if (index >= 2 || (index + count) > 2)
586 return (EINVAL);
587 if (!uvm_useracc(p->cmap.red, count, B_READ) ||
588 !uvm_useracc(p->cmap.green, count, B_READ) ||
589 !uvm_useracc(p->cmap.blue, count, B_READ))
590 return (EFAULT);
591
592 count = p->cmap.count;
593 copyin(p->cmap.red, &cc->cc_color[index], count);
594 copyin(p->cmap.green, &cc->cc_color[index + 2], count);
595 copyin(p->cmap.blue, &cc->cc_color[index + 4], count);
596
597 bt478_load_curcmap(sc);
598 }
599 if (v & WSDISPLAY_CURSOR_DOSHAPE) {
600 if (p->size.x > CURSOR_MAX_SIZE || p->size.y > CURSOR_MAX_SIZE)
601 return (EINVAL);
602 count = (CURSOR_MAX_SIZE / NBBY) * p->size.y;
603 if (!uvm_useracc(p->image, count, B_READ) ||
604 !uvm_useracc(p->mask, count, B_READ))
605 return (EFAULT);
606 cc->cc_size = p->size;
607 memset(cc->cc_image, 0, sizeof cc->cc_image);
608 copyin(p->image, (caddr_t)cc->cc_image, count);
609 copyin(p->mask, (caddr_t)(cc->cc_image+CURSOR_MAX_SIZE), count);
610
611 pcc_load_curshape(sc);
612 }
613 if (v & WSDISPLAY_CURSOR_DOCUR) {
614 cc->cc_hot = p->hot;
615 pcc_show_cursor(sc, p->enable);
616 }
617 if (v & WSDISPLAY_CURSOR_DOPOS) {
618 set_curpos(sc, &p->pos);
619 pcc_set_curpos(sc);
620 }
621
622 return (0);
623 #undef cc
624 }
625
626 static int
627 get_cursor(sc, p)
628 struct pm_softc *sc;
629 struct wsdisplay_cursor *p;
630 {
631 return (ENOTTY); /* XXX */
632 }
633
634 void
635 set_curpos(sc, curpos)
636 struct pm_softc *sc;
637 struct wsdisplay_curpos *curpos;
638 {
639 struct fb_devconfig *dc = sc->sc_dc;
640 int x = curpos->x, y = curpos->y;
641
642 if (y < 0)
643 y = 0;
644 else if (y > dc->dc_ht)
645 y = dc->dc_ht;
646 if (x < 0)
647 x = 0;
648 else if (x > dc->dc_wid)
649 x = dc->dc_wid;
650 sc->sc_cursor.cc_pos.x = x;
651 sc->sc_cursor.cc_pos.y = y;
652 }
653
654 void
655 bt478_loadcmap(sc)
656 struct pm_softc *sc;
657 {
658 int i;
659 struct hwcmap *cm = &sc->sc_cmap;
660 volatile struct bt478reg *vdac = sc->sc_vdac;
661
662 for (i = 0; i < CMAP_SIZE; i++) {
663 vdac->bt_mapWA = i; kn01_wbflush();
664 vdac->bt_map = cm->r[i]; kn01_wbflush();
665 vdac->bt_map = cm->g[i]; kn01_wbflush();
666 vdac->bt_map = cm->b[i]; kn01_wbflush();
667 }
668 }
669
670 void
671 bt478_load_curcmap(sc)
672 struct pm_softc *sc;
673 {
674 u_int8_t *cp = sc->sc_cursor.cc_color;
675 volatile struct bt478reg *vdac = sc->sc_vdac;
676
677 vdac->bt_overWA = 0x04; kn01_wbflush();
678 vdac->bt_over = cp[1]; kn01_wbflush();
679 vdac->bt_over = cp[3]; kn01_wbflush();
680 vdac->bt_over = cp[5]; kn01_wbflush();
681
682 vdac->bt_overWA = 0x08; kn01_wbflush();
683 vdac->bt_over = 0x00; kn01_wbflush();
684 vdac->bt_over = 0x00; kn01_wbflush();
685 vdac->bt_over = 0x7f; kn01_wbflush();
686
687 vdac->bt_overWA = 0x0c; kn01_wbflush();
688 vdac->bt_over = cp[0]; kn01_wbflush();
689 vdac->bt_over = cp[2]; kn01_wbflush();
690 vdac->bt_over = cp[4]; kn01_wbflush();
691 }
692
693 void
694 pcc_load_curshape(sc)
695 struct pm_softc *sc;
696 {
697 volatile struct pccreg *pcc = sc->sc_pcc;
698 u_int32_t *bp;
699 int i;
700
701 pcc->pcc_cmdr = sc->sc_pcccmdr | PCC_LODSA;
702 bp = sc->sc_cursor.cc_image;
703 for (i = 0; i < sizeof(sc->sc_cursor.cc_image); i++) {
704 pcc->pcc_memory = (u_int16_t)*bp++;
705 }
706 pcc->pcc_cmdr = sc->sc_pcccmdr;
707 }
708
709 void
710 pcc_set_curpos(sc)
711 struct pm_softc *sc;
712 {
713 volatile struct pccreg *pcc = sc->sc_pcc;
714
715 pcc->pcc_xpos = sc->sc_cursor.cc_pos.x + sc->magic_x;
716 pcc->pcc_ypos = sc->sc_cursor.cc_pos.y + sc->magic_y;
717 }
718
719 void
720 pcc_show_cursor(sc, enable)
721 struct pm_softc *sc;
722 int enable;
723 {
724 volatile struct pccreg *pcc = sc->sc_pcc;
725
726 if (enable)
727 sc->sc_pcccmdr |= (PCC_ENPA | PCC_ENPB);
728 else
729 sc->sc_pcccmdr &= ~(PCC_ENPA | PCC_ENPB);
730 pcc->pcc_cmdr = sc->sc_pcccmdr;
731 }
732