From 97a0f9b3ed62d9612b9d5c85f872d4824b664281 Mon Sep 17 00:00:00 2001 From: martin Date: Fri, 25 Feb 2005 16:00:58 +0000 Subject: [PATCH] From Michael Lorenz: more cleanup and various bugfixes, support for WSDISPLAYIO_GETWSCHAR and WSDISPLAYIO_PUTWSCHAR ioctls. --- sys/dev/pci/machfb.c | 584 ++++++++++++++++++++++++++++++------------- 1 file changed, 409 insertions(+), 175 deletions(-) diff --git a/sys/dev/pci/machfb.c b/sys/dev/pci/machfb.c index 904f5e12e497..9a8de8c6206a 100644 --- a/sys/dev/pci/machfb.c +++ b/sys/dev/pci/machfb.c @@ -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 -__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 #include @@ -63,7 +63,7 @@ __KERNEL_RCSID(0, "$NetBSD: machfb.c,v 1.20 2005/01/17 22:52:46 martin Exp $"); #include #include -#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;iattrs[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;iattrs[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;ivirt_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->colri.ri_cols) && (wsc->row>=0) && + (wsc->rowri.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->colri.ri_cols) && (wsc->row>=0) && + (wsc->rowri.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 +