Annotation of sys/arch/vax/vsa/smg.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: smg.c,v 1.19 2006/11/29 19:08:22 miod Exp $ */
2: /* $NetBSD: smg.c,v 1.21 2000/03/23 06:46:44 thorpej Exp $ */
3: /*
4: * Copyright (c) 2006, Miodrag Vallat
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: *
15: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18: * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
19: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
23: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
24: * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25: * POSSIBILITY OF SUCH DAMAGE.
26: */
27: /*
28: * Copyright (c) 1998 Ludd, University of Lule}, Sweden.
29: * All rights reserved.
30: *
31: * Redistribution and use in source and binary forms, with or without
32: * modification, are permitted provided that the following conditions
33: * are met:
34: * 1. Redistributions of source code must retain the above copyright
35: * notice, this list of conditions and the following disclaimer.
36: * 2. Redistributions in binary form must reproduce the above copyright
37: * notice, this list of conditions and the following disclaimer in the
38: * documentation and/or other materials provided with the distribution.
39: * 3. All advertising materials mentioning features or use of this software
40: * must display the following acknowledgement:
41: * This product includes software developed at Ludd, University of
42: * Lule}, Sweden and its contributors.
43: * 4. The name of the author may not be used to endorse or promote products
44: * derived from this software without specific prior written permission
45: *
46: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
47: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
48: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
49: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
50: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
51: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
52: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
53: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
54: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
55: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
56: */
57: /*
58: * Copyright (c) 1996 Jason R. Thorpe. All rights reserved.
59: * Copyright (c) 1991 University of Utah.
60: * Copyright (c) 1990, 1993
61: * The Regents of the University of California. All rights reserved.
62: *
63: * This code is derived from software contributed to Berkeley by
64: * the Systems Programming Group of the University of Utah Computer
65: * Science Department and Mark Davies of the Department of Computer
66: * Science, Victoria University of Wellington, New Zealand.
67: *
68: * Redistribution and use in source and binary forms, with or without
69: * modification, are permitted provided that the following conditions
70: * are met:
71: * 1. Redistributions of source code must retain the above copyright
72: * notice, this list of conditions and the following disclaimer.
73: * 2. Redistributions in binary form must reproduce the above copyright
74: * notice, this list of conditions and the following disclaimer in the
75: * documentation and/or other materials provided with the distribution.
76: * 3. Neither the name of the University nor the names of its contributors
77: * may be used to endorse or promote products derived from this software
78: * without specific prior written permission.
79: *
80: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
81: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
82: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
83: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
84: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
85: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
86: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
87: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
88: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
89: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
90: * SUCH DAMAGE.
91: *
92: * from: Utah $Hdr: grf_hy.c 1.2 93/08/13$
93: *
94: * @(#)grf_hy.c 8.4 (Berkeley) 1/12/94
95: */
96:
97: #include <sys/param.h>
98: #include <sys/device.h>
99: #include <sys/systm.h>
100: #include <sys/malloc.h>
101: #include <sys/conf.h>
102: #include <sys/kernel.h>
103:
104: #include <machine/vsbus.h>
105: #include <machine/sid.h>
106: #include <machine/cpu.h>
107: #include <machine/ka420.h>
108: #include <machine/scb.h>
109:
110: #include <uvm/uvm_extern.h>
111:
112: #include <dev/cons.h>
113:
114: #include <dev/ic/dc503reg.h>
115:
116: #include <vax/qbus/dzreg.h>
117: #include <vax/qbus/dzvar.h>
118: #include <vax/dec/dzkbdvar.h>
119:
120: #include <dev/wscons/wsconsio.h>
121: #include <dev/wscons/wsdisplayvar.h>
122: #include <dev/rasops/rasops.h>
123: #include <dev/rasops/rasops_masks.h>
124:
125: /* Screen hardware defs */
126: #define SM_XWIDTH 1024
127: #define SM_YWIDTH 864
128:
129: #define CUR_XBIAS 216 /* Add to cursor position */
130: #define CUR_YBIAS 33
131:
132: int smg_match(struct device *, void *, void *);
133: void smg_attach(struct device *, struct device *, void *);
134:
135: struct smg_screen {
136: struct rasops_info ss_ri;
137: caddr_t ss_addr; /* frame buffer address */
138: struct dc503reg *ss_cursor; /* cursor registers */
139: u_int16_t ss_curcmd;
140: struct wsdisplay_curpos ss_curpos, ss_curhot;
141: u_int16_t ss_curimg[PCC_CURSOR_SIZE];
142: u_int16_t ss_curmask[PCC_CURSOR_SIZE];
143: };
144:
145: /* for console */
146: struct smg_screen smg_consscr;
147:
148: struct smg_softc {
149: struct device sc_dev;
150: struct smg_screen *sc_scr;
151: int sc_nscreens;
152: };
153:
154: struct cfattach smg_ca = {
155: sizeof(struct smg_softc), smg_match, smg_attach,
156: };
157:
158: struct cfdriver smg_cd = {
159: NULL, "smg", DV_DULL
160: };
161:
162: struct wsscreen_descr smg_stdscreen = {
163: "std",
164: };
165:
166: const struct wsscreen_descr *_smg_scrlist[] = {
167: &smg_stdscreen,
168: };
169:
170: const struct wsscreen_list smg_screenlist = {
171: sizeof(_smg_scrlist) / sizeof(struct wsscreen_descr *),
172: _smg_scrlist,
173: };
174:
175: int smg_ioctl(void *, u_long, caddr_t, int, struct proc *);
176: paddr_t smg_mmap(void *, off_t, int);
177: int smg_alloc_screen(void *, const struct wsscreen_descr *,
178: void **, int *, int *, long *);
179: void smg_free_screen(void *, void *);
180: int smg_show_screen(void *, void *, int,
181: void (*) (void *, int, int), void *);
182: void smg_burner(void *, u_int, u_int);
183:
184: const struct wsdisplay_accessops smg_accessops = {
185: smg_ioctl,
186: smg_mmap,
187: smg_alloc_screen,
188: smg_free_screen,
189: smg_show_screen,
190: NULL, /* load_font */
191: NULL, /* scrollback */
192: NULL, /* getchar */
193: smg_burner
194: };
195:
196: void smg_blockmove(struct rasops_info *, u_int, u_int, u_int, u_int, u_int,
197: int);
198: void smg_copycols(void *, int, int, int, int);
199: void smg_erasecols(void *, int, int, int, long);
200:
201: int smg_getcursor(struct smg_screen *, struct wsdisplay_cursor *);
202: int smg_setup_screen(struct smg_screen *);
203: int smg_setcursor(struct smg_screen *, struct wsdisplay_cursor *);
204: void smg_updatecursor(struct smg_screen *, u_int);
205:
206: int
207: smg_match(struct device *parent, void *vcf, void *aux)
208: {
209: struct cfdata *cf = vcf;
210: struct vsbus_attach_args *va = aux;
211: volatile short *curcmd;
212: volatile short *cfgtst;
213: short tmp, tmp2;
214: extern struct consdev wsdisplay_cons;
215:
216: switch (vax_boardtype) {
217: default:
218: return (0);
219:
220: case VAX_BTYP_410:
221: case VAX_BTYP_420:
222: case VAX_BTYP_43:
223: if (va->va_paddr != KA420_CUR_BASE)
224: return (0);
225:
226: /* not present on microvaxes */
227: if ((vax_confdata & KA420_CFG_MULTU) != 0)
228: return (0);
229:
230: /*
231: * If the color option board is present, do not attach
232: * unless we are explicitely asked to via device flags.
233: */
234: if ((vax_confdata & KA420_CFG_VIDOPT) != 0 &&
235: (cf->cf_flags & 1) == 0)
236: return (0);
237: break;
238: }
239:
240: /* when already running as console, always fake things */
241: if ((vax_confdata & (KA420_CFG_L3CON | KA420_CFG_VIDOPT)) == 0 &&
242: cn_tab == &wsdisplay_cons) {
243: struct vsbus_softc *sc = (void *)parent;
244: extern int oldvsbus;
245:
246: sc->sc_mask = 0x08;
247: scb_fake(0x44, oldvsbus ? 0x14 : 0x15);
248: return (20);
249: } else {
250: /*
251: * Try to find the cursor chip by testing the flip-flop.
252: * If nonexistent, no glass tty.
253: */
254: curcmd = (short *)va->va_addr;
255: cfgtst = (short *)vax_map_physmem(VS_CFGTST, 1);
256: curcmd[0] = PCCCMD_HSHI | PCCCMD_FOPB;
257: DELAY(300000);
258: tmp = cfgtst[0];
259: curcmd[0] = PCCCMD_TEST | PCCCMD_HSHI;
260: DELAY(300000);
261: tmp2 = cfgtst[0];
262: vax_unmap_physmem((vaddr_t)cfgtst, 1);
263:
264: if (tmp2 != tmp)
265: return (20); /* Using periodic interrupt */
266: else
267: return (0);
268: }
269: }
270:
271: void
272: smg_attach(struct device *parent, struct device *self, void *aux)
273: {
274: struct smg_softc *sc = (struct smg_softc *)self;
275: struct smg_screen *scr;
276: struct wsemuldisplaydev_attach_args aa;
277: int console;
278: extern struct consdev wsdisplay_cons;
279:
280: console = (vax_confdata & (KA420_CFG_L3CON | KA420_CFG_VIDOPT)) == 0 &&
281: cn_tab == &wsdisplay_cons;
282: if (console) {
283: scr = &smg_consscr;
284: sc->sc_nscreens = 1;
285: } else {
286: scr = malloc(sizeof(struct smg_screen), M_DEVBUF, M_NOWAIT);
287: if (scr == NULL) {
288: printf(": can not allocate memory\n");
289: return;
290: }
291: bzero(scr, sizeof(struct smg_screen));
292:
293: scr->ss_addr =
294: (caddr_t)vax_map_physmem(SMADDR, SMSIZE / VAX_NBPG);
295: if (scr->ss_addr == NULL) {
296: printf(": can not map frame buffer\n");
297: free(scr, M_DEVBUF);
298: return;
299: }
300:
301: scr->ss_cursor =
302: (struct dc503reg *)vax_map_physmem(KA420_CUR_BASE, 1);
303: if (scr->ss_cursor == NULL) {
304: printf(": can not map cursor chip\n");
305: vax_unmap_physmem((vaddr_t)scr->ss_addr,
306: SMSIZE / VAX_NBPG);
307: free(scr, M_DEVBUF);
308: return;
309: }
310:
311: if (smg_setup_screen(scr) != 0) {
312: printf(": initialization failed\n");
313: vax_unmap_physmem((vaddr_t)scr->ss_cursor, 1);
314: vax_unmap_physmem((vaddr_t)scr->ss_addr,
315: SMSIZE / VAX_NBPG);
316: free(scr, M_DEVBUF);
317: return;
318: }
319: }
320: sc->sc_scr = scr;
321:
322: printf("\n%s: %dx%d on-board monochrome framebuffer\n",
323: self->dv_xname, SM_XWIDTH, SM_YWIDTH);
324:
325: aa.console = console;
326: aa.scrdata = &smg_screenlist;
327: aa.accessops = &smg_accessops;
328: aa.accesscookie = sc;
329: aa.defaultscreens = 0;
330:
331: config_found(self, &aa, wsemuldisplaydevprint);
332: }
333:
334: /*
335: * Initialize anything necessary for an emulating wsdisplay to work (i.e.
336: * pick a font, initialize a rasops structure, setup the accessops callbacks.)
337: */
338: int
339: smg_setup_screen(struct smg_screen *ss)
340: {
341: struct rasops_info *ri = &ss->ss_ri;
342:
343: bzero(ri, sizeof(*ri));
344: ri->ri_depth = 1;
345: ri->ri_width = SM_XWIDTH;
346: ri->ri_height = SM_YWIDTH;
347: ri->ri_stride = SM_XWIDTH >> 3;
348: ri->ri_flg = RI_CLEAR | RI_CENTER;
349: ri->ri_bits = (void *)ss->ss_addr;
350: ri->ri_hw = ss;
351:
352: /*
353: * Ask for an unholy big display, rasops will trim this to more
354: * reasonable values.
355: */
356: if (rasops_init(ri, 160, 160) != 0)
357: return (-1);
358:
359: ri->ri_ops.copycols = smg_copycols;
360: ri->ri_ops.erasecols = smg_erasecols;
361:
362: smg_stdscreen.ncols = ri->ri_cols;
363: smg_stdscreen.nrows = ri->ri_rows;
364: smg_stdscreen.textops = &ri->ri_ops;
365: smg_stdscreen.fontwidth = ri->ri_font->fontwidth;
366: smg_stdscreen.fontheight = ri->ri_font->fontheight;
367: smg_stdscreen.capabilities = ri->ri_caps;
368:
369: ss->ss_curcmd = PCCCMD_HSHI;
370: ss->ss_cursor->cmdr = ss->ss_curcmd;
371:
372: return (0);
373: }
374:
375: int
376: smg_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
377: {
378: struct smg_softc *sc = v;
379: struct smg_screen *ss = sc->sc_scr;
380: struct wsdisplay_fbinfo *wdf;
381: struct wsdisplay_curpos *pos;
382:
383: switch (cmd) {
384: case WSDISPLAYIO_GTYPE:
385: *(u_int *)data = WSDISPLAY_TYPE_VAX_MONO;
386: break;
387:
388: case WSDISPLAYIO_GINFO:
389: wdf = (struct wsdisplay_fbinfo *)data;
390: wdf->height = ss->ss_ri.ri_height;
391: wdf->width = ss->ss_ri.ri_width;
392: wdf->depth = ss->ss_ri.ri_depth;
393: wdf->cmsize = 0;
394: break;
395:
396: case WSDISPLAYIO_LINEBYTES:
397: *(u_int *)data = ss->ss_ri.ri_stride;
398: break;
399:
400: case WSDISPLAYIO_GETCMAP:
401: case WSDISPLAYIO_PUTCMAP:
402: case WSDISPLAYIO_GVIDEO:
403: case WSDISPLAYIO_SVIDEO:
404: break;
405:
406: case WSDISPLAYIO_GCURPOS:
407: pos = (struct wsdisplay_curpos *)data;
408: pos->x = ss->ss_curpos.x;
409: pos->y = ss->ss_curpos.y;
410: break;
411: case WSDISPLAYIO_SCURPOS:
412: pos = (struct wsdisplay_curpos *)data;
413: ss->ss_curpos.x = pos->x;
414: ss->ss_curpos.y = pos->y;
415: smg_updatecursor(ss, WSDISPLAY_CURSOR_DOPOS);
416: break;
417: case WSDISPLAYIO_GCURMAX:
418: pos = (struct wsdisplay_curpos *)data;
419: pos->x = pos->y = PCC_CURSOR_SIZE;
420: case WSDISPLAYIO_GCURSOR:
421: return (smg_getcursor(ss, (struct wsdisplay_cursor *)data));
422: case WSDISPLAYIO_SCURSOR:
423: return (smg_setcursor(ss, (struct wsdisplay_cursor *)data));
424: break;
425:
426: default:
427: return (-1);
428: }
429:
430: return (0);
431: }
432:
433: paddr_t
434: smg_mmap(void *v, off_t offset, int prot)
435: {
436: if (offset >= SMSIZE || offset < 0)
437: return (-1);
438:
439: return (SMADDR + offset) >> PGSHIFT;
440: }
441:
442: int
443: smg_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep,
444: int *curxp, int *curyp, long *defattrp)
445: {
446: struct smg_softc *sc = v;
447: struct smg_screen *ss = sc->sc_scr;
448: struct rasops_info *ri = &ss->ss_ri;
449:
450: if (sc->sc_nscreens > 0)
451: return (ENOMEM);
452:
453: *cookiep = ri;
454: *curxp = *curyp = 0;
455: ri->ri_ops.alloc_attr(ri, 0, 0, 0, defattrp);
456: sc->sc_nscreens++;
457:
458: return (0);
459: }
460:
461: void
462: smg_free_screen(void *v, void *cookie)
463: {
464: struct smg_softc *sc = v;
465:
466: sc->sc_nscreens--;
467: }
468:
469: int
470: smg_show_screen(void *v, void *cookie, int waitok,
471: void (*cb)(void *, int, int), void *cbarg)
472: {
473: return (0);
474: }
475:
476: void
477: smg_burner(void *v, u_int on, u_int flags)
478: {
479: struct smg_softc *sc = v;
480: struct smg_screen *ss = sc->sc_scr;
481:
482: ss->ss_cursor->cmdr = on ? ss->ss_curcmd :
483: (ss->ss_curcmd & ~(PCCCMD_FOPA | PCCCMD_ENPA)) | PCCCMD_FOPB;
484: }
485:
486: int
487: smg_getcursor(struct smg_screen *ss, struct wsdisplay_cursor *wdc)
488: {
489: int error;
490:
491: if (wdc->which & WSDISPLAY_CURSOR_DOCUR)
492: wdc->enable = ss->ss_curcmd & PCCCMD_ENPA ? 1 : 0;
493: if (wdc->which & WSDISPLAY_CURSOR_DOPOS) {
494: wdc->pos.x = ss->ss_curpos.x;
495: wdc->pos.y = ss->ss_curpos.y;
496: }
497: if (wdc->which & WSDISPLAY_CURSOR_DOHOT) {
498: wdc->hot.x = ss->ss_curhot.x;
499: wdc->hot.y = ss->ss_curhot.y;
500: }
501: if (wdc->which & WSDISPLAY_CURSOR_DOCMAP) {
502: wdc->cmap.index = 0;
503: wdc->cmap.count = 0;
504: }
505: if (wdc->which & WSDISPLAY_CURSOR_DOSHAPE) {
506: wdc->size.x = wdc->size.y = PCC_CURSOR_SIZE;
507: error = copyout(ss->ss_curimg, wdc->image,
508: sizeof(ss->ss_curimg));
509: if (error != 0)
510: return (error);
511: error = copyout(ss->ss_curmask, wdc->mask,
512: sizeof(ss->ss_curmask));
513: if (error != 0)
514: return (error);
515: }
516:
517: return (0);
518: }
519:
520: int
521: smg_setcursor(struct smg_screen *ss, struct wsdisplay_cursor *wdc)
522: {
523: u_int16_t curfg[PCC_CURSOR_SIZE], curmask[PCC_CURSOR_SIZE];
524: int error;
525:
526: if (wdc->which & WSDISPLAY_CURSOR_DOCMAP) {
527: /* No cursor colormap since we are a B&W device. */
528: if (wdc->cmap.count != 0)
529: return (EINVAL);
530: }
531:
532: /*
533: * First, do the userland-kernel data transfers, so that we can fail
534: * if necessary before altering anything.
535: */
536: if (wdc->which & WSDISPLAY_CURSOR_DOSHAPE) {
537: if (wdc->size.x != PCC_CURSOR_SIZE ||
538: wdc->size.y != PCC_CURSOR_SIZE)
539: return (EINVAL);
540: error = copyin(wdc->image, curfg, sizeof(curfg));
541: if (error != 0)
542: return (error);
543: error = copyin(wdc->mask, curmask, sizeof(curmask));
544: if (error != 0)
545: return (error);
546: }
547:
548: /*
549: * Now update our variables...
550: */
551: if (wdc->which & WSDISPLAY_CURSOR_DOCUR) {
552: if (wdc->enable)
553: ss->ss_curcmd |= PCCCMD_ENPB | PCCCMD_ENPA;
554: else
555: ss->ss_curcmd &= ~(PCCCMD_ENPB | PCCCMD_ENPA);
556: }
557: if (wdc->which & WSDISPLAY_CURSOR_DOPOS) {
558: ss->ss_curpos.x = wdc->pos.x;
559: ss->ss_curpos.y = wdc->pos.y;
560: }
561: if (wdc->which & WSDISPLAY_CURSOR_DOHOT) {
562: ss->ss_curhot.x = wdc->hot.x;
563: ss->ss_curhot.y = wdc->hot.y;
564: }
565: if (wdc->which & WSDISPLAY_CURSOR_DOSHAPE) {
566: bcopy(curfg, ss->ss_curimg, sizeof ss->ss_curimg);
567: bcopy(curmask, ss->ss_curmask, sizeof ss->ss_curmask);
568: }
569:
570: /*
571: * ...and update the cursor
572: */
573: smg_updatecursor(ss, wdc->which);
574:
575: return (0);
576: }
577:
578: void
579: smg_updatecursor(struct smg_screen *ss, u_int which)
580: {
581: u_int i;
582:
583: if (which & (WSDISPLAY_CURSOR_DOPOS | WSDISPLAY_CURSOR_DOHOT)) {
584: ss->ss_cursor->xpos =
585: ss->ss_curpos.x - ss->ss_curhot.x + CUR_XBIAS;
586: ss->ss_cursor->ypos =
587: ss->ss_curpos.y - ss->ss_curhot.y + CUR_YBIAS;
588: }
589: if (which & WSDISPLAY_CURSOR_DOSHAPE) {
590: ss->ss_cursor->cmdr = ss->ss_curcmd | PCCCMD_LODSA;
591: for (i = 0; i < PCC_CURSOR_SIZE; i++)
592: ss->ss_cursor->load = ss->ss_curimg[i];
593: for (i = 0; i < PCC_CURSOR_SIZE; i++)
594: ss->ss_cursor->load = ss->ss_curmask[i];
595: ss->ss_cursor->cmdr = ss->ss_curcmd;
596: } else
597: if (which & WSDISPLAY_CURSOR_DOCUR)
598: ss->ss_cursor->cmdr = ss->ss_curcmd;
599: }
600:
601: /*
602: * Faster console operations
603: */
604:
605: #include <vax/vsa/maskbits.h>
606:
607: void
608: smg_blockmove(struct rasops_info *ri, u_int sx, u_int y, u_int dx, u_int cx,
609: u_int cy, int rop)
610: {
611: int width; /* add to get to same position in next line */
612:
613: unsigned int *psrcLine, *pdstLine;
614: /* pointers to line with current src and dst */
615: unsigned int *psrc; /* pointer to current src longword */
616: unsigned int *pdst; /* pointer to current dst longword */
617:
618: /* following used for looping through a line */
619: unsigned int startmask, endmask; /* masks for writing ends of dst */
620: int nlMiddle; /* whole longwords in dst */
621: int nl; /* temp copy of nlMiddle */
622: int xoffSrc; /* offset (>= 0, < 32) from which to
623: fetch whole longwords fetched in src */
624: int nstart; /* number of ragged bits at start of dst */
625: int nend; /* number of ragged bits at end of dst */
626: int srcStartOver; /* pulling nstart bits from src
627: overflows into the next word? */
628:
629: width = SM_XWIDTH >> 5;
630:
631: /* start at first scanline */
632: psrcLine = pdstLine = ((u_int *)ri->ri_bits) + (y * width);
633:
634: /* x direction doesn't matter for < 1 longword */
635: if (cx <= 32) {
636: int srcBit, dstBit; /* bit offset of src and dst */
637:
638: pdstLine += (dx >> 5);
639: psrcLine += (sx >> 5);
640: psrc = psrcLine;
641: pdst = pdstLine;
642:
643: srcBit = sx & 0x1f;
644: dstBit = dx & 0x1f;
645:
646: while (cy--) {
647: getandputrop(psrc, srcBit, dstBit, cx, pdst, rop);
648: pdst += width;
649: psrc += width;
650: }
651: } else {
652: maskbits(dx, cx, startmask, endmask, nlMiddle);
653: if (startmask)
654: nstart = 32 - (dx & 0x1f);
655: else
656: nstart = 0;
657: if (endmask)
658: nend = (dx + cx) & 0x1f;
659: else
660: nend = 0;
661:
662: xoffSrc = ((sx & 0x1f) + nstart) & 0x1f;
663: srcStartOver = ((sx & 0x1f) + nstart) > 31;
664:
665: if (sx >= dx) { /* move left to right */
666: pdstLine += (dx >> 5);
667: psrcLine += (sx >> 5);
668:
669: while (cy--) {
670: psrc = psrcLine;
671: pdst = pdstLine;
672:
673: if (startmask) {
674: getandputrop(psrc, (sx & 0x1f),
675: (dx & 0x1f), nstart, pdst, rop);
676: pdst++;
677: if (srcStartOver)
678: psrc++;
679: }
680:
681: /* special case for aligned operations */
682: if (xoffSrc == 0) {
683: nl = nlMiddle;
684: while (nl--) {
685: switch (rop) {
686: case RR_CLEAR:
687: *pdst = 0;
688: break;
689: case RR_SET:
690: *pdst = ~0;
691: break;
692: default:
693: *pdst = *psrc;
694: break;
695: }
696: psrc++;
697: pdst++;
698: }
699: } else {
700: nl = nlMiddle + 1;
701: while (--nl) {
702: switch (rop) {
703: case RR_CLEAR:
704: *pdst = 0;
705: break;
706: case RR_SET:
707: *pdst = ~0;
708: break;
709: default:
710: getunalignedword(psrc,
711: xoffSrc, *pdst);
712: break;
713: }
714: pdst++;
715: psrc++;
716: }
717: }
718:
719: if (endmask) {
720: getandputrop(psrc, xoffSrc, 0, nend,
721: pdst, rop);
722: }
723:
724: pdstLine += width;
725: psrcLine += width;
726: }
727: } else { /* move right to left */
728: pdstLine += ((dx + cx) >> 5);
729: psrcLine += ((sx + cx) >> 5);
730: /*
731: * If fetch of last partial bits from source crosses
732: * a longword boundary, start at the previous longword
733: */
734: if (xoffSrc + nend >= 32)
735: --psrcLine;
736:
737: while (cy--) {
738: psrc = psrcLine;
739: pdst = pdstLine;
740:
741: if (endmask) {
742: getandputrop(psrc, xoffSrc, 0, nend,
743: pdst, rop);
744: }
745:
746: nl = nlMiddle + 1;
747: while (--nl) {
748: --psrc;
749: --pdst;
750: switch (rop) {
751: case RR_CLEAR:
752: *pdst = 0;
753: break;
754: case RR_SET:
755: *pdst = ~0;
756: break;
757: default:
758: getunalignedword(psrc, xoffSrc,
759: *pdst);
760: break;
761: }
762: }
763:
764: if (startmask) {
765: if (srcStartOver)
766: --psrc;
767: --pdst;
768: getandputrop(psrc, (sx & 0x1f),
769: (dx & 0x1f), nstart, pdst, rop);
770: }
771:
772: pdstLine += width;
773: psrcLine += width;
774: }
775: }
776: }
777: }
778:
779: void
780: smg_copycols(void *cookie, int row, int src, int dst, int n)
781: {
782: struct rasops_info *ri = cookie;
783:
784: n *= ri->ri_font->fontwidth;
785: src *= ri->ri_font->fontwidth;
786: dst *= ri->ri_font->fontwidth;
787: row *= ri->ri_font->fontheight;
788:
789: smg_blockmove(ri, src, row, dst, n, ri->ri_font->fontheight,
790: RR_COPY);
791: }
792:
793: void
794: smg_erasecols(void *cookie, int row, int col, int num, long attr)
795: {
796: struct rasops_info *ri = cookie;
797: int fg, bg;
798:
799: ri->ri_ops.unpack_attr(cookie, attr, &fg, &bg, NULL);
800:
801: num *= ri->ri_font->fontwidth;
802: col *= ri->ri_font->fontwidth;
803: row *= ri->ri_font->fontheight;
804:
805: smg_blockmove(ri, col, row, col, num, ri->ri_font->fontheight,
806: bg == 0 ? RR_CLEAR : RR_SET);
807: }
808:
809: /*
810: * Console support code
811: */
812:
813: int smgcnprobe(void);
814: void smgcninit(void);
815:
816: int
817: smgcnprobe()
818: {
819: switch (vax_boardtype) {
820: case VAX_BTYP_410:
821: case VAX_BTYP_420:
822: case VAX_BTYP_43:
823: if ((vax_confdata & (KA420_CFG_L3CON | KA420_CFG_MULTU)) != 0)
824: break; /* doesn't use graphics console */
825:
826: if ((vax_confdata & KA420_CFG_VIDOPT) != 0)
827: break; /* there is a color option */
828:
829: return (1);
830:
831: default:
832: break;
833: }
834:
835: return (0);
836: }
837:
838: /*
839: * Called very early to setup the glass tty as console.
840: * Because it's called before the VM system is initialized, virtual memory
841: * for the framebuffer can be stolen directly without disturbing anything.
842: */
843: void
844: smgcninit()
845: {
846: struct smg_screen *ss = &smg_consscr;
847: extern vaddr_t virtual_avail;
848: long defattr;
849: struct rasops_info *ri;
850:
851: ss->ss_addr = (caddr_t)virtual_avail;
852: virtual_avail += SMSIZE;
853: ioaccess((vaddr_t)ss->ss_addr, SMADDR, SMSIZE / VAX_NBPG);
854:
855: ss->ss_cursor = (struct dc503reg *)virtual_avail;
856: virtual_avail += VAX_NBPG;
857: ioaccess((vaddr_t)ss->ss_cursor, KA420_CUR_BASE, 1);
858:
859: virtual_avail = round_page(virtual_avail);
860:
861: /* this had better not fail as we can't recover there */
862: if (smg_setup_screen(ss) != 0)
863: panic(__func__);
864:
865: ri = &ss->ss_ri;
866: ri->ri_ops.alloc_attr(ri, 0, 0, 0, &defattr);
867: wsdisplay_cnattach(&smg_stdscreen, ri, 0, 0, defattr);
868: }
CVSweb