From Michael Lorenz: more cleanup and various bugfixes, support

for WSDISPLAYIO_GETWSCHAR and WSDISPLAYIO_PUTWSCHAR ioctls.
This commit is contained in:
martin 2005-02-25 16:00:58 +00:00
parent 1d351ebc53
commit 97a0f9b3ed

View File

@ -1,4 +1,4 @@
/* $NetBSD: machfb.c,v 1.20 2005/01/17 22:52:46 martin Exp $ */
/* $NetBSD: machfb.c,v 1.21 2005/02/25 16:00:58 martin Exp $ */
/*
* Copyright (c) 2002 Bang Jun-Young
@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: machfb.c,v 1.20 2005/01/17 22:52:46 martin Exp $");
__KERNEL_RCSID(0, "$NetBSD: machfb.c,v 1.21 2005/02/25 16:00:58 martin Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -63,7 +63,7 @@ __KERNEL_RCSID(0, "$NetBSD: machfb.c,v 1.20 2005/01/17 22:52:46 martin Exp $");
#include <dev/wsfont/wsfont.h>
#include <dev/rasops/rasops.h>
#include "opt_wsemul.h"
/* #define DEBUG_MACHFB */
#define MACH64_REG_SIZE 1024
#define MACH64_REG_OFF 0x7ffc00
@ -104,6 +104,8 @@ struct mach64_softc {
size_t memsize;
int memtype;
int sc_mode;
int sc_bg;
int has_dsp;
int bits_per_pixel;
@ -141,7 +143,8 @@ struct mach64screen {
struct mach64_softc *sc;
const struct wsscreen_descr *type;
int active;
u_int16_t *mem;
u_int *chars;
long *attrs;
int dispoffset;
int mindispoffset;
int maxdispoffset;
@ -149,7 +152,7 @@ struct mach64screen {
int cursoron;
int cursorcol;
int cursorrow;
u_int16_t cursortmp;
int cursordrawn;
};
struct mach64_crtcregs {
@ -219,33 +222,7 @@ struct videomode mach64_modes[] = {
VID_NHSYNC | VID_NVSYNC }
};
/* Macallan: let the terminal emulator program the palette, it should be in the softc anyway */
#if 0
/* FIXME values are wrong! */
const u_char mach64_cmap[16 * 3] = {
0x00, 0x00, 0x00, /* black */
0x7f, 0x00, 0x00, /* red */
0x00, 0x7f, 0x00, /* green */
0x7f, 0x7f, 0x00, /* brown */
0x00, 0x00, 0x7f, /* blue */
0x7f, 0x00, 0x7f, /* magenta */
0x00, 0x7f, 0x7f, /* cyan */
0xc8, 0xc8, 0xc8, /* white */
0x7f, 0x7f, 0x7f, /* black */
0xff, 0x00, 0x00, /* red */
0x00, 0xff, 0x00, /* green */
0xff, 0xff, 0x00, /* brown */
0x00, 0x00, 0xff, /* blue */
0xff, 0x00, 0xff, /* magenta */
0x00, 0xff, 0xff, /* cyan */
0xff, 0xff, 0xff, /* white */
};
#endif
#ifdef WSEMUL_VT100
extern const u_char rasops_cmap[768];
#endif
int mach64_match(struct device *, struct cfdata *, void *);
void mach64_attach(struct device *, struct device *, void *);
@ -271,7 +248,7 @@ void mach64_switch_screen(struct mach64_softc *);
void mach64_init_screen(struct mach64_softc *, struct mach64screen *,
const struct wsscreen_descr *, int, long *, int);
void mach64_restore_screen(struct mach64screen *,
const struct wsscreen_descr *, u_int16_t *);
const struct wsscreen_descr *, u_int *);
int mach64_set_screentype(struct mach64_softc *,
const struct wsscreen_descr *);
int mach64_is_console(struct pci_attach_args *);
@ -284,6 +261,7 @@ void mach64_erasecols(void *, int, int, int, long);
void mach64_copyrows(void *, int, int, int);
void mach64_eraserows(void *, int, int, long);
int mach64_allocattr(void *, int, int, int, long *);
void mach64_clearscreen(struct mach64_softc *);
void mach64_scroll(void *, void *, int);
@ -292,7 +270,14 @@ int mach64_getcmap(struct mach64_softc *, struct wsdisplay_cmap *);
int mach64_putpalreg(struct mach64_softc *, uint8_t, uint8_t, uint8_t, uint8_t);
void mach64_bitblt(struct mach64_softc *, int, int, int, int, int, int, int, int) ;
void mach64_rectfill(struct mach64_softc *, int, int, int, int, int);
void mach64_setup_mono(struct mach64_softc *, int, int, int, int, uint32_t, uint32_t);
void mach64_feed_bytes(struct mach64_softc *, int, uint8_t *);
void mach64_showpal(struct mach64_softc *);
int mach64_getwschar(void *, struct wsdisplay_char *);
int mach64_putwschar(void *, struct wsdisplay_char *);
void set_address(struct rasops_info *, bus_addr_t);
#if 0
const struct wsdisplay_emulops mach64_emulops = {
@ -398,8 +383,8 @@ struct wsdisplay_accessops mach64_accessops = {
mach64_show_screen,
NULL, /* load_font */
NULL, /* polls */
NULL, /* getwschar */
NULL, /* putwschar */
mach64_getwschar, /* getwschar */
mach64_putwschar, /* putwschar */
NULL, /* scroll */
NULL, /* getborder */
NULL /* setborder */
@ -500,13 +485,20 @@ mach64_attach(struct device *parent, struct device *self, void *aux)
struct wsemuldisplaydev_attach_args aa;
long defattr;
int setmode, console;
pcireg_t screg;
sc->sc_pc = pa->pa_pc;
sc->sc_pcitag = pa->pa_tag;
sc->sc_dacw=-1;
sc->sc_mode=-1;
pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo));
printf(": %s (rev. 0x%02x)\n", devinfo, PCI_REVISION(pa->pa_class));
/* enable memory and IO access */
screg=pci_conf_read(sc->sc_pc, sc->sc_pcitag, PCI_COMMAND_STATUS_REG);
screg|=PCI_FLAGS_IO_ENABLED|PCI_FLAGS_MEM_ENABLED;
pci_conf_write(sc->sc_pc, sc->sc_pcitag,PCI_COMMAND_STATUS_REG,screg);
for (bar = 0; bar < NBARS; bar++) {
reg = PCI_MAPREG_START + (bar * 4);
sc->sc_bars[bar].vb_type = pci_mapreg_type(sc->sc_pc,
@ -541,9 +533,12 @@ mach64_attach(struct device *parent, struct device *self, void *aux)
/* XXX is there any way to calculate reference frequency from
known values? */
if (mach64_chip_id == PCI_PRODUCT_ATI_RAGE_XL_PCI)
if ((mach64_chip_id == PCI_PRODUCT_ATI_RAGE_XL_PCI) ||
((mach64_chip_id>=PCI_PRODUCT_ATI_RAGE_LT_PRO_PCI) &&
(mach64_chip_id<=PCI_PRODUCT_ATI_RAGE_LT_PRO))) {
printf("ref_freq=29.498MHz\n");
sc->ref_freq = 29498;
else
} else
sc->ref_freq = 14318;
regwb(sc, CLOCK_CNTL + 1, PLL_REF_DIV << 2);
@ -603,40 +598,47 @@ mach64_attach(struct device *parent, struct device *self, void *aux)
default_mode.hdisplay, default_mode.vdisplay,
sc->bits_per_pixel);
mach64_console_screen.ri.ri_hw = sc;
mach64_console_screen.ri.ri_hw = &mach64_console_screen;
mach64_console_screen.ri.ri_depth = sc->bits_per_pixel;
mach64_console_screen.ri.ri_bits = (void*)(u_long)sc->sc_aperbase;
mach64_console_screen.ri.ri_width = default_mode.hdisplay;
mach64_console_screen.ri.ri_height = default_mode.vdisplay;
mach64_console_screen.ri.ri_stride = mach64_console_screen.ri.ri_width;
mach64_console_screen.ri.ri_flg = RI_CLEAR|RI_CENTER;
#ifdef WSEMUL_SUN
mach64_console_screen.ri.ri_flg = RI_CLEAR|RI_CENTER|RI_FORCEMONO;
#endif
mach64_console_screen.ri.ri_bits=(void *)sc->sc_aperbase;
mach64_console_screen.ri.ri_flg = RI_CENTER;
mach64_console_screen.active=1;
sc->active=&mach64_console_screen;
rasops_init(&mach64_console_screen.ri, mach64_console_screen.ri.ri_height / 16,
mach64_console_screen.ri.ri_width / 8); /* XXX width/height are nonsense */
rasops_reconfig(&mach64_console_screen.ri,
mach64_console_screen.ri.ri_height / mach64_console_screen.ri.ri_font->fontheight,
mach64_console_screen.ri.ri_width / mach64_console_screen.ri.ri_font->fontwidth);
set_address(&mach64_console_screen.ri,sc->sc_aperbase);
/* enable acceleration */
mach64_console_screen.ri.ri_ops.copyrows=mach64_copyrows;
mach64_console_screen.ri.ri_ops.eraserows=mach64_eraserows;
mach64_console_screen.ri.ri_ops.copycols=mach64_copycols;
mach64_console_screen.ri.ri_ops.erasecols=mach64_erasecols;
mach64_console_screen.ri.ri_ops.putchar=mach64_putchar;
mach64_console_screen.ri.ri_ops.cursor=mach64_cursor;
mach64_defaultscreen.nrows = mach64_console_screen.ri.ri_rows;
mach64_defaultscreen.ncols = mach64_console_screen.ri.ri_cols;
mach64_console_screen.ri.ri_ops.allocattr(&mach64_console_screen.ri, 0, 0, 0,
mach64_allocattr(&mach64_console_screen.ri, WS_DEFAULT_FG, WS_DEFAULT_BG, 0,
&defattr);
sc->sc_bg=WS_DEFAULT_BG;
/* really necessary? */
mach64_defaultscreen.capabilities=mach64_console_screen.ri.ri_caps;
mach64_defaultscreen.textops=&mach64_console_screen.ri.ri_ops;
/* Initialize fonts */
/* XXX Macallan: shouldn't that happen /before/ we call rasops_init()? */
/* XXX shouldn't that happen /before/ we call rasops_init()? */
wsfont_init();
if (console) {
@ -647,10 +649,12 @@ mach64_attach(struct device *parent, struct device *self, void *aux)
}
mach64_init_lut(sc);
#ifdef DEBUG
mach64_showpal(sc);
delay(4000000);
mach64_clearscreen(sc);
#ifdef DEBUG_MACHFB
/*mach64_showpal(sc);*/
/*mach64_setup_mono(sc, 10, 10, 24, 8, 0xff,0);
mach64_feed_bytes(sc,23,(uint8_t[]){0xff,0xff,0xff,0,0,0,0xff,0xff,0xff,0,0,0,0xff,0xff,0xff,0,0,0,0xff,0xff,0xff,0,0,0});
delay(4000000);*/
#endif
aa.console = console;
aa.scrdata = &mach64_screenlist;
@ -664,7 +668,8 @@ void
mach64_init_screen(struct mach64_softc *sc, struct mach64screen *scr,
const struct wsscreen_descr *type, int existing, long *attrp, int setmode)
{
struct rasops_info *ri=&scr->ri;
int cnt;
scr->sc = sc;
scr->type = type;
scr->mindispoffset = 0;
@ -673,11 +678,22 @@ mach64_init_screen(struct mach64_softc *sc, struct mach64screen *scr,
scr->cursorcol = 0;
scr->cursorrow = 0;
scr->mem = (u_int16_t *)malloc(type->nrows * type->ncols * 2,
cnt=type->nrows * type->ncols;
scr->attrs=(long *)malloc((cnt)*(sizeof(long)+sizeof(u_int)),
M_DEVBUF, M_WAITOK);
scr->chars=(u_int *)&scr->attrs[cnt];
/* we allocate both chars and attributes in one chunk, attributes first because
they have the (potentially) bigger alignment */
ri->ri_depth = sc->bits_per_pixel;
ri->ri_width = default_mode.hdisplay;
ri->ri_height = default_mode.vdisplay;
ri->ri_stride = ri->ri_width;
ri->ri_flg = RI_CENTER;
if (existing) {
scr->active = 1;
ri->ri_flg|=RI_CLEAR;
if (setmode && mach64_set_screentype(sc, type)) {
panic("%s: failed to switch video mode",
sc->sc_dev.dv_xname);
@ -739,6 +755,7 @@ mach64_get_memsize(struct mach64_softc *sc)
};
tmp = regr(sc, MEM_CNTL);
printf("memctl: %08x\n",tmp);
if (sc->has_dsp) {
tmp &= 0x0000000f;
if (tmp < 8)
@ -794,7 +811,7 @@ mach64_get_mode(struct mach64_softc *sc, struct videomode *mode)
mode->vsync_start = (crtc.v_sync_strt_wid & 0xffff) + 1;
mode->vsync_end = (crtc.v_sync_strt_wid >> 16) + mode->vsync_start;
#ifdef MACH64_DEBUG
#ifdef DEBUG_MACHFB
printf("mach64_get_mode: %d %d %d %d %d %d %d %d\n",
mode->hdisplay, mode->hsync_start, mode->hsync_end, mode->htotal,
mode->vdisplay, mode->vsync_start, mode->vsync_end, mode->vtotal);
@ -963,7 +980,7 @@ mach64_init_engine(struct mach64_softc *sc)
case 8:
regw(sc, DP_PIX_WIDTH, HOST_8BPP | SRC_8BPP | DST_8BPP);
regw(sc, DP_CHAIN_MASK, DP_CHAIN_8BPP);
/* XXX Macallan: huh? We /want/ an 8 bit per channel palette! */
/* XXX huh? We /want/ an 8 bit per channel palette! */
/*regw(sc, DAC_CNTL, regr(sc, DAC_CNTL) & ~DAC_8BIT_EN);*/
regw(sc, DAC_CNTL, regr(sc, DAC_CNTL) | DAC_8BIT_EN);
break;
@ -1002,6 +1019,7 @@ mach64_set_dsp(struct mach64_softc *sc)
u_int32_t xclks_per_qw, y;
u_int32_t fifo_off, fifo_on;
printf("initializing the DSP\n");
if (mach64_chip_id == PCI_PRODUCT_ATI_MACH64_VT ||
mach64_chip_id == PCI_PRODUCT_ATI_RAGE_II ||
mach64_chip_id == PCI_PRODUCT_ATI_RAGE_IIP ||
@ -1066,7 +1084,7 @@ mach64_set_dsp(struct mach64_softc *sc)
dsp_on = fifo_on >> dsp_precision;
dsp_off = fifo_off >> dsp_precision;
#ifdef MACH64_DEBUG
#ifdef DEBUG_MACHFB
printf("dsp_xclks_per_qw = %d, dsp_on = %d, dsp_off = %d,\n"
"dsp_precision = %d, dsp_loop_latency = %d,\n"
"mclk_fb_div = %d, vclk_fb_div = %d,\n"
@ -1088,7 +1106,7 @@ mach64_set_pll(struct mach64_softc *sc, int clock)
int q;
q = (clock * sc->ref_div * 100) / (2 * sc->ref_freq);
#ifdef MACH64_DEBUG
#ifdef DEBUG_MACHFB
printf("q = %d\n", q);
#endif
if (q > 25500) {
@ -1123,16 +1141,6 @@ mach64_set_pll(struct mach64_softc *sc, int clock)
void
mach64_init_lut(struct mach64_softc *sc)
{
/* XXX this is pretty dodgy since it's perfectly possible that
both terminal emulations are compiled into the kernel, in this
case we'd install the VT100 colour map which may be wrong */
#ifdef WSEMUL_SUN
mach64_putpalreg(sc,0,255,255,255);
mach64_putpalreg(sc,1,0,0,0);
mach64_putpalreg(sc,255,0,0,0);
#endif
#ifdef WSEMUL_VT100
{
int i,idx;
idx=0;
for(i=0;i<256;i++) {
@ -1140,10 +1148,9 @@ mach64_init_lut(struct mach64_softc *sc)
idx+=3;
}
}
#endif
}
int mach64_putpalreg(struct mach64_softc *sc, uint8_t index, uint8_t r, uint8_t g, uint8_t b)
int
mach64_putpalreg(struct mach64_softc *sc, uint8_t index, uint8_t r, uint8_t g, uint8_t b)
{
sc->sc_cmap_red[index]=r;
sc->sc_cmap_green[index]=g;
@ -1162,7 +1169,8 @@ int mach64_putpalreg(struct mach64_softc *sc, uint8_t index, uint8_t r, uint8_t
return 0;
}
int mach64_putcmap(struct mach64_softc *sc, struct wsdisplay_cmap *cm)
int
mach64_putcmap(struct mach64_softc *sc, struct wsdisplay_cmap *cm)
{
u_int index = cm->index;
u_int count = cm->count;
@ -1200,7 +1208,8 @@ int mach64_putcmap(struct mach64_softc *sc, struct wsdisplay_cmap *cm)
return 0;
}
int mach64_getcmap(struct mach64_softc *sc, struct wsdisplay_cmap *cm)
int
mach64_getcmap(struct mach64_softc *sc, struct wsdisplay_cmap *cm)
{
u_int index = cm->index;
u_int count = cm->count;
@ -1222,72 +1231,6 @@ int mach64_getcmap(struct mach64_softc *sc, struct wsdisplay_cmap *cm)
return 0;
}
void
mach64_switch_screen(struct mach64_softc *sc)
{
struct mach64screen *scr, *oldscr;
const struct wsscreen_descr *type;
scr = sc->wanted;
if (!scr) {
printf("mach64_switch_screen: disappeared\n");
(*sc->switchcb)(sc->switchcbarg, EIO, 0);
return;
}
type = scr->type;
oldscr = sc->active; /* can be NULL! */
#ifdef DIAGNOSTIC
if (oldscr) {
if (!oldscr->active)
panic("mach64_switch_screen: not active");
if (oldscr->type != sc->currenttype)
panic("mach64_switch_screen: bad type");
}
#endif
if (scr == oldscr)
return;
#ifdef DIAGNOSTIC
/* XXX Macallan: this one bites us at reboot */
/* if (scr->active)
panic("mach64_switch_screen: active");*/
#endif
if (oldscr)
oldscr->active = 0;
if (sc->currenttype != type) {
mach64_set_screentype(sc, type);
sc->currenttype = type;
}
scr->dispoffset = scr->mindispoffset;
if (!oldscr || (scr->dispoffset != oldscr->dispoffset)) {
}
/* Clear the entire screen. */
scr->active = 1;
mach64_restore_screen(scr, type, scr->mem);
sc->active = scr;
mach64_cursor(scr, scr->cursoron, scr->cursorrow, scr->cursorcol);
sc->wanted = 0;
if (sc->switchcb)
(*sc->switchcb)(sc->switchcbarg, 0, 0);
}
void
mach64_restore_screen(struct mach64screen *scr,
const struct wsscreen_descr *type, u_int16_t *mem)
{
}
int
mach64_set_screentype(struct mach64_softc *sc, const struct wsscreen_descr *des)
{
@ -1319,10 +1262,12 @@ mach64_is_console(struct pci_attach_args *pa)
chosen = OF_finddevice("/chosen");
OF_getprop(chosen, "stdout", &stdout, 4);
node = OF_instance_to_package(stdout);
#ifdef DEBUG_MACHFB
printf("us : %08x\n",us);
printf("inst: %08x\n",stdout);
printf("node: %08x\n",node);
return((us==node)||(us==stdout));
#endif
return(us==node);
#else
return 1;
#endif
@ -1335,7 +1280,32 @@ mach64_is_console(struct pci_attach_args *pa)
void
mach64_cursor(void *cookie, int on, int row, int col)
{
struct rasops_info *ri=cookie;
struct mach64screen *scr=ri->ri_hw;
struct mach64_softc *sc=scr->sc;
int x,y,wi=ri->ri_font->fontwidth,he=ri->ri_font->fontheight;
if(scr->active) {
x=scr->cursorcol*wi+ri->ri_xorigin;
y=scr->cursorrow*he+ri->ri_yorigin;
if(scr->cursordrawn) {
mach64_bitblt(sc,x,y,x,y,wi,he,MIX_NOT_SRC,0xff);
scr->cursordrawn=0;
}
scr->cursorrow=row;
scr->cursorcol=col;
if((scr->cursoron=on)!=0)
{
x=scr->cursorcol*wi+ri->ri_xorigin;
y=scr->cursorrow*he+ri->ri_yorigin;
mach64_bitblt(sc,x,y,x,y,wi,he,MIX_NOT_SRC,0xff);
scr->cursordrawn=1;
}
} else {
scr->cursoron=on;
scr->cursorrow=row;
scr->cursorcol=col;
scr->cursordrawn=0;
}
}
#if 0
@ -1345,21 +1315,56 @@ mach64_mapchar(void *cookie, int uni, u_int *index)
return 0;
}
#endif
void
mach64_putchar(void *cookie, int row, int col, u_int c, long attr)
{
struct rasops_info *ri=cookie;
struct mach64screen *scr=ri->ri_hw;
struct mach64_softc *sc=scr->sc;
int offset=ri->ri_cols*row+col;
scr->attrs[offset]=attr;
scr->chars[offset]=c;
if(scr->active) {
int fg,bg,uc;
uint8_t *data;
int x,y,wi=ri->ri_font->fontwidth,he=ri->ri_font->fontheight;
/*scr->putchar(cookie,row,col,c,attr);*/
if (!CHAR_IN_FONT(c, ri->ri_font))
return;
bg = (u_char)ri->ri_devcmap[(attr >> 16) & 0xf];
fg = (u_char)ri->ri_devcmap[(attr >> 24) & 0xf];
x=ri->ri_xorigin+col*wi;
y=ri->ri_yorigin+row*he;
if(c==0x20) {
mach64_rectfill(sc,x,y,wi,he,bg);
} else {
uc = c-ri->ri_font->firstchar;
data = (uint8_t *)ri->ri_font->data + uc * ri->ri_fontscale;
mach64_setup_mono(sc,x,y,wi,he,fg,bg);
mach64_feed_bytes(sc,ri->ri_fontscale,data);
}
}
}
#endif
void
mach64_copycols(void *cookie, int row, int srccol, int dstcol, int ncols)
{
struct rasops_info *ri=cookie;
struct mach64_softc *sc=ri->ri_hw;
struct mach64screen *scr=ri->ri_hw;
struct mach64_softc *sc=scr->sc;
int32_t xs,xd,y,width,height;
int from=srccol+row*ri->ri_cols;
int to=dstcol+row*ri->ri_cols;
memmove(&scr->attrs[to],&scr->attrs[from],ncols*sizeof(long));
memmove(&scr->chars[to],&scr->chars[from],ncols*sizeof(u_int));
if(scr->active) {
xs=ri->ri_xorigin+ri->ri_font->fontwidth*srccol;
xd=ri->ri_xorigin+ri->ri_font->fontwidth*dstcol;
y=ri->ri_yorigin+ri->ri_font->fontheight*row;
@ -1367,14 +1372,23 @@ mach64_copycols(void *cookie, int row, int srccol, int dstcol, int ncols)
height=ri->ri_font->fontheight;
mach64_bitblt(sc,xs,y,xd,y,width,height,MIX_SRC,0xff);
}
}
void
mach64_erasecols(void *cookie, int row, int startcol, int ncols, long fillattr)
{
struct rasops_info *ri=cookie;
struct mach64_softc *sc=ri->ri_hw;
struct mach64screen *scr=ri->ri_hw;
struct mach64_softc *sc=scr->sc;
int32_t x,y,width,height,fg,bg,ul;;
int start=startcol+row*ri->ri_cols;
int end=start+ncols, i;
for(i=start;i<end;i++) {
scr->attrs[i]=fillattr;
scr->chars[i]=0x20;
}
if(scr->active) {
x=ri->ri_xorigin+ri->ri_font->fontwidth*startcol;
y=ri->ri_yorigin+ri->ri_font->fontheight*row;
width=ri->ri_font->fontwidth*ncols;
@ -1382,16 +1396,22 @@ mach64_erasecols(void *cookie, int row, int startcol, int ncols, long fillattr)
rasops_unpack_attr(fillattr,&fg,&bg,&ul);
mach64_rectfill(sc,x,y,width,height,bg);
}
}
void
mach64_copyrows(void *cookie, int srcrow, int dstrow, int nrows)
{
struct rasops_info *ri=cookie;
struct mach64_softc *sc=ri->ri_hw;
struct mach64screen *scr=ri->ri_hw;
struct mach64_softc *sc=scr->sc;
int32_t x,ys,yd,width,height;
int from=ri->ri_cols*srcrow, to=ri->ri_cols*dstrow, len=ri->ri_cols*nrows;
memmove(&scr->attrs[to],&scr->attrs[from],len*sizeof(long));
memmove(&scr->chars[to],&scr->chars[from],len*sizeof(u_int));
if(scr->active) {
x=ri->ri_xorigin;
ys=ri->ri_yorigin+ri->ri_font->fontheight*srcrow;
yd=ri->ri_yorigin+ri->ri_font->fontheight*dstrow;
@ -1399,9 +1419,35 @@ mach64_copyrows(void *cookie, int srcrow, int dstrow, int nrows)
height=ri->ri_font->fontheight*nrows;
mach64_bitblt(sc,x,ys,x,yd,width,height,MIX_SRC,0xff);
}
}
void mach64_bitblt(struct mach64_softc *sc, int xs, int ys, int xd, int yd, int width, int height, int rop,
int mask)
void
mach64_eraserows(void *cookie, int row, int nrows, long fillattr)
{
struct rasops_info *ri=cookie;
struct mach64screen *scr=ri->ri_hw;
struct mach64_softc *sc=scr->sc;
int32_t x,y,width,height,fg,bg,ul;
int start=ri->ri_cols*row, end=ri->ri_cols*(row+nrows),i;
for(i=start;i<end;i++) {
scr->attrs[i]=fillattr;
scr->chars[i]=0x20;
}
if(scr->active) {
x=ri->ri_xorigin;
y=ri->ri_yorigin+ri->ri_font->fontheight*row;
width=ri->ri_emuwidth;
height=ri->ri_font->fontheight*nrows;
rasops_unpack_attr(fillattr,&fg,&bg,&ul);
mach64_rectfill(sc,x,y,width,height,bg);
}
}
void
mach64_bitblt(struct mach64_softc *sc, int xs, int ys, int xd, int yd, int width, int height, int rop, int mask)
{
uint32_t dest_ctl=0;
wait_for_idle(sc);
@ -1437,7 +1483,54 @@ int mask)
wait_for_idle(sc);
}
void mach64_rectfill(struct mach64_softc *sc, int x, int y, int width, int height, int colour)
void
mach64_setup_mono(struct mach64_softc *sc, int xd, int yd, int width, int height, uint32_t fg,
uint32_t bg)
{
wait_for_idle(sc);
regw(sc,DP_WRITE_MASK,0xff); /* XXX only good for 8 bit */
regw(sc,DP_PIX_WIDTH,DST_8BPP|SRC_1BPP|HOST_1BPP);
regw(sc,DP_SRC,MONO_SRC_HOST|BKGD_SRC_BKGD_CLR|FRGD_SRC_FRGD_CLR);
regw(sc,DP_MIX,((MIX_SRC&0xffff)<<16)|MIX_SRC);
regw(sc,CLR_CMP_CNTL,0); /* no transparency */
regw(sc,SRC_CNTL,SRC_LINE_X_LEFT_TO_RIGHT);
regw(sc,DST_CNTL,DST_Y_TOP_TO_BOTTOM|DST_X_LEFT_TO_RIGHT);
regw(sc,HOST_CNTL,HOST_BYTE_ALIGN);
regw(sc,DP_BKGD_CLR,bg);
regw(sc,DP_FRGD_CLR,fg);
regw(sc,SRC_Y_X,0);
regw(sc,SRC_WIDTH1,width);
regw(sc,DST_Y_X,(xd<<16)|yd);
regw(sc,DST_HEIGHT_WIDTH,(width<<16)|height);
/* now feed the data into the chip */
}
void
mach64_feed_bytes(struct mach64_softc *sc, int count, uint8_t *data)
{
int i;
uint32_t latch=0, bork;
int shift=0;
int reg=0;
for(i=0;i<count;i++) {
bork=data[i];
latch|=(bork<<shift);
if(shift==24) {
regw(sc,HOST_DATA0+reg,latch);
latch=0;
shift=0;
reg=(reg+4)&0x3c;
} else
shift+=8;
}
if(shift!=24)
regw(sc,HOST_DATA0+reg,latch);
wait_for_idle(sc);
}
void
mach64_rectfill(struct mach64_softc *sc, int x, int y, int width, int height, int colour)
{
wait_for_idle(sc);
regw(sc,DP_WRITE_MASK,0xff);
@ -1456,7 +1549,15 @@ void mach64_rectfill(struct mach64_softc *sc, int x, int y, int width, int heigh
wait_for_idle(sc);
}
void mach64_showpal(struct mach64_softc *sc)
void
mach64_clearscreen(struct mach64_softc *sc)
{
mach64_rectfill(sc,0,0,sc->virt_x,sc->virt_y,sc->sc_bg);
}
void
mach64_showpal(struct mach64_softc *sc)
{
int i,x=0;
for (i=0;i<16;i++) {
@ -1468,24 +1569,13 @@ void mach64_showpal(struct mach64_softc *sc)
int
mach64_allocattr(void *cookie, int fg, int bg, int flags, long *attrp)
{
return 0;
}
void
mach64_eraserows(void *cookie, int row, int nrows, long fillattr)
if((fg==0)&&(bg==0))
{
struct rasops_info *ri=cookie;
struct mach64_softc *sc=ri->ri_hw;
int32_t x,y,width,height,fg,bg,ul;
x=ri->ri_xorigin;
y=ri->ri_yorigin+ri->ri_font->fontheight*row;
width=ri->ri_emuwidth;
height=ri->ri_font->fontheight*nrows;
rasops_unpack_attr(fillattr,&fg,&bg,&ul);
mach64_rectfill(sc,x,y,width,height,bg);
fg=WS_DEFAULT_FG;
bg=WS_DEFAULT_BG;
}
*attrp=(fg&0xf)<<24|(bg&0xf)<<16|(flags&0xff)<<8;
return 0;
}
/*
@ -1521,7 +1611,6 @@ mach64_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
case PCI_IOC_CFGWRITE:
return (pci_devioctl(sc->sc_pc, sc->sc_pcitag,
cmd, data, flag, p));
#ifdef notyet
case WSDISPLAYIO_SMODE:
{
int new_mode=*(int*)data;
@ -1533,10 +1622,16 @@ mach64_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
/* we'll probably want to reset the console into a known state here
just in case the Xserver crashed or didn't properly clean up after
itself for whetever reason */
mach64_restore_screen(ms, ms->type, ms->chars);
mach64_cursor(ms, ms->cursoron, ms->cursorrow, ms->cursorcol);
}
}
}
#endif
return 0;
case WSDISPLAYIO_GETWSCHAR:
return mach64_getwschar(sc,(struct wsdisplay_char *)data);
case WSDISPLAYIO_PUTWSCHAR:
return mach64_putwschar(sc,(struct wsdisplay_char *)data);
}
return EPASSTHROUGH;
}
@ -1578,20 +1673,34 @@ mach64_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep,
{
struct mach64_softc *sc = v;
struct mach64screen *scr;
struct rasops_info *ri;
int cnt=type->nrows * type->ncols;
scr = malloc(sizeof(struct mach64screen), M_DEVBUF, M_WAITOK|M_ZERO);
mach64_init_screen(sc, scr, type, 0, defattrp, sc->active == NULL);
rasops_init(&scr->ri, mach64_console_screen.ri.ri_height / 16,
ri=&scr->ri;
ri->ri_hw=scr;
/*ri->ri_bits=(void *)sc->sc_aperbase;*/
rasops_init(ri, mach64_console_screen.ri.ri_height / 8,
mach64_console_screen.ri.ri_width / 8);
scr->ri.ri_hw=sc;
rasops_reconfig(ri, ri->ri_height / ri->ri_font->fontheight,
ri->ri_width / ri->ri_font->fontwidth);
set_address(ri,sc->sc_aperbase);
mach64_allocattr(ri,WS_DEFAULT_FG,WS_DEFAULT_BG,0,defattrp);
scr->ri.ri_ops.copyrows=mach64_copyrows;
scr->ri.ri_ops.eraserows=mach64_eraserows;
scr->ri.ri_ops.copycols=mach64_copycols;
scr->ri.ri_ops.erasecols=mach64_erasecols;
scr->ri.ri_ops.putchar=mach64_putchar;
scr->ri.ri_ops.cursor=mach64_cursor;
scr->mem = malloc(type->ncols * type->nrows * 2, M_DEVBUF,
M_WAITOK);
mach64_eraserows(&scr->ri, 0, type->nrows, *defattrp);
scr->attrs=(long *)malloc((cnt)*(sizeof(long)+sizeof(u_int)),
M_DEVBUF, M_WAITOK);
scr->chars=(u_int *)&scr->attrs[cnt];
mach64_eraserows(ri, 0, ri->ri_rows, *defattrp);
if (sc->active == NULL) {
scr->active = 1;
sc->active = scr;
@ -1612,9 +1721,10 @@ mach64_free_screen(void *v, void *cookie)
struct mach64screen *scr = cookie;
LIST_REMOVE(scr, next);
if (scr != &mach64_console_screen)
if (scr != &mach64_console_screen) {
free(scr->attrs,M_DEVBUF);
free(scr, M_DEVBUF);
else
} else
panic("mach64_free_screen: console");
if (sc->active == scr)
@ -1647,6 +1757,129 @@ mach64_show_screen(void *v, void *cookie, int waitok,
return 0;
}
void
mach64_switch_screen(struct mach64_softc *sc)
{
struct mach64screen *scr, *oldscr;
const struct wsscreen_descr *type;
scr = sc->wanted;
if (!scr) {
printf("mach64_switch_screen: disappeared\n");
(*sc->switchcb)(sc->switchcbarg, EIO, 0);
return;
}
type = scr->type;
oldscr = sc->active; /* can be NULL! */
#ifdef DIAGNOSTIC
if (oldscr) {
if (!oldscr->active)
panic("mach64_switch_screen: not active");
if (oldscr->type != sc->currenttype)
panic("mach64_switch_screen: bad type");
}
#endif
if (scr == oldscr)
return;
#ifdef DIAGNOSTIC
/* XXX: this one bites us at reboot */
/* if (scr->active)
panic("mach64_switch_screen: active");*/
#endif
if (oldscr)
oldscr->active = 0;
if (sc->currenttype != type) {
mach64_set_screentype(sc, type);
sc->currenttype = type;
}
scr->dispoffset = scr->mindispoffset;
if (!oldscr || (scr->dispoffset != oldscr->dispoffset)) {
}
/* Clear the entire screen. */
scr->active = 1;
mach64_restore_screen(scr, type, scr->chars);
sc->active = scr;
scr->ri.ri_ops.cursor(scr, scr->cursoron, scr->cursorrow, scr->cursorcol);
sc->wanted = 0;
if (sc->switchcb)
(*sc->switchcb)(sc->switchcbarg, 0, 0);
}
void
mach64_restore_screen(struct mach64screen *scr,
const struct wsscreen_descr *type, u_int *mem)
{
int i, j, offset=0;
/*struct rasops_info *ri=&scr->ri;*/
u_int *charptr=scr->chars;
long *attrptr=scr->attrs;
mach64_clearscreen(scr->sc);
for (i = 0; i < scr->ri.ri_rows; i++) {
for (j = 0; j < scr->ri.ri_cols; j++) {
mach64_putchar(scr, i, j, charptr[offset], attrptr[offset]);
offset++;
}
}
scr->cursordrawn=0;
}
/* set ri->ri_bits according to fb, ri_xorigin and ri_yorigin */
void
set_address(struct rasops_info *ri, bus_addr_t fb)
{
/*printf(" %d %d %d\n",ri->ri_xorigin,ri->ri_yorigin,ri->ri_stride);*/
ri->ri_bits=(void *)((u_long)fb+ri->ri_stride*ri->ri_yorigin+ri->ri_xorigin);
}
int
mach64_getwschar(void *cookie, struct wsdisplay_char *wsc)
{
struct mach64_softc *sc=cookie;
struct mach64screen *scr=sc->active;
int fg,bg,fl;
if(scr){
if((wsc->col>=0) && (wsc->col<scr->ri.ri_cols) && (wsc->row>=0) &&
(wsc->row<scr->ri.ri_rows)) {
int pos=scr->ri.ri_cols*wsc->row+wsc->col;
wsc->letter=scr->chars[pos];
rasops_unpack_attr(scr->attrs[pos],&fg, &bg, &fl);
wsc->foreground=fg;
wsc->background=bg;
wsc->flags=fl;
return 0;
}
}
return EINVAL;
}
int
mach64_putwschar(void *cookie, struct wsdisplay_char *wsc)
{
struct mach64_softc *sc=cookie;
struct mach64screen *scr=sc->active;
long attr;
if(scr){
if((wsc->col>=0) && (wsc->col<scr->ri.ri_cols) && (wsc->row>=0) &&
(wsc->row<scr->ri.ri_rows)) {
mach64_allocattr(&scr->ri,wsc->foreground, wsc->background, wsc->flags,&attr);
mach64_putchar(&scr->ri,wsc->row, wsc->col, wsc->letter,attr);
return 0;
}
}
return EINVAL;
}
#if 0
int
mach64_load_font(void *v, void *cookie, struct wsdisplay_font *data)
@ -1655,3 +1888,4 @@ mach64_load_font(void *v, void *cookie, struct wsdisplay_font *data)
return 0;
}
#endif