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