static void newport_putchar(void *c, int row, int col, u_int ch, long attr) { struct rasops_info *ri = c; struct vcons_screen *scr = ri->ri_hw; struct newport_devconfig *dc = scr->scr_cookie; struct wsdisplay_font *font = ri->ri_font; uint8_t *bitmap = (u_int8_t *)font->data + (ch - font->firstchar) * font->fontheight * font->stride; uint32_t pattern; int i; int x = col * font->fontwidth + ri->ri_xorigin; int y = row * font->fontheight + ri->ri_yorigin; rex3_wait_gfifo(dc); rex3_write(dc, REX3_REG_DRAWMODE0, REX3_DRAWMODE0_OPCODE_DRAW | REX3_DRAWMODE0_ADRMODE_BLOCK | REX3_DRAWMODE0_STOPONX | REX3_DRAWMODE0_ENZPATTERN | REX3_DRAWMODE0_ZPOPAQUE); rex3_write(dc, REX3_REG_DRAWMODE1, REX3_DRAWMODE1_PLANES_CI | REX3_DRAWMODE1_DD_DD8 | REX3_DRAWMODE1_RWPACKED | REX3_DRAWMODE1_HD_HD8 | REX3_DRAWMODE1_COMPARE_LT | REX3_DRAWMODE1_COMPARE_EQ | REX3_DRAWMODE1_COMPARE_GT | REX3_DRAWMODE1_LO_SRC); rex3_write(dc, REX3_REG_XYSTARTI, (x << REX3_XYSTARTI_XSHIFT) | y); rex3_write(dc, REX3_REG_XYENDI, (x + font->fontwidth - 1) << REX3_XYENDI_XSHIFT); rex3_write(dc, REX3_REG_COLORI, NEWPORT_ATTR_FG(attr)); rex3_write(dc, REX3_REG_COLORBACK, NEWPORT_ATTR_BG(attr)); rex3_write(dc, REX3_REG_WRMASK, 0xffffffff); for (i = 0; i < font->fontheight; i++) { /* XXX Works only with font->fontwidth == 8 XXX */ pattern = *bitmap << 24; rex3_write_go(dc, REX3_REG_ZPATTERN, pattern); bitmap += font->stride; } rex3_wait_gfifo(dc); }
/**** Helper functions ****/ static void newport_fill_rectangle(struct newport_devconfig *dc, int x1, int y1, int x2, int y2, uint8_t color) { rex3_wait_gfifo(dc); rex3_write(dc, REX3_REG_DRAWMODE0, REX3_DRAWMODE0_OPCODE_DRAW | REX3_DRAWMODE0_ADRMODE_BLOCK | REX3_DRAWMODE0_DOSETUP | REX3_DRAWMODE0_STOPONX | REX3_DRAWMODE0_STOPONY); rex3_write(dc, REX3_REG_WRMASK, 0xffffffff); rex3_write(dc, REX3_REG_COLORI, color); rex3_write(dc, REX3_REG_XYSTARTI, (x1 << REX3_XYSTARTI_XSHIFT) | y1); rex3_write_go(dc, REX3_REG_XYENDI, (x2 << REX3_XYENDI_XSHIFT) | y2); }
static void newport_bitblt(struct newport_devconfig *dc, int xs, int ys, int xd, int yd, int wi, int he, int rop) { int xe, ye; uint32_t tmp; rex3_wait_gfifo(dc); if (yd > ys) { /* need to copy bottom up */ ye = ys; yd += he - 1; ys += he - 1; } else ye = ys + he - 1; if (xd > xs) { /* need to copy right to left */ xe = xs; xd += wi - 1; xs += wi - 1; } else xe = xs + wi - 1; rex3_write(dc, REX3_REG_DRAWMODE0, REX3_DRAWMODE0_OPCODE_SCR2SCR | REX3_DRAWMODE0_ADRMODE_BLOCK | REX3_DRAWMODE0_DOSETUP | REX3_DRAWMODE0_STOPONX | REX3_DRAWMODE0_STOPONY); rex3_write(dc, REX3_REG_DRAWMODE1, REX3_DRAWMODE1_PLANES_CI | REX3_DRAWMODE1_DD_DD8 | REX3_DRAWMODE1_RWPACKED | REX3_DRAWMODE1_HD_HD8 | REX3_DRAWMODE1_COMPARE_LT | REX3_DRAWMODE1_COMPARE_EQ | REX3_DRAWMODE1_COMPARE_GT | ((rop << 28) & REX3_DRAWMODE1_LOGICOP_MASK)); rex3_write(dc, REX3_REG_XYSTARTI, (xs << REX3_XYSTARTI_XSHIFT) | ys); rex3_write(dc, REX3_REG_XYENDI, (xe << REX3_XYENDI_XSHIFT) | ye); tmp = (yd - ys) & 0xffff; tmp |= (xd - xs) << REX3_XYMOVE_XSHIFT; rex3_write_go(dc, REX3_REG_XYMOVE, tmp); }
static void newport_copy_rectangle(struct newport_devconfig *dc, int x1, int y1, int x2, int y2, int dx, int dy) { uint32_t tmp; rex3_wait_gfifo(dc); rex3_write(dc, REX3_REG_DRAWMODE0, REX3_DRAWMODE0_OPCODE_SCR2SCR | REX3_DRAWMODE0_ADRMODE_BLOCK | REX3_DRAWMODE0_DOSETUP | REX3_DRAWMODE0_STOPONX | REX3_DRAWMODE0_STOPONY); rex3_write(dc, REX3_REG_XYSTARTI, (x1 << REX3_XYSTARTI_XSHIFT) | y1); rex3_write(dc, REX3_REG_XYENDI, (x2 << REX3_XYENDI_XSHIFT) | y2); tmp = (dy - y1) & 0xffff; tmp |= (dx - x1) << REX3_XYMOVE_XSHIFT; rex3_write_go(dc, REX3_REG_XYMOVE, tmp); }
static int newport_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, struct lwp *l) { struct vcons_data *vd; struct newport_devconfig *dc; struct vcons_screen *__unused(ms); int nmode; vd = (struct vcons_data *)v; dc = (struct newport_devconfig *)vd->cookie; ms = (struct vcons_screen *)vd->active; #define FBINFO (*(struct wsdisplay_fbinfo*)data) switch (cmd) { case WSDISPLAYIO_GINFO: FBINFO.width = dc->dc_xres; FBINFO.height = dc->dc_yres; FBINFO.depth = dc->dc_depth; FBINFO.cmsize = 1 << FBINFO.depth; return 0; case WSDISPLAYIO_GTYPE: *(u_int *)data = WSDISPLAY_TYPE_NEWPORT; return 0; case WSDISPLAYIO_SMODE: nmode = *(int *)data; if (nmode != dc->dc_mode) { dc->dc_mode = nmode; if (nmode == WSDISPLAYIO_MODE_EMUL) { rex3_wait_gfifo(dc); newport_setup_hw(dc); vcons_redraw_screen(vd->active); } } return 0; } return EPASSTHROUGH; }
static void newport_putchar(void *c, int row, int col, u_int ch, long attr) { struct newport_devconfig *dc = (void *)c; struct wsdisplay_font *font = dc->dc_fontdata; uint8_t *bitmap = (u_int8_t *)font->data + (ch - font->firstchar) * font->fontheight * font->stride; uint32_t pattern; int i; int x = col * font->fontwidth; int y = row * font->fontheight; rex3_wait_gfifo(dc); rex3_write(dc, REX3_REG_DRAWMODE0, REX3_DRAWMODE0_OPCODE_DRAW | REX3_DRAWMODE0_ADRMODE_BLOCK | REX3_DRAWMODE0_STOPONX | REX3_DRAWMODE0_ENZPATTERN | REX3_DRAWMODE0_ZPOPAQUE); rex3_write(dc, REX3_REG_XYSTARTI, (x << REX3_XYSTARTI_XSHIFT) | y); rex3_write(dc, REX3_REG_XYENDI, (x + font->fontwidth - 1) << REX3_XYENDI_XSHIFT); rex3_write(dc, REX3_REG_COLORI, NEWPORT_ATTR_FG(attr)); rex3_write(dc, REX3_REG_COLORBACK, NEWPORT_ATTR_BG(attr)); rex3_write(dc, REX3_REG_WRMASK, 0xffffffff); for (i=0; i<font->fontheight; i++) { /* XXX Works only with font->fontwidth == 8 XXX */ pattern = *bitmap << 24; rex3_write_go(dc, REX3_REG_ZPATTERN, pattern); bitmap += font->stride; } }
/**** Helper functions ****/ static void newport_fill_rectangle(struct newport_devconfig *dc, int x1, int y1, int x2, int y2, uint8_t color) { rex3_wait_gfifo(dc); rex3_write(dc, REX3_REG_DRAWMODE0, REX3_DRAWMODE0_OPCODE_DRAW | REX3_DRAWMODE0_ADRMODE_BLOCK | REX3_DRAWMODE0_DOSETUP | REX3_DRAWMODE0_STOPONX | REX3_DRAWMODE0_STOPONY); rex3_write(dc, REX3_REG_DRAWMODE1, REX3_DRAWMODE1_PLANES_CI | REX3_DRAWMODE1_DD_DD8 | REX3_DRAWMODE1_RWPACKED | REX3_DRAWMODE1_HD_HD8 | REX3_DRAWMODE1_COMPARE_LT | REX3_DRAWMODE1_COMPARE_EQ | REX3_DRAWMODE1_COMPARE_GT | REX3_DRAWMODE1_LO_SRC); rex3_write(dc, REX3_REG_WRMASK, 0xffffffff); rex3_write(dc, REX3_REG_COLORI, color); rex3_write(dc, REX3_REG_XYSTARTI, (x1 << REX3_XYSTARTI_XSHIFT) | y1); rex3_write_go(dc, REX3_REG_XYENDI, (x2 << REX3_XYENDI_XSHIFT) | y2); }