summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2006-07-23 19:17:24 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2006-07-23 19:17:24 +0000
commit8efb29caf1b3a3b8ca7c5024af7baa85d8550b6f (patch)
tree25646da846e62b34533d32b46ff22fa8e4d70397
parent205e73574a86100484ee56e0b187336d5aa25da2 (diff)
Make smg(4) on par with the current state of wsdisplay drivers: make it use
a rasops backend and wsfont, better ioctl conformance, and too many other changes to mention.
-rw-r--r--sys/arch/vax/conf/files.vax6
-rw-r--r--sys/arch/vax/vsa/smg.c790
-rw-r--r--sys/dev/ic/dc503reg.h99
3 files changed, 491 insertions, 404 deletions
diff --git a/sys/arch/vax/conf/files.vax b/sys/arch/vax/conf/files.vax
index b1f8018807f..68e5a365e26 100644
--- a/sys/arch/vax/conf/files.vax
+++ b/sys/arch/vax/conf/files.vax
@@ -1,4 +1,4 @@
-# $OpenBSD: files.vax,v 1.35 2006/07/20 19:15:34 miod Exp $
+# $OpenBSD: files.vax,v 1.36 2006/07/23 19:17:21 miod Exp $
# $NetBSD: files.vax,v 1.60 1999/08/27 20:04:32 ragge Exp $
#
# new style config file for vax architecture
@@ -132,7 +132,9 @@ major {ry = 24}
include "arch/vax/dec/files.dec"
# wscons files.
+include "dev/rasops/files.rasops"
include "dev/wscons/files.wscons"
+include "dev/wsfont/files.wsfont"
# RAM Disk for install floppy
major {rd = 23}
@@ -156,7 +158,7 @@ attach le at vsbus with le_vsbus
file arch/vax/vsa/if_le_vsbus.c le_vsbus
# Monochrome framebuffer on VS3100.
-device smg: wsemuldisplaydev
+device smg: wsemuldisplaydev, rasops1
attach smg at vsbus
file arch/vax/vsa/smg.c smg needs-flag
diff --git a/sys/arch/vax/vsa/smg.c b/sys/arch/vax/vsa/smg.c
index 2d009857be0..a9d8a92325a 100644
--- a/sys/arch/vax/vsa/smg.c
+++ b/sys/arch/vax/vsa/smg.c
@@ -1,6 +1,30 @@
-/* $OpenBSD: smg.c,v 1.9 2006/01/17 20:26:16 miod Exp $ */
+/* $OpenBSD: smg.c,v 1.10 2006/07/23 19:17:23 miod Exp $ */
/* $NetBSD: smg.c,v 1.21 2000/03/23 06:46:44 thorpej Exp $ */
/*
+ * Copyright (c) 2006, Miodrag Vallat
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
* Copyright (c) 1998 Ludd, University of Lule}, Sweden.
* All rights reserved.
*
@@ -34,121 +58,68 @@
#include <sys/param.h>
#include <sys/device.h>
#include <sys/systm.h>
-#include <sys/time.h>
#include <sys/malloc.h>
#include <sys/conf.h>
#include <sys/kernel.h>
-#include <sys/timeout.h>
#include <machine/vsbus.h>
#include <machine/sid.h>
#include <machine/cpu.h>
#include <machine/ka420.h>
-#include <dev/cons.h>
+#include <dev/ic/dc503reg.h>
#include <vax/qbus/dzreg.h>
#include <vax/qbus/dzvar.h>
#include <vax/dec/dzkbdvar.h>
-#include <dev/wscons/wsdisplayvar.h>
#include <dev/wscons/wsconsio.h>
#include <dev/wscons/wscons_callbacks.h>
+#include <dev/wscons/wsdisplayvar.h>
+#include <dev/rasops/rasops.h>
+#include <dev/wsfont/wsfont.h>
#include "dzkbd.h"
-/* Safety guard */
-#ifndef FONT_QVSS8x15
-#include <dev/wsfont/qvss8x15.h>
-#endif
-
/* Screen hardware defs */
-#define SM_COLS 128 /* char width of screen */
-#define SM_ROWS 57 /* rows of char on screen */
-#define SM_CHEIGHT 15 /* lines a char consists of */
-#define SM_NEXTROW (SM_COLS * SM_CHEIGHT)
-#define SM_YWIDTH 864
#define SM_XWIDTH 1024
-
-/* Cursor register definitions */
-#define CUR_CMD 0
-#define CUR_XPOS 4
-#define CUR_YPOS 8
-#define CUR_XMIN_1 12
-#define CUR_XMAX_1 16
-#define CUR_YMIN_1 20
-#define CUR_YMAX_1 24
-#define CUR_XMIN_2 28
-#define CUR_XMAX_2 32
-#define CUR_YMIN_2 36
-#define CUR_YMAX_2 40
-#define CUR_LOAD 44
-
-#define CUR_CMD_TEST 0x8000
-#define CUR_CMD_HSHI 0x4000
-#define CUR_CMD_VBHI 0x2000
-#define CUR_CMD_LODSA 0x1000
-#define CUR_CMD_FORG2 0x0800
-#define CUR_CMD_ENRG2 0x0400
-#define CUR_CMD_FORG1 0x0200
-#define CUR_CMD_ENRG1 0x0100
-#define CUR_CMD_XHWID 0x0080
-#define CUR_CMD_XHCL1 0x0040
-#define CUR_CMD_XHCLP 0x0020
-#define CUR_CMD_XHAIR 0x0010
-#define CUR_CMD_FOPB 0x0008
-#define CUR_CMD_ENPB 0x0004
-#define CUR_CMD_FOPA 0x0002
-#define CUR_CMD_ENPA 0x0001
+#define SM_YWIDTH 864
#define CUR_XBIAS 216 /* Add to cursor position */
#define CUR_YBIAS 33
-#define WRITECUR(addr, val) *(volatile short *)(curaddr + (addr)) = (val)
-static caddr_t curaddr;
-static short curcmd, curx, cury, hotX, hotY;
-static int bgmask, fgmask;
+int smg_match(struct device *, void *, void *);
+void smg_attach(struct device *, struct device *, void *);
+
+struct smg_screen {
+ struct rasops_info ss_ri;
+ caddr_t ss_addr; /* frame buffer address */
+ struct dc503reg *ss_cursor; /* cursor registers */
+ u_int16_t ss_curcmd;
+ struct wsdisplay_curpos ss_curpos, ss_curhot;
+ u_int16_t ss_curimg[PCC_CURSOR_SIZE];
+ u_int16_t ss_curmask[PCC_CURSOR_SIZE];
+};
-static int smg_match(struct device *, struct cfdata *, void *);
-static void smg_attach(struct device *, struct device *, void *);
+/* for console */
+struct smg_screen smg_consscr;
struct smg_softc {
- struct device ss_dev;
+ struct device sc_dev;
+ struct smg_screen *sc_scr;
+ int sc_nscreens;
};
struct cfattach smg_ca = {
- sizeof(struct smg_softc), (cfmatch_t)smg_match, smg_attach,
+ sizeof(struct smg_softc), smg_match, smg_attach,
};
struct cfdriver smg_cd = {
NULL, "smg", DV_DULL
};
-static void smg_cursor(void *, int, int, int);
-static int smg_mapchar(void *, int, unsigned int *);
-static void smg_putchar(void *, int, int, u_int, long);
-static void smg_copycols(void *, int, int, int,int);
-static void smg_erasecols(void *, int, int, int, long);
-static void smg_copyrows(void *, int, int, int);
-static void smg_eraserows(void *, int, int, long);
-static int smg_alloc_attr(void *, int, int, int, long *);
-
-const struct wsdisplay_emulops smg_emulops = {
- smg_cursor,
- smg_mapchar,
- smg_putchar,
- smg_copycols,
- smg_erasecols,
- smg_copyrows,
- smg_eraserows,
- smg_alloc_attr
-};
-
-const struct wsscreen_descr smg_stdscreen = {
- "128x57", SM_COLS, SM_ROWS,
- &smg_emulops,
- 8, SM_CHEIGHT,
- WSSCREEN_UNDERLINE|WSSCREEN_REVERSE,
+struct wsscreen_descr smg_stdscreen = {
+ "std",
};
const struct wsscreen_descr *_smg_scrlist[] = {
@@ -160,25 +131,14 @@ const struct wsscreen_list smg_screenlist = {
_smg_scrlist,
};
-static caddr_t sm_addr;
-
-extern struct wsdisplay_font qvss8x15;
-static u_char *qf;
-
-#define QCHAR(c) (c < 32 ? 32 : (c > 127 ? c - 66 : c - 32))
-#define QFONT(c,line) qf[QCHAR(c) * 15 + line]
-#define SM_ADDR(row, col, line) \
- sm_addr[col + (row * SM_CHEIGHT * SM_COLS) + line * SM_COLS]
-
-
-static int smg_ioctl(void *, u_long, caddr_t, int, struct proc *);
-static paddr_t smg_mmap(void *, off_t, int);
-static int smg_alloc_screen(void *, const struct wsscreen_descr *,
- void **, int *, int *, long *);
-static void smg_free_screen(void *, void *);
-static int smg_show_screen(void *, void *, int,
- void (*) (void *, int, int), void *);
-static void smg_crsr_blink(void *);
+int smg_ioctl(void *, u_long, caddr_t, int, struct proc *);
+paddr_t smg_mmap(void *, off_t, int);
+int smg_alloc_screen(void *, const struct wsscreen_descr *,
+ void **, int *, int *, long *);
+void smg_free_screen(void *, void *);
+int smg_show_screen(void *, void *, int,
+ void (*) (void *, int, int), void *);
+void smg_burner(void *, u_int, u_int);
const struct wsdisplay_accessops smg_accessops = {
smg_ioctl,
@@ -186,284 +146,185 @@ const struct wsdisplay_accessops smg_accessops = {
smg_alloc_screen,
smg_free_screen,
smg_show_screen,
- 0 /* load_font */
-};
-
-struct smg_screen {
- int ss_curx;
- int ss_cury;
- u_char ss_image[SM_ROWS][SM_COLS]; /* Image of current screen */
- u_char ss_attr[SM_ROWS][SM_COLS]; /* Reversed etc... */
+ NULL, /* load_font */
+ NULL, /* scrollback */
+ NULL, /* getchar */
+ smg_burner
};
-static struct smg_screen smg_conscreen;
-static struct smg_screen *curscr;
-
-static struct timeout smg_blink_timeout;
-
-extern int getmajor(void *); /* conf.c */
+int smg_getcursor(struct smg_screen *, struct wsdisplay_cursor *);
+int smg_setup_screen(struct smg_screen *);
+int smg_setcursor(struct smg_screen *, struct wsdisplay_cursor *);
+void smg_updatecursor(struct smg_screen *, u_int);
int
-smg_match(struct device *parent, struct cfdata *match, void *aux)
+smg_match(struct device *parent, void *vcf, void *aux)
{
+ struct cfdata *cf = vcf;
struct vsbus_attach_args *va = aux;
volatile short *curcmd;
volatile short *cfgtst;
short tmp, tmp2;
- if (vax_boardtype == VAX_BTYP_49 || vax_boardtype == VAX_BTYP_1303)
- return 0;
+ switch (vax_boardtype) {
+ default:
+ return (0);
+
+ case VAX_BTYP_410:
+ case VAX_BTYP_420:
+ case VAX_BTYP_43:
+ if (va->va_paddr != KA420_CUR_BASE)
+ return (0);
+
+ /* not present on microvaxes */
+ if ((vax_confdata & KA420_CFG_MULTU) != 0)
+ return (0);
+
+ /*
+ * If the color option board is present, do not attach
+ * unless we are explicitely asked to via device flags.
+ */
+ if ((vax_confdata & KA420_CFG_VIDOPT) != 0 &&
+ (cf->cf_flags & 1) == 0)
+ return (0);
+ break;
+ }
- curcmd = (short *)va->va_addr;
- cfgtst = (short *)vax_map_physmem(VS_CFGTST, 1);
/*
* Try to find the cursor chip by testing the flip-flop.
* If nonexistent, no glass tty.
*/
- curcmd[0] = CUR_CMD_HSHI|CUR_CMD_FOPB;
+ curcmd = (short *)va->va_addr;
+ cfgtst = (short *)vax_map_physmem(VS_CFGTST, 1);
+ curcmd[0] = PCCCMD_HSHI | PCCCMD_FOPB;
DELAY(300000);
tmp = cfgtst[0];
- curcmd[0] = CUR_CMD_TEST|CUR_CMD_HSHI;
+ curcmd[0] = PCCCMD_TEST | PCCCMD_HSHI;
DELAY(300000);
tmp2 = cfgtst[0];
vax_unmap_physmem((vaddr_t)cfgtst, 1);
if (tmp2 != tmp)
- return 20; /* Using periodic interrupt */
+ return (20); /* Using periodic interrupt */
else
- return 0;
+ return (0);
}
void
smg_attach(struct device *parent, struct device *self, void *aux)
{
+ struct smg_softc *sc = (struct smg_softc *)self;
+ struct smg_screen *scr;
struct wsemuldisplaydev_attach_args aa;
+ int console;
+
+ console = (vax_confdata & KA420_CFG_L3CON) == 0;
+ if (console) {
+ scr = &smg_consscr;
+ sc->sc_nscreens = 1;
+ } else {
+ scr = malloc(sizeof(struct smg_screen), M_DEVBUF, M_NOWAIT);
+ if (scr == NULL) {
+ printf(": can not allocate memory\n");
+ return;
+ }
+ bzero(scr, sizeof(struct smg_screen));
+
+ scr->ss_addr =
+ (caddr_t)vax_map_physmem(SMADDR, SMSIZE / VAX_NBPG);
+ if (scr->ss_addr == NULL) {
+ printf(": can not map frame buffer\n");
+ free(scr, M_DEVBUF);
+ return;
+ }
- printf("\n");
- sm_addr = (caddr_t)vax_map_physmem(SMADDR, (SMSIZE/VAX_NBPG));
- curaddr = (caddr_t)vax_map_physmem(KA420_CUR_BASE, 1);
- if (sm_addr == 0) {
- printf("%s: Couldn't alloc graphics memory.\n", self->dv_xname);
- return;
- }
- curscr = &smg_conscreen;
- aa.console = !(vax_confdata & 0x20);
- aa.scrdata = &smg_screenlist;
- aa.accessops = &smg_accessops;
- timeout_set(&smg_blink_timeout, smg_crsr_blink, NULL);
- timeout_add(&smg_blink_timeout, hz / 2);
- curcmd = CUR_CMD_HSHI;
- WRITECUR(CUR_CMD, curcmd);
- qf = qvss8x15.data;
-
- config_found(self, &aa, wsemuldisplaydevprint);
-}
-
-static u_char *cursor;
-static int cur_on;
-
-static void
-smg_crsr_blink(void *arg)
-{
- if (cur_on)
- *cursor ^= 255;
- timeout_add(&smg_blink_timeout, hz / 2);
-}
-
-void
-smg_cursor(void *id, int on, int row, int col)
-{
- struct smg_screen *ss = id;
-
- if (ss == curscr) {
- SM_ADDR(ss->ss_cury, ss->ss_curx, 14) =
- QFONT(ss->ss_image[ss->ss_cury][ss->ss_curx], 14);
- cursor = &SM_ADDR(row, col, 14);
- if ((cur_on = on))
- *cursor ^= 255;
- }
- ss->ss_curx = col;
- ss->ss_cury = row;
-}
+ scr->ss_cursor =
+ (struct dc503reg *)vax_map_physmem(KA420_CUR_BASE, 1);
+ if (scr->ss_cursor == NULL) {
+ printf(": can not map cursor chip\n");
+ vax_unmap_physmem((vaddr_t)scr->ss_addr,
+ SMSIZE / VAX_NBPG);
+ free(scr, M_DEVBUF);
+ return;
+ }
-int
-smg_mapchar(void *id, int uni, unsigned int *index)
-{
- if (uni < 256) {
- *index = uni;
- return (5);
+ if (smg_setup_screen(scr) != 0) {
+ printf(": initialization failed\n");
+ vax_unmap_physmem((vaddr_t)scr->ss_cursor, 1);
+ vax_unmap_physmem((vaddr_t)scr->ss_addr,
+ SMSIZE / VAX_NBPG);
+ free(scr, M_DEVBUF);
+ return;
+ }
}
- *index = ' ';
- return (0);
-}
-
-static void
-smg_putchar(void *id, int row, int col, u_int c, long attr)
-{
- struct smg_screen *ss = id;
- int i;
+ sc->sc_scr = scr;
- c &= 0xff;
-
- ss->ss_image[row][col] = c;
- ss->ss_attr[row][col] = attr;
- if (ss != curscr)
- return;
- for (i = 0; i < 15; i++) {
- unsigned char ch = QFONT(c, i);
-
- SM_ADDR(row, col, i) = (attr & WSATTR_REVERSE ? ~ch : ch);
-
- }
- if (attr & WSATTR_UNDERLINE)
- SM_ADDR(row, col, 14) ^= SM_ADDR(row, col, 14);
-}
+ printf("\n");
-/*
- * copies columns inside a row.
- */
-static void
-smg_copycols(void *id, int row, int srccol, int dstcol, int ncols)
-{
- struct smg_screen *ss = id;
- int i;
+ aa.console = console;
+ aa.scrdata = &smg_screenlist;
+ aa.accessops = &smg_accessops;
+ aa.accesscookie = sc;
- bcopy(&ss->ss_image[row][srccol], &ss->ss_image[row][dstcol], ncols);
- bcopy(&ss->ss_attr[row][srccol], &ss->ss_attr[row][dstcol], ncols);
- if (ss != curscr)
- return;
- for (i = 0; i < SM_CHEIGHT; i++)
- bcopy(&SM_ADDR(row,srccol, i), &SM_ADDR(row, dstcol, i),ncols);
+ config_found(self, &aa, wsemuldisplaydevprint);
}
/*
- * Erases a bunch of chars inside one row.
+ * Initialize anything necessary for an emulating wsdisplay to work (i.e.
+ * pick a font, initialize a rasops structure, setup the accessops callbacks.)
*/
-static void
-smg_erasecols(void *id, int row, int startcol, int ncols, long fillattr)
+int
+smg_setup_screen(struct smg_screen *ss)
{
- struct smg_screen *ss = id;
- int i;
-
- bzero(&ss->ss_image[row][startcol], ncols);
- bzero(&ss->ss_attr[row][startcol], ncols);
- if (ss != curscr)
- return;
- for (i = 0; i < SM_CHEIGHT; i++)
- bzero(&SM_ADDR(row, startcol, i), ncols);
-}
+ struct rasops_info *ri = &ss->ss_ri;
-static void
-smg_copyrows(void *id, int srcrow, int dstrow, int nrows)
-{
- struct smg_screen *ss = id;
- int frows;
-
- bcopy(&ss->ss_image[srcrow][0], &ss->ss_image[dstrow][0],
- nrows * SM_COLS);
- bcopy(&ss->ss_attr[srcrow][0], &ss->ss_attr[dstrow][0],
- nrows * SM_COLS);
- if (ss != curscr)
- return;
- if (nrows > 25) {
- frows = nrows >> 1;
- if (srcrow > dstrow) {
- bcopy(&sm_addr[(srcrow * SM_NEXTROW)],
- &sm_addr[(dstrow * SM_NEXTROW)],
- frows * SM_NEXTROW);
- bcopy(&sm_addr[((srcrow + frows) * SM_NEXTROW)],
- &sm_addr[((dstrow + frows) * SM_NEXTROW)],
- (nrows - frows) * SM_NEXTROW);
- } else {
- bcopy(&sm_addr[((srcrow + frows) * SM_NEXTROW)],
- &sm_addr[((dstrow + frows) * SM_NEXTROW)],
- (nrows - frows) * SM_NEXTROW);
- bcopy(&sm_addr[(srcrow * SM_NEXTROW)],
- &sm_addr[(dstrow * SM_NEXTROW)],
- frows * SM_NEXTROW);
- }
- } else
- bcopy(&sm_addr[(srcrow * SM_NEXTROW)],
- &sm_addr[(dstrow * SM_NEXTROW)], nrows * SM_NEXTROW);
-}
+ bzero(ri, sizeof(*ri));
+ ri->ri_depth = 1;
+ ri->ri_width = SM_XWIDTH;
+ ri->ri_height = SM_YWIDTH;
+ ri->ri_stride = SM_XWIDTH >> 3;
+ ri->ri_flg = RI_CLEAR | RI_CENTER;
+ ri->ri_bits = (void *)ss->ss_addr;
+ ri->ri_hw = ss;
-static void
-smg_eraserows(void *id, int startrow, int nrows, long fillattr)
-{
- struct smg_screen *ss = id;
- int frows;
+ /*
+ * We can not let rasops select our font, because we need to use
+ * a font with right-to-left bit order on this frame buffer.
+ */
+ wsfont_init();
+ if ((ri->ri_wsfcookie = wsfont_find(NULL, 8, 15, 0)) <= 0)
+ return (-1);
+ if (wsfont_lock(ri->ri_wsfcookie, &ri->ri_font,
+ WSDISPLAY_FONTORDER_R2L, WSDISPLAY_FONTORDER_L2R) <= 0)
+ return (-1);
- bzero(&ss->ss_image[startrow][0], nrows * SM_COLS);
- bzero(&ss->ss_attr[startrow][0], nrows * SM_COLS);
- if (ss != curscr)
- return;
- if (nrows > 25) {
- frows = nrows >> 1;
- bzero(&sm_addr[(startrow * SM_NEXTROW)], frows * SM_NEXTROW);
- bzero(&sm_addr[((startrow + frows) * SM_NEXTROW)],
- (nrows - frows) * SM_NEXTROW);
- } else
- bzero(&sm_addr[(startrow * SM_NEXTROW)], nrows * SM_NEXTROW);
-}
+ /*
+ * Ask for an unholy big display, rasops will trim this to more
+ * reasonable values.
+ */
+ if (rasops_init(ri, 160, 160) != 0)
+ return (-1);
-static int
-smg_alloc_attr(void *id, int fg, int bg, int flags, long *attrp)
-{
- *attrp = flags;
- return 0;
-}
+ smg_stdscreen.ncols = ri->ri_cols;
+ smg_stdscreen.nrows = ri->ri_rows;
+ smg_stdscreen.textops = &ri->ri_ops;
+ smg_stdscreen.fontwidth = ri->ri_font->fontwidth;
+ smg_stdscreen.fontheight = ri->ri_font->fontheight;
+ smg_stdscreen.capabilities = ri->ri_caps;
-static void
-setcursor(struct wsdisplay_cursor *v)
-{
- u_short red, green, blue, curfg[16], curmask[16];
- int i;
+ ss->ss_curcmd = PCCCMD_HSHI;
+ ss->ss_cursor->cmdr = ss->ss_curcmd;
- /* Enable cursor */
- if (v->which & WSDISPLAY_CURSOR_DOCUR) {
- if (v->enable)
- curcmd |= CUR_CMD_ENPB|CUR_CMD_ENPA;
- else
- curcmd &= ~(CUR_CMD_ENPB|CUR_CMD_ENPA);
- WRITECUR(CUR_CMD, curcmd);
- }
- if (v->which & WSDISPLAY_CURSOR_DOHOT) {
- hotX = v->hot.x;
- hotY = v->hot.y;
- }
- if (v->which & WSDISPLAY_CURSOR_DOCMAP) {
- /* First background */
- copyin(v->cmap.red, &red, sizeof(u_short));
- copyin(v->cmap.green, &green, sizeof(u_short));
- copyin(v->cmap.blue, &blue, sizeof(u_short));
- bgmask = (((30L * red + 59L * green + 11L * blue) >> 8) >=
- (((1<<8)-1)*50)) ? ~0 : 0;
- copyin(v->cmap.red + 2, &red, sizeof(u_short));
- copyin(v->cmap.green + 2, &green, sizeof(u_short));
- copyin(v->cmap.blue + 2, &blue, sizeof(u_short));
- fgmask = (((30L * red + 59L * green + 11L * blue) >> 8) >=
- (((1<<8)-1)*50)) ? ~0 : 0;
- }
- if (v->which & WSDISPLAY_CURSOR_DOSHAPE) {
- WRITECUR(CUR_CMD, curcmd | CUR_CMD_LODSA);
- copyin(v->image, curfg, sizeof(curfg));
- copyin(v->mask, curmask, sizeof(curmask));
- for (i = 0; i < sizeof(curfg)/2; i++) {
- WRITECUR(CUR_LOAD, (curfg[i] & fgmask) |
- ((curmask[i] & ~curfg[i]) & bgmask));
- }
- for (i = 0; i < sizeof(curmask)/2; i++) {
- WRITECUR(CUR_LOAD, curmask[i]);
- }
- WRITECUR(CUR_CMD, curcmd);
- }
+ return (0);
}
int
smg_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
{
- struct wsdisplay_fbinfo *fb = (void *)data;
- static short curc;
+ struct smg_softc *sc = v;
+ struct smg_screen *ss = sc->sc_scr;
+ struct wsdisplay_fbinfo *wdf;
+ struct wsdisplay_curpos *pos;
switch (cmd) {
case WSDISPLAYIO_GTYPE:
@@ -471,55 +332,56 @@ smg_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
break;
case WSDISPLAYIO_GINFO:
- fb->height = SM_YWIDTH;
- fb->width = SM_XWIDTH;
- fb->depth = 1;
- fb->cmsize = 2;
+ wdf = (struct wsdisplay_fbinfo *)data;
+ wdf->height = ss->ss_ri.ri_height;
+ wdf->width = ss->ss_ri.ri_width;
+ wdf->depth = ss->ss_ri.ri_depth;
+ wdf->cmsize = 0;
break;
- case WSDISPLAYIO_SVIDEO:
- if (*(u_int *)data == WSDISPLAYIO_VIDEO_ON) {
- curcmd = curc;
- } else {
- curc = curcmd;
- curcmd &= ~(CUR_CMD_FOPA|CUR_CMD_ENPA);
- curcmd |= CUR_CMD_FOPB;
- }
- WRITECUR(CUR_CMD, curcmd);
+ case WSDISPLAYIO_LINEBYTES:
+ *(u_int *)data = ss->ss_ri.ri_stride;
break;
+ case WSDISPLAYIO_GETCMAP:
+ case WSDISPLAYIO_PUTCMAP:
case WSDISPLAYIO_GVIDEO:
- *(u_int *)data = (curcmd & CUR_CMD_FOPB ?
- WSDISPLAYIO_VIDEO_OFF : WSDISPLAYIO_VIDEO_ON);
+ case WSDISPLAYIO_SVIDEO:
break;
- case WSDISPLAYIO_SCURSOR:
- setcursor((struct wsdisplay_cursor *)data);
+ case WSDISPLAYIO_GCURPOS:
+ pos = (struct wsdisplay_curpos *)data;
+ pos->x = ss->ss_curpos.x;
+ pos->y = ss->ss_curpos.y;
break;
-
case WSDISPLAYIO_SCURPOS:
- curx = ((struct wsdisplay_curpos *)data)->x;
- cury = ((struct wsdisplay_curpos *)data)->y;
- WRITECUR(CUR_XPOS, curx + CUR_XBIAS);
- WRITECUR(CUR_YPOS, cury + CUR_YBIAS);
+ pos = (struct wsdisplay_curpos *)data;
+ ss->ss_curpos.x = pos->x;
+ ss->ss_curpos.y = pos->y;
+ smg_updatecursor(ss, WSDISPLAY_CURSOR_DOPOS);
break;
-
- case WSDISPLAYIO_GCURPOS:
- ((struct wsdisplay_curpos *)data)->x = curx;
- ((struct wsdisplay_curpos *)data)->y = cury;
+ case WSDISPLAYIO_GCURMAX:
+ pos = (struct wsdisplay_curpos *)data;
+ pos->x = pos->y = PCC_CURSOR_SIZE;
+ case WSDISPLAYIO_GCURSOR:
+ return (smg_getcursor(ss, (struct wsdisplay_cursor *)data));
+ case WSDISPLAYIO_SCURSOR:
+ return (smg_setcursor(ss, (struct wsdisplay_cursor *)data));
break;
default:
- return ENOTTY;
+ return (-1);
}
- return 0;
+
+ return (0);
}
-static paddr_t
+paddr_t
smg_mmap(void *v, off_t offset, int prot)
{
if (offset >= SMSIZE || offset < 0)
- return -1;
+ return (-1);
+
return (SMADDR + offset) >> PGSHIFT;
}
@@ -527,91 +389,192 @@ int
smg_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep,
int *curxp, int *curyp, long *defattrp)
{
- *cookiep = malloc(sizeof(struct smg_screen), M_DEVBUF, M_WAITOK);
- bzero(*cookiep, sizeof(struct smg_screen));
- *curxp = *curyp = *defattrp = 0;
- return 0;
+ struct smg_softc *sc = v;
+ struct smg_screen *ss = sc->sc_scr;
+ struct rasops_info *ri = &ss->ss_ri;
+
+ if (sc->sc_nscreens > 0)
+ return (ENOMEM);
+
+ *cookiep = ri;
+ *curxp = *curyp = 0;
+ ri->ri_ops.alloc_attr(ri, 0, 0, 0, defattrp);
+ sc->sc_nscreens++;
+
+ return (0);
}
void
smg_free_screen(void *v, void *cookie)
{
+ struct smg_softc *sc = v;
+
+ sc->sc_nscreens--;
}
int
smg_show_screen(void *v, void *cookie, int waitok,
void (*cb)(void *, int, int), void *cbarg)
{
- struct smg_screen *ss = cookie;
- int row, col, line;
+ return (0);
+}
- if (ss == curscr)
- return (0);
+void
+smg_burner(void *v, u_int on, u_int flags)
+{
+ struct smg_softc *sc = v;
+ struct smg_screen *ss = sc->sc_scr;
+
+ ss->ss_cursor->cmdr = on ? ss->ss_curcmd :
+ (ss->ss_curcmd & ~(PCCCMD_FOPA | PCCCMD_ENPA)) | PCCCMD_FOPB;
+}
+
+int
+smg_getcursor(struct smg_screen *ss, struct wsdisplay_cursor *wdc)
+{
+ int error;
+
+ if (wdc->which & WSDISPLAY_CURSOR_DOCUR)
+ wdc->enable = ss->ss_curcmd & PCCCMD_ENPA ? 1 : 0;
+ if (wdc->which & WSDISPLAY_CURSOR_DOPOS) {
+ wdc->pos.x = ss->ss_curpos.x;
+ wdc->pos.y = ss->ss_curpos.y;
+ }
+ if (wdc->which & WSDISPLAY_CURSOR_DOHOT) {
+ wdc->hot.x = ss->ss_curhot.x;
+ wdc->hot.y = ss->ss_curhot.y;
+ }
+ if (wdc->which & WSDISPLAY_CURSOR_DOCMAP) {
+ wdc->cmap.index = 0;
+ wdc->cmap.count = 0;
+ }
+ if (wdc->which & WSDISPLAY_CURSOR_DOSHAPE) {
+ wdc->size.x = wdc->size.y = PCC_CURSOR_SIZE;
+ error = copyout(ss->ss_curimg, wdc->image,
+ sizeof(ss->ss_curimg));
+ if (error != 0)
+ return (error);
+ error = copyout(ss->ss_curmask, wdc->mask,
+ sizeof(ss->ss_curmask));
+ if (error != 0)
+ return (error);
+ }
- for (row = 0; row < SM_ROWS; row++)
- for (line = 0; line < SM_CHEIGHT; line++) {
- for (col = 0; col < SM_COLS; col++) {
- u_char s, c = ss->ss_image[row][col];
-
- if (c < 32)
- c = 32;
- s = QFONT(c, line);
- if (ss->ss_attr[row][col] & WSATTR_REVERSE)
- s ^= 255;
- SM_ADDR(row, col, line) = s;
- }
- if (ss->ss_attr[row][col] & WSATTR_UNDERLINE)
- SM_ADDR(row, col, line) = 255;
- }
- cursor = &sm_addr[(ss->ss_cury * SM_CHEIGHT * SM_COLS) + ss->ss_curx +
- ((SM_CHEIGHT - 1) * SM_COLS)];
- curscr = ss;
return (0);
}
-cons_decl(smg);
+int
+smg_setcursor(struct smg_screen *ss, struct wsdisplay_cursor *wdc)
+{
+ u_int16_t curfg[PCC_CURSOR_SIZE], curmask[PCC_CURSOR_SIZE];
+ int error;
+
+ if (wdc->which & WSDISPLAY_CURSOR_DOCMAP) {
+ /* No cursor colormap since we are a B&W device. */
+ if (wdc->cmap.count != 0)
+ return (EINVAL);
+ }
+
+ /*
+ * First, do the userland-kernel data transfers, so that we can fail
+ * if necessary before altering anything.
+ */
+ if (wdc->which & WSDISPLAY_CURSOR_DOSHAPE) {
+ if (wdc->size.x != PCC_CURSOR_SIZE ||
+ wdc->size.y != PCC_CURSOR_SIZE)
+ return (EINVAL);
+ error = copyin(wdc->image, curfg, sizeof(curfg));
+ if (error != 0)
+ return (error);
+ error = copyin(wdc->mask, curmask, sizeof(curmask));
+ if (error != 0)
+ return (error);
+ }
+
+ /*
+ * Now update our variables...
+ */
+ if (wdc->which & WSDISPLAY_CURSOR_DOCUR) {
+ if (wdc->enable)
+ ss->ss_curcmd |= PCCCMD_ENPB | PCCCMD_ENPA;
+ else
+ ss->ss_curcmd &= ~(PCCCMD_ENPB | PCCCMD_ENPA);
+ }
+ if (wdc->which & WSDISPLAY_CURSOR_DOPOS) {
+ ss->ss_curpos.x = wdc->pos.x;
+ ss->ss_curpos.y = wdc->pos.y;
+ }
+ if (wdc->which & WSDISPLAY_CURSOR_DOHOT) {
+ ss->ss_curhot.x = wdc->hot.x;
+ ss->ss_curhot.y = wdc->hot.y;
+ }
+ if (wdc->which & WSDISPLAY_CURSOR_DOSHAPE) {
+ bcopy(curfg, ss->ss_curimg, sizeof ss->ss_curimg);
+ bcopy(curmask, ss->ss_curmask, sizeof ss->ss_curmask);
+ }
+
+ /*
+ * ...and update the cursor
+ */
+ smg_updatecursor(ss, wdc->which);
+
+ return (0);
+}
void
-smgcninit(cndev)
- struct consdev *cndev;
+smg_updatecursor(struct smg_screen *ss, u_int which)
{
- extern void lkccninit(struct consdev *);
- extern int lkccngetc(dev_t);
- extern int dz_vsbus_lk201_cnattach(int);
- /* Clear screen */
- memset(sm_addr, 0, 128*864);
-
- curscr = &smg_conscreen;
- wsdisplay_cnattach(&smg_stdscreen, &smg_conscreen, 0, 0, 0);
- cn_tab->cn_pri = CN_INTERNAL;
- qf = qvss8x15.data;
+ u_int i;
-#if NDZKBD > 0
- dzkbd_cnattach(0); /* Connect keyboard and screen together */
-#endif
+ if (which & (WSDISPLAY_CURSOR_DOPOS | WSDISPLAY_CURSOR_DOHOT)) {
+ ss->ss_cursor->xpos =
+ ss->ss_curpos.x - ss->ss_curhot.x + CUR_XBIAS;
+ ss->ss_cursor->ypos =
+ ss->ss_curpos.y - ss->ss_curhot.y + CUR_YBIAS;
+ }
+ if (which & WSDISPLAY_CURSOR_DOSHAPE) {
+ ss->ss_cursor->cmdr = ss->ss_curcmd | PCCCMD_LODSA;
+ for (i = 0; i < PCC_CURSOR_SIZE; i++)
+ ss->ss_cursor->load = ss->ss_curimg[i];
+ for (i = 0; i < PCC_CURSOR_SIZE; i++)
+ ss->ss_cursor->load = ss->ss_curmask[i];
+ ss->ss_cursor->cmdr = ss->ss_curcmd;
+ } else
+ if (which & WSDISPLAY_CURSOR_DOCUR)
+ ss->ss_cursor->cmdr = ss->ss_curcmd;
}
+#include <dev/cons.h>
+cons_decl(smg);
+
/*
* Called very early to setup the glass tty as console.
- * Because it's called before the VM system is inited, virtual memory
+ * Because it's called before the VM system is initialized, virtual memory
* for the framebuffer can be stolen directly without disturbing anything.
*/
void
smgcnprobe(cndev)
struct consdev *cndev;
{
+ struct smg_screen *ss = &smg_consscr;
extern vaddr_t virtual_avail;
+ extern int getmajor(void *); /* conf.c */
switch (vax_boardtype) {
case VAX_BTYP_410:
case VAX_BTYP_420:
case VAX_BTYP_43:
- if ((vax_confdata & KA420_CFG_L3CON) ||
- (vax_confdata & KA420_CFG_MULTU))
+ if ((vax_confdata & (KA420_CFG_L3CON | KA420_CFG_MULTU)) != 0)
break; /* doesn't use graphics console */
- sm_addr = (caddr_t)virtual_avail;
+
+ ss->ss_addr = (caddr_t)virtual_avail;
virtual_avail += SMSIZE;
- ioaccess((vaddr_t)sm_addr, SMADDR, (SMSIZE/VAX_NBPG));
+ ioaccess((vaddr_t)ss->ss_addr, SMADDR, SMSIZE / VAX_NBPG);
+
+ ss->ss_cursor = (struct dc503reg *)virtual_avail;
+ virtual_avail += PAGE_SIZE; /* VAX_NBPG */
+ ioaccess((vaddr_t)ss->ss_cursor, KA420_CUR_BASE, 1);
+
cndev->cn_pri = CN_INTERNAL;
cndev->cn_dev = makedev(getmajor(wsdisplayopen), 0);
break;
@@ -620,3 +583,26 @@ smgcnprobe(cndev)
break;
}
}
+
+void
+smgcninit(struct consdev *cndev)
+{
+ struct smg_screen *ss = &smg_consscr;
+ long defattr;
+ struct rasops_info *ri;
+ extern void lkccninit(struct consdev *);
+ extern int lkccngetc(dev_t);
+ extern int dz_vsbus_lk201_cnattach(int);
+
+ /* ss_addr and ss_cursor initialized in smgcnprobe() */
+ if (smg_setup_screen(ss) != 0)
+ return;
+
+ ri = &ss->ss_ri;
+ ri->ri_ops.alloc_attr(ri, 0, 0, 0, &defattr);
+ wsdisplay_cnattach(&smg_stdscreen, ri, 0, 0, defattr);
+
+#if NDZKBD > 0
+ dzkbd_cnattach(0); /* Connect keyboard and screen together */
+#endif
+}
diff --git a/sys/dev/ic/dc503reg.h b/sys/dev/ic/dc503reg.h
new file mode 100644
index 00000000000..26ed195f50c
--- /dev/null
+++ b/sys/dev/ic/dc503reg.h
@@ -0,0 +1,99 @@
+/* $OpenBSD: dc503reg.h,v 1.1 2006/07/23 19:17:23 miod Exp $ */
+/* $NetBSD: pmreg.h,v 1.7 2005/12/11 12:18:36 christos Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ralph Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)pmreg.h 8.1 (Berkeley) 6/10/93
+ */
+
+/*
+ * Layout of the programmable cursor chip (DC503) registers.
+ * All registers are 16 bit wide.
+ */
+
+#define PCC_CMD 0x00 /* cursor command register */
+#define PCCCMD_TEST 0x8000
+#define PCCCMD_HSHI 0x4000
+#define PCCCMD_VBHI 0x2000
+#define PCCCMD_LODSA 0x1000
+#define PCCCMD_FORG2 0x0800
+#define PCCCMD_ENRG2 0x0400
+#define PCCCMD_FORG1 0x0200
+#define PCCCMD_ENRG1 0x0100
+#define PCCCMD_XHWID 0x0080
+#define PCCCMD_XHCL1 0x0040
+#define PCCCMD_XHCLP 0x0020
+#define PCCCMD_XHAIR 0x0010
+#define PCCCMD_FOPB 0x0008
+#define PCCCMD_ENPB 0x0004
+#define PCCCMD_FOPA 0x0002
+#define PCCCMD_ENPA 0x0001
+
+#define PCC_XPOS 0x04 /* cursor X position */
+#define PCC_YPOS 0x08 /* cursor Y position */
+#define PCC_XMIN_1 0x0c /* region 1 left edge */
+#define PCC_XMAX_1 0x10 /* region 1 right edge */
+#define PCC_YMIN_1 0x14 /* region 1 top edge */
+#define PCC_YMAX_1 0x18 /* region 1 bottom edge */
+#define PCC_XMIN_2 0x1c /* region 2 left edge */
+#define PCC_XMAX_2 0x20 /* region 2 right edge */
+#define PCC_YMIN_2 0x24 /* region 2 top edge */
+#define PCC_YMAX_2 0x28 /* region 2 bottom edge */
+#define PCC_LOAD 0x2c /* cursor pattern load */
+
+struct dc503reg {
+ volatile u_int16_t cmdr;
+ int16_t pad1;
+ volatile u_int16_t xpos;
+ int16_t pad2;
+ volatile u_int16_t ypos;
+ int16_t pad3;
+ volatile u_int16_t xmin1;
+ int16_t pad4;
+ volatile u_int16_t xmax1;
+ int16_t pad5;
+ volatile u_int16_t ymin1;
+ int16_t pad6;
+ volatile u_int16_t ymax1;
+ int16_t pad7[9];
+ volatile u_int16_t xmin2;
+ int16_t pad8;
+ volatile u_int16_t xmax2;
+ int16_t pad9;
+ volatile u_int16_t ymin2;
+ int16_t pad10;
+ volatile u_int16_t ymax2;
+ int16_t pad11;
+ volatile u_int16_t load;
+};
+
+#define PCC_CURSOR_SIZE 16