Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <sys/cdefs.h>
- __KERNEL_RCSID(0, "$NetBSD: lcg.c,v 1.1 2004/01/27 10:24:00 Blaz Antonic Exp $");
- #include <sys/param.h>
- #include <sys/device.h>
- #include <sys/systm.h>
- #include <sys/callout.h>
- #include <sys/time.h>
- #include <sys/types.h>
- #include <sys/malloc.h>
- #include <sys/conf.h>
- #include <sys/kernel.h>
- #include <machine/vsbus.h>
- #include <machine/sid.h>
- #include <machine/cpu.h>
- //#define NO_EXPERIMENTAL
- #ifndef NO_EXPERIMENTAL
- #include <machine/lcgreg.h>
- #endif
- #include <dev/cons.h>
- #include <dev/dec/dzreg.h>
- #include <dev/dec/dzvar.h>
- #include <dev/dec/dzkbdvar.h>
- #include <dev/wscons/wsdisplayvar.h>
- #include <dev/wscons/wsconsio.h>
- #include <dev/wscons/wscons_callbacks.h>
- #include "machine/scb.h"
- #include "dzkbd.h"
- #include "opt_wsfont.h"
- /* Safety guard */
- #include <dev/wsfont/qvss8x15.h>
- /* Screen hardware defs */
- #define LCG_COLS 160 /* char width of screen */
- #define LCG_ROWS 68 /* rows of char on screen */
- #define LCG_CHEIGHT 15 /* lines a char consists of */
- #define LCG_CWIDTH 8 /* cols a char consists of */
- #define LCG_ONEROW (LCG_COLS * LCG_CHEIGHT * LCG_CWIDTH)
- #define LCG_YSIZE 1024
- #define LCG_XSIZE 1280
- #define LCG_TEXT_COLOR 0xff
- #define LCG_FB_ADDR 0x21801000 /* Frame buffer */
- #define LCG_FB_SIZE (LCG_XSIZE * LCG_YSIZE)
- // #define LCG_FB_SIZE 0x00200000 /* 8MB in size */
- #ifndef NO_EXPERIMENTAL
- #define LCG_REG_ADDR 0x20100000 /* LCG registers */
- #define LCG_REG_SIZE 0x4000 /* 16384 bytes */
- #define LCG_LUT_ADDR 0x21800800 /* LUT right before onscreen FB */
- #define LCG_LUT_OFFSET 0x00000800
- #define LCG_LUT_SIZE 0x800 /* 2048 bytes */
- #endif
- static int lcg_match(struct device *, struct cfdata *, void *);
- static void lcg_attach(struct device *, struct device *, void *);
- struct lcg_softc {
- struct device ss_dev;
- };
- CFATTACH_DECL_NEW(lcg, sizeof(struct lcg_softc),
- lcg_match, lcg_attach, NULL, NULL);
- static void lcg_cursor(void *, int, int, int);
- static int lcg_mapchar(void *, int, unsigned int *);
- static void lcg_putchar(void *, int, int, u_int, long);
- static void lcg_copycols(void *, int, int, int,int);
- static void lcg_erasecols(void *, int, int, int, long);
- static void lcg_copyrows(void *, int, int, int);
- static void lcg_eraserows(void *, int, int, long);
- static int lcg_allocattr(void *, int, int, int, long *);
- const struct wsdisplay_emulops lcg_emulops = {
- lcg_cursor,
- lcg_mapchar,
- lcg_putchar,
- lcg_copycols,
- lcg_erasecols,
- lcg_copyrows,
- lcg_eraserows,
- lcg_allocattr
- };
- const struct wsscreen_descr lcg_stdscreen = {
- "160x68", LCG_COLS, LCG_ROWS,
- &lcg_emulops,
- 8, LCG_CHEIGHT,
- WSSCREEN_UNDERLINE|WSSCREEN_REVERSE,
- };
- const struct wsscreen_descr *_lcg_scrlist[] = {
- &lcg_stdscreen,
- };
- const struct wsscreen_list lcg_screenlist = {
- sizeof(_lcg_scrlist) / sizeof(struct wsscreen_descr *),
- _lcg_scrlist,
- };
- static char *lcgaddr;
- #ifndef NO_EXPERMINETAL
- static char *lutaddr;
- static long *regaddr;
- #endif
- 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 LCG_ADDR(row, col, line, dot) \
- lcgaddr[(col * LCG_CWIDTH) + (row * LCG_CHEIGHT * LCG_XSIZE) + \
- line * LCG_XSIZE + dot]
- static int lcg_ioctl(void *, void *, u_long, void *, int, struct lwp *);
- static paddr_t lcg_mmap(void *, void *, off_t, int);
- static int lcg_alloc_screen(void *, const struct wsscreen_descr *,
- void **, int *, int *, long *);
- static void lcg_free_screen(void *, void *);
- static int lcg_show_screen(void *, void *, int,
- void (*) (void *, int, int), void *);
- static void lcg_crsr_blink(void *);
- const struct wsdisplay_accessops lcg_accessops = {
- lcg_ioctl,
- lcg_mmap,
- lcg_alloc_screen,
- lcg_free_screen,
- lcg_show_screen,
- 0 /* load_font */
- };
- struct lcg_screen {
- int ss_curx;
- int ss_cury;
- u_char ss_image[LCG_ROWS][LCG_COLS]; /* Image of current screen */
- u_char ss_attr[LCG_ROWS][LCG_COLS]; /* Reversed etc... */
- };
- static struct lcg_screen lcg_conscreen;
- static struct lcg_screen *curscr;
- static callout_t lcg_cursor_ch;
- int
- lcg_match(struct device *parent, struct cfdata *match, void *aux)
- {
- struct vsbus_softc *sc = device_private(parent);
- struct vsbus_attach_args *va = aux;
- char *ch = (char *)va->va_addr;
- if ((vax_boardtype != VAX_BTYP_46) && (vax_boardtype != VAX_BTYP_48))
- return 0;
- *ch = 1;
- if ((*ch & 1) == 0)
- return 0;
- *ch = 0;
- if ((*ch & 1) != 0)
- return 0;
- sc->sc_mask = 0x04; /* XXX - should be generated */
- scb_fake(0x120, 0x15);
- return 20;
- }
- void
- lcg_attach(struct device *parent, struct device *self, void *aux)
- {
- struct vsbus_attach_args *va = aux;
- struct wsemuldisplaydev_attach_args aa;
- #ifndef NO_EXPERIMENTAL
- int i, j, k;
- long video_conf;
- #endif
- printf("\n");
- aa.console = lcgaddr != NULL;
- lcgaddr = (void *)vax_map_physmem(va->va_paddr, (LCG_FB_SIZE/VAX_NBPG));
- if (lcgaddr == 0) {
- printf("%s: Couldn't allocate graphics memory.\n", self->dv_xname);
- return;
- }
- #ifndef NO_EXPERIMENTAL
- lutaddr = (void *)vax_map_physmem(LCG_LUT_ADDR, (LCG_LUT_SIZE/VAX_NBPG));
- regaddr = (long*)vax_map_physmem(LCG_REG_ADDR, (LCG_REG_SIZE/VAX_NBPG));
- for (i = 0; i < 256; i++)
- for (j = 0; j < 50; j++)
- for (k = 0; k < 4; k++)
- if (k != 3)
- lcgaddr[(j * LCG_XSIZE) + (i * 5) + k + (900 * LCG_XSIZE)] = i;
- for (i = 255; i >= 0; i--) {
- lutaddr[i * 8 + 0] = 0;
- lutaddr[i * 8 + 1] = i; // address
- lutaddr[i * 8 + 2] = 1;
- lutaddr[i * 8 + 3] = 0; // red
- lutaddr[i * 8 + 4] = 1;
- lutaddr[i * 8 + 5] = 0; // green
- lutaddr[i * 8 + 6] = 1;
- lutaddr[i * 8 + 7] = i; // blue
- }
- video_conf = 0;
- video_conf |= (3 << 30);
- video_conf |= (3 << 28);
- video_conf |= (0 << 26);
- video_conf |= (0 << 25);
- video_conf |= (0 << 24);
- video_conf |= (0 << 23);
- video_conf |= (0 << 22);
- video_conf |= (0 << 16);
- video_conf |= (0 << 15);
- video_conf |= (0 << 14);
- video_conf |= (1 << 13);
- video_conf |= (1 << 12);
- video_conf |= (1 << 11);
- video_conf |= (1 << 10);
- video_conf |= (2 << 8);
- video_conf |= (1 << 6);
- video_conf |= (0 << 5);
- video_conf |= (1 << 4);
- video_conf |= (1 << 3);
- video_conf |= (0 << 2);
- video_conf |= (1 << 1);
- video_conf |= (1 << 0);
- regaddr[LCG_REG_VIDEO_CONFIG/4] = video_conf;
- /* vital !!! */
- regaddr[LCG_REG_LUT_CONSOLE_SEL/4] = 1;
- regaddr[LCG_REG_LUT_COLOR_BASE_W/4] = LCG_LUT_OFFSET;
- /* 787 x 100 worked */
- i = 0;
- while (i < 783) {
- j = 0;
- while (j < 100) j++;
- i++;
- }
- regaddr[LCG_REG_LUT_CONSOLE_SEL/4] = 0;
- #if 0
- /* delay not needed, only here to see the result on color bar */
- i = 0;
- while (i < 35000) {
- j = 0;
- while (j < 1000) j++;
- i++;
- }
- #endif
- #endif
- curscr = &lcg_conscreen;
- aa.scrdata = &lcg_screenlist;
- aa.accessops = &lcg_accessops;
- qf = qvss8x15.data;
- /* enable software cursor */
- callout_init(&lcg_cursor_ch, 0);
- callout_reset(&lcg_cursor_ch, hz / 2, lcg_crsr_blink, NULL);
- config_found(self, &aa, wsemuldisplaydevprint);
- }
- static char *cursor;
- static int cur_on;
- static void
- lcg_crsr_blink(void *arg)
- {
- int dot;
- if (cur_on)
- for (dot = 0; dot < LCG_CWIDTH; dot++)
- cursor[dot] ^= LCG_TEXT_COLOR;
- callout_reset(&lcg_cursor_ch, hz / 2, lcg_crsr_blink, NULL);
- }
- void
- lcg_cursor(void *id, int on, int row, int col)
- {
- struct lcg_screen *ss = id;
- int dot;
- if (ss == NULL)
- return;
- if (ss == curscr) {
- char ch = QFONT(ss->ss_image[ss->ss_cury][ss->ss_curx], 14);
- for (dot = 0; dot < LCG_CWIDTH; dot++)
- LCG_ADDR(ss->ss_cury, ss->ss_curx, LCG_CHEIGHT - 1, dot) =
- (LCG_TEXT_COLOR * ((ch >> dot) & 1));
- cursor = &LCG_ADDR(row, col, 14, 0);
- cur_on = on;
- #if 0
- if ((cur_on = on))
- for (dot = 0; dot < LCG_CWIDTH; dot++)
- cursor[dot] ^= LCG_TEXT_COLOR;
- #endif
- }
- ss->ss_curx = col;
- ss->ss_cury = row;
- }
- int
- lcg_mapchar(void *id, int uni, unsigned int *index)
- {
- if (uni < 256) {
- *index = uni;
- return (5);
- }
- *index = ' ';
- return (0);
- }
- static void
- lcg_putchar(void *id, int row, int col, u_int c, long attr)
- {
- struct lcg_screen *ss = id;
- int i, j;
- c &= 0xff;
- ss->ss_image[row][col] = c;
- ss->ss_attr[row][col] = attr;
- if (ss != curscr)
- return;
- for (i = 0; i < LCG_CHEIGHT; i++) {
- unsigned char ch = QFONT(c, i);
- char dot;
- for (j = 0; j < LCG_CWIDTH; j++) {
- dot = (LCG_TEXT_COLOR * ((ch >> j) & 1));
- if (attr & WSATTR_REVERSE)
- dot = (~dot) & 0xff;
- LCG_ADDR(row, col, i, j) = dot;
- }
- }
- if (attr & WSATTR_UNDERLINE) {
- char *p = &LCG_ADDR(row, col, i, 0);
- for (i = 0; i < LCG_CWIDTH; i++)
- p[i] = ~p[i];
- }
- }
- /*
- * copies columns inside a row.
- */
- static void
- lcg_copycols(void *id, int row, int srccol, int dstcol, int ncols)
- {
- struct lcg_screen *ss = id;
- int i;
- 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 < LCG_CHEIGHT; i++)
- memcpy(&LCG_ADDR(row, dstcol, i, 0),
- &LCG_ADDR(row,srccol, i, 0), ncols * LCG_CWIDTH);
- }
- /*
- * Erases a bunch of chars inside one row.
- */
- static void
- lcg_erasecols(void *id, int row, int startcol, int ncols, long fillattr)
- {
- struct lcg_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 < LCG_CHEIGHT; i++)
- memset(&LCG_ADDR(row, startcol, i, 0), 0, ncols * LCG_CWIDTH);
- }
- static void
- lcg_copyrows(void *id, int srcrow, int dstrow, int nrows)
- {
- struct lcg_screen *ss = id;
- bcopy(&ss->ss_image[srcrow][0], &ss->ss_image[dstrow][0],
- nrows * LCG_COLS);
- bcopy(&ss->ss_attr[srcrow][0], &ss->ss_attr[dstrow][0],
- nrows * LCG_COLS);
- if (ss != curscr)
- return;
- memcpy(&lcgaddr[dstrow * LCG_ONEROW],
- &lcgaddr[srcrow * LCG_ONEROW], nrows * LCG_ONEROW);
- }
- static void
- lcg_eraserows(void *id, int startrow, int nrows, long fillattr)
- {
- struct lcg_screen *ss = id;
- bzero(&ss->ss_image[startrow][0], nrows * LCG_COLS);
- bzero(&ss->ss_attr[startrow][0], nrows * LCG_COLS);
- if (ss != curscr)
- return;
- memset(&lcgaddr[startrow * LCG_ONEROW], 0, nrows * LCG_ONEROW);
- }
- static int
- lcg_allocattr(void *id, int fg, int bg, int flags, long *attrp)
- {
- *attrp = flags;
- return 0;
- }
- int
- lcg_ioctl(void *v, void *vs, u_long cmd, void * data, int flag, struct lwp *p)
- {
- struct wsdisplay_fbinfo *fb = (void *)data;
- switch (cmd) {
- case WSDISPLAYIO_GTYPE:
- *(u_int *)data = WSDISPLAY_TYPE_LCG;
- break;
- case WSDISPLAYIO_GINFO:
- fb->height = LCG_YSIZE;
- fb->width = LCG_XSIZE;
- fb->depth = 1;
- fb->cmsize = 2;
- break;
- #if 0
- 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);
- break;
- case WSDISPLAYIO_GVIDEO:
- *(u_int *)data = (curcmd & CUR_CMD_FOPB ?
- WSDISPLAYIO_VIDEO_OFF : WSDISPLAYIO_VIDEO_ON);
- break;
- #endif
- default:
- return EPASSTHROUGH;
- }
- return 0;
- }
- static paddr_t
- lcg_mmap(void *v, void *vs, off_t offset, int prot)
- {
- if (offset >= LCG_FB_SIZE || offset < 0)
- return -1;
- return (LCG_FB_ADDR + offset) >> PGSHIFT;
- }
- int
- lcg_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep,
- int *curxp, int *curyp, long *defattrp)
- {
- *cookiep = malloc(sizeof(struct lcg_screen), M_DEVBUF, M_WAITOK);
- bzero(*cookiep, sizeof(struct lcg_screen));
- *curxp = *curyp = *defattrp = 0;
- return 0;
- }
- void
- lcg_free_screen(void *v, void *cookie)
- {
- }
- int
- lcg_show_screen(void *v, void *cookie, int waitok,
- void (*cb)(void *, int, int), void *cbarg)
- {
- struct lcg_screen *ss = cookie;
- int row, col, line, dot;
- if (ss == curscr)
- return (0);
- for (row = 0; row < LCG_ROWS; row++)
- for (col = 0; col < LCG_COLS; col++) {
- for (line = 0; line < LCG_CHEIGHT; line++) {
- 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;
- for (dot = 0; dot < LCG_CWIDTH; dot++)
- LCG_ADDR(row, col, line, dot) =
- (LCG_TEXT_COLOR * ((s >> dot) & 1));
- }
- if (ss->ss_attr[row][col] & WSATTR_UNDERLINE)
- for (dot = 0; dot < LCG_CWIDTH; dot++)
- LCG_ADDR(row, col, LCG_CHEIGHT - 1, dot) ^= LCG_TEXT_COLOR;
- }
- cur_on = 1;
- cursor = &lcgaddr[(ss->ss_cury * LCG_ONEROW) +
- ((LCG_CHEIGHT - 1) * LCG_COLS * LCG_CWIDTH) +
- (ss->ss_curx * LCG_CWIDTH)];
- curscr = ss;
- return (0);
- }
- cons_decl(lcg);
- #if 0
- cdev_decl(wsdisplay);
- #endif
- void
- lcgcninit(struct consdev *cndev)
- {
- /* Clear screen */
- memset(lcgaddr, 0, LCG_XSIZE * LCG_YSIZE);
- curscr = &lcg_conscreen;
- wsdisplay_cnattach(&lcg_stdscreen, &lcg_conscreen, 0, 0, 0);
- cn_tab->cn_pri = CN_INTERNAL;
- qf = qvss8x15.data;
- #if NDZKBD > 0
- dzkbd_cnattach(0); /* Connect keyboard and screen together */
- #endif
- }
- int wsdisplayopen(dev_t dev, int flag, int mode, struct lwp *l);
- /*
- * Called very early to setup the glass tty as console.
- * Because it's called before the VM system is inited, virtual memory
- * for the framebuffer can be stolen directly without disturbing anything.
- */
- void
- lcgcnprobe(struct consdev *cndev)
- {
- extern vaddr_t virtual_avail;
- extern const struct cdevsw wsdisplay_cdevsw;
- if ((vax_boardtype != VAX_BTYP_46) && (vax_boardtype != VAX_BTYP_48))
- return; /* Only for 4000/60 and VLC */
- if (vax_confdata & 8)
- return; /* Diagnostic console */
- lcgaddr = (void *)virtual_avail;
- virtual_avail += LCG_FB_SIZE;
- #ifndef NO_EXPERIMENTAL
- virtual_avail += LCG_LUT_SIZE;
- virtual_avail += LCG_REG_SIZE;
- #endif
- ioaccess((vaddr_t)lcgaddr, LCG_FB_ADDR, (LCG_FB_SIZE/VAX_NBPG));
- cndev->cn_pri = CN_INTERNAL;
- cndev->cn_dev = makedev(cdevsw_lookup_major(&wsdisplay_cdevsw), 0);
- //cndev->cn_dev = makedev(major(wsdisplayopen), 0);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement