hwscroll fix cursor fix code cleanup Reference: /n/sources/patch/applied/mga-hwscroll-fix2 Date: Mon Mar 27 15:24:42 CES 2006 Signed-off-by: xigh@free.fr --- /sys/src/9/pc/vgamga4xx.c Mon Mar 27 15:24:15 2006 +++ /sys/src/9/pc/vgamga4xx.c Mon Mar 27 15:24:10 2006 @@ -1,22 +1,22 @@ /* * Matrox G200, G400 and G450. - * see /sys/src/cmd/aux/vga/mga4xx.c + * Written by Philippe Anel */ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" -#include "../port/error.h" - -#define Image IMAGE -#include -#include -#include -#include "screen.h" +#include "u.h" +#include "../port/lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "io.h" +#include "../port/error.h" + +#define Image IMAGE +#include +#include +#include +#include "screen.h" enum { MATROX = 0x102B, @@ -35,14 +35,10 @@ DWG_LINEAR = 0x0080, DWG_SOLID = 0x0800, DWG_ARZERO = 0x1000, - DWG_SGNZERO = 0x2000, + DWG_SGNZERO = 0x2000, DWG_SHIFTZERO = 0x4000, DWG_REPLACE = 0x000C0000, - DWG_REPLACE2 = (DWG_REPLACE | 0x40), - DWG_XOR = 0x00060010, DWG_BFCOL = 0x04000000, - DWG_BMONOWF = 0x08000000, - DWG_TRANSC = 0x40000000, SRCORG = 0x2cb4, PITCH = 0x1c8c, DSTORG = 0x2cb8, @@ -62,10 +58,8 @@ AR4 = 0x1C70, AR5 = 0x1C74, SGN = 0x1C58, - SGN_SCANLEFT = 1, - SGN_SCANRIGHT = 0, - SGN_SDY_POSITIVE = 0, - SGN_SDY_NEGATIVE = 4, + SGN_LEFT = 1, + SGN_UP = 4, GO = 0x0100, FIFOSTATUS = 0x1E10, @@ -74,37 +68,37 @@ CRTCEXTIDX = 0x1FDE, /* CRTC Extension Index */ CRTCEXTDATA = 0x1FDF, /* CRTC Extension Data */ - FILL_OPERAND = 0x800c7804, + FILL_OPERAND = 0x800c7804, }; -static Pcidev* +static Pcidev * mgapcimatch(void) { - Pcidev* p; + Pcidev *p; p = pcimatch(nil, MATROX, MGA4xx); - if (p == nil) + if(p == nil) p = pcimatch(nil, MATROX, MGA200); return p; } static void -mgawrite8(VGAscr* scr, int index, uchar val) +mgawrite8(VGAscr *scr, int index, uchar val) { - ((uchar*)scr->mmio)[index] = val; + ((uchar *)scr->mmio)[index] = val; } static uchar -mgaread8(VGAscr* scr, int index) +mgaread8(VGAscr *scr, int index) { - return ((uchar*)scr->mmio)[index]; + return ((uchar *)scr->mmio)[index]; } static uchar -crtcextset(VGAscr* scr, int index, uchar set, uchar clr) +crtcextset(VGAscr *scr, int index, uchar set, uchar clr) { - uchar tmp; + uchar tmp; mgawrite8(scr, CRTCEXTIDX, index); tmp = mgaread8(scr, CRTCEXTDATA); @@ -117,12 +111,12 @@ static void mga4xxenable(VGAscr* scr) { - Pcidev * pci; - int size; - int i, n, k; - uchar * p; - uchar x[16]; - uchar crtcext3; + Pcidev *pci; + int size; + int i, n, k; + uchar *p; + uchar x[16]; + uchar crtcext3; if(scr->mmio) return; @@ -153,7 +147,7 @@ p = scr->vaddr; n = (size / MB) / 2; - for (i = 0; i < n; i++) { + for(i = 0; i < n; i++){ k = (2*i+1)*MB; p[k] = 0; p[k] = i+1; @@ -169,7 +163,7 @@ } } -enum { +enum{ Index = 0x00, /* Index */ Data = 0x0A, /* Data */ @@ -184,9 +178,9 @@ }; static void -dac4xxdisable(VGAscr* scr) +dac4xxdisable(VGAscr *scr) { - uchar * dac4xx; + uchar *dac4xx; if(scr->mmio == 0) return; @@ -198,16 +192,16 @@ } static void -dac4xxload(VGAscr* scr, Cursor* curs) +dac4xxload(VGAscr *scr, Cursor *curs) { - int y; - uchar * p; - uchar * dac4xx; + int y; + uchar *p; + uchar *dac4xx; if(scr->mmio == 0) return; - dac4xx = (uchar*)scr->mmio+0x3C00; + dac4xx = (uchar *)scr->mmio+0x3C00; dac4xxdisable(scr); @@ -216,8 +210,8 @@ *p++ = 0; *p++ = 0; *p++ = 0; *p++ = 0; *p++ = 0; *p++ = 0; if(y <16){ - *p++ = curs->set[1+y*2]|curs->clr[1+2*y]; - *p++ = curs->set[y*2]|curs->clr[2*y]; + *p++ = curs->set[1+y*2]; + *p++ = curs->set[y*2]; } else{ *p++ = 0; *p++ = 0; } @@ -225,8 +219,8 @@ *p++ = 0; *p++ = 0; *p++ = 0; *p++ = 0; *p++ = 0; *p++ = 0; if(y <16){ - *p++ = curs->set[1+y*2]; - *p++ = curs->set[y*2]; + *p++ = curs->set[1+y*2]|curs->clr[1+2*y]; + *p++ = curs->set[y*2]|curs->clr[2*y]; } else{ *p++ = 0; *p++ = 0; } @@ -239,10 +233,10 @@ } static int -dac4xxmove(VGAscr* scr, Point p) +dac4xxmove(VGAscr *scr, Point p) { - int x, y; - uchar * dac4xx; + int x, y; + uchar *dac4xx; if(scr->mmio == 0) return 1; @@ -262,18 +256,18 @@ } static void -dac4xxenable(VGAscr* scr) +dac4xxenable(VGAscr *scr) { - uchar * dac4xx; - ulong storage; + uchar *dac4xx; + ulong storage; if(scr->mmio == 0) return; - dac4xx = (uchar*)scr->mmio+0x3C00; + dac4xx = (uchar *)scr->mmio+0x3C00; dac4xxdisable(scr); - storage = (scr->apsize - 4096) & ~0x3ff; + storage = (scr->apsize-4096)&~0x3ff; *(dac4xx+Index) = Icuradrl; *(dac4xx+Data) = 0xff & (storage >> 10); @@ -319,34 +313,33 @@ } static void -mga4xxblank(VGAscr* scr, int blank) +mga4xxblank(VGAscr *scr, int blank) { - char * cp; - uchar * mga; - uchar seq1, crtcext1; + char *cp; + uchar *mga; + uchar seq1, crtcext1; /* blank = 0 -> turn screen on */ /* blank = 1 -> turn screen off */ if(scr->mmio == 0) return; - mga = (uchar*)scr->mmio; + mga = (uchar *)scr->mmio; - if (blank == 0) { + if(blank == 0){ seq1 = 0x00; crtcext1 = 0x00; } else { seq1 = 0x20; crtcext1 = 0x10; /* Default value ... : standby */ cp = getconf("*dpms"); - if (cp) { - if (cistrcmp(cp, "standby") == 0) { + if(cp){ + if(cistrcmp(cp, "standby") == 0) crtcext1 = 0x10; - } else if (cistrcmp(cp, "suspend") == 0) { + else if(cistrcmp(cp, "suspend") == 0) crtcext1 = 0x20; - } else if (cistrcmp(cp, "off") == 0) { + else if(cistrcmp(cp, "off") == 0) crtcext1 = 0x30; - } } } @@ -360,153 +353,124 @@ } static void -mgawrite32(uchar * mga, ulong reg, ulong val) +mgawrite32(uchar *mga, ulong reg, ulong val) { - ulong * l; - - l = (ulong *)(&mga[reg]); - l[0] = val; + *((ulong *)(&mga[reg])) = val; } static ulong -mgaread32(uchar * mga, ulong reg) +mgaread32(uchar *mga, ulong reg) { return *((ulong *)(&mga[reg])); } +static void +mga_fifo(uchar *mga, uchar n) +{ + ulong t; + +#define Timeout 100 + for (t = 0; t < Timeout; t++) + if ((mgaread32(mga, FIFOSTATUS) & 0xff) >= n) + break; + if (t >= Timeout) + print("mga4xx: fifo timeout"); +} + static int -mga4xxfill(VGAscr* scr, Rectangle r, ulong color) +mga4xxfill(VGAscr *scr, Rectangle r, ulong color) { - uchar * mga; - - /* Constant Shaded Trapezoids / Rectangle Fills */ + uchar *mga; + if(scr->mmio == 0) return 0; - mga = (uchar*)scr->mmio; + mga = (uchar *)scr->mmio; + mga_fifo(mga, 7); mgawrite32(mga, DWGCTL, 0); mgawrite32(mga, FCOL, color); - mgawrite32(mga, FXRIGHT, r.max.x); mgawrite32(mga, FXLEFT, r.min.x); + mgawrite32(mga, FXRIGHT, r.max.x); mgawrite32(mga, YDST, r.min.y); mgawrite32(mga, YLEN, Dy(r)); mgawrite32(mga, DWGCTL + GO, FILL_OPERAND); - while (mgaread32(mga, STATUS) & 0x00010000) + while(mgaread32(mga, STATUS) & 0x00010000) ; + return 1; } -#define mga_fifo(n) do {} while ((mgaread32(mga, FIFOSTATUS) & 0xFF) < (n)) - static int -mga4xxscroll(VGAscr* scr, Rectangle r_dst, Rectangle r_src) +mga4xxscroll(VGAscr *scr, Rectangle r_dst, Rectangle r_src) { - uchar * mga; - ulong pitch, y; - ulong width, height, start, end, scandir; - int ydir; + uchar * mga; + int pitch; + int width, height; + ulong start, end, sgn; + Point p_src, p_dst; - /* Two-operand Bitblts */ if(scr->mmio == 0) return 0; - mga = (uchar*)scr->mmio; - pitch = Dx(scr->gscreen->r); - - mgawrite32(mga, DWGCTL, 0); - - scandir = 0; - - height = abs(Dy(r_src)); - width = abs(Dx(r_src)); - - assert(height == abs(Dy(r_dst))); - assert(width == abs(Dx(r_dst))); + assert(Dx(r_src) == Dx(r_dst) && Dy(r_src) == Dy(r_dst)); - if ((r_src.min.y == r_dst.min.y) && (r_src.min.x == r_dst.min.x)) - { - if (0) - print("move x,y to x,y !\n"); + p_src = r_src.min; + p_dst = r_dst.min; + if(eqpt(p_src, p_dst)) return 1; - } - - ydir = 1; - if (r_dst.min.y > r_src.min.y) - { - if (0) - print("ydir = -1\n"); - ydir = -1; - scandir |= 4; // Blit UP - } - if (r_dst.min.x > r_src.min.x) - { - if (0) - print("xdir = -1\n"); - scandir |= 1; // Blit Left + pitch = Dx(scr->gscreen->r); + width = Dx(r_src); + height = Dy(r_src); + sgn = 0; + + if(p_dst.y > p_src.y && p_dst.y < p_src.y + height){ + p_src.y += height - 1; + p_dst.y += height - 1; + sgn |= SGN_UP; } - mga_fifo(4); - if (scandir) - { - mgawrite32(mga, DWGCTL, DWG_BITBLT | DWG_SHIFTZERO | - DWG_SGNZERO | DWG_BFCOL | DWG_REPLACE); - mgawrite32(mga, SGN, scandir); - } else - { - mgawrite32(mga, DWGCTL, DWG_BITBLT | DWG_SHIFTZERO | - DWG_BFCOL | DWG_REPLACE); - } - mgawrite32(mga, AR5, ydir * pitch); - width--; - start = end = r_src.min.x + (r_src.min.y * pitch); - if ((scandir & 1) == 1) - { - start += width; - } else - { - end += width; - } + start = end = p_src.x + (p_src.y * pitch); - y = r_dst.min.y; - if ((scandir & 4) == 4) - { - start += (height - 1) * pitch; - end += (height - 1) * pitch; - y += (height - 1); + if(p_dst.x > p_src.x && p_dst.x < p_src.x + width){ + start += width; + sgn |= SGN_LEFT; } + else + end += width; - mga_fifo(4); + mga_fifo(mga, 8); + mgawrite32(mga, DWGCTL, 0); + mgawrite32(mga, SGN, sgn); + mgawrite32(mga, AR5, sgn & SGN_UP ? -pitch : pitch); mgawrite32(mga, AR0, end); mgawrite32(mga, AR3, start); - mgawrite32(mga, FXBNDRY, ((r_dst.min.x+width)<<16) | r_dst.min.x); - mgawrite32(mga, YDSTLEN + GO, (y << 16) | height); - - if (1) - { - while (mgaread32(mga, STATUS) & 0x00010000) - ; - } + mgawrite32(mga, FXBNDRY, ((p_dst.x + width) << 16) | p_dst.x); + mgawrite32(mga, YDSTLEN, (p_dst.y << 16) | height); + mgawrite32(mga, DWGCTL + GO, DWG_BITBLT | DWG_SHIFTZERO | DWG_BFCOL | DWG_REPLACE); + + while(mgaread32(mga, STATUS) & 0x00010000) + ; return 1; } static void -mga4xxdrawinit(VGAscr* scr) +mga4xxdrawinit(VGAscr *scr) { - uchar * mga; - Pcidev* p; + uchar *mga; + Pcidev *p; p = pcimatch(nil, MATROX, MGA4xx); - if (p == nil) + if(p == nil) return ; if(scr->mmio == 0) return; - mga = (uchar*)scr->mmio; + mga = (uchar *)scr->mmio; mgawrite32(mga, SRCORG, 0); mgawrite32(mga, DSTORG, 0); @@ -517,7 +481,7 @@ mgawrite32(mga, YTOP, 0); mgawrite32(mga, YBOT, 0x01FFFFFF); mgawrite32(mga, PITCH, Dx(scr->gscreen->r) & ((1 << 13) - 1)); - switch(scr->gscreen->depth) { + switch(scr->gscreen->depth){ case 8: mgawrite32(mga, MACCESS, 0); break; @@ -532,9 +496,8 @@ scr->blank = mga4xxblank; } -VGAdev vgamga4xxdev = { +VGAdev vgamga4xxdev={ "mga4xx", - mga4xxenable, /* enable */ 0, /* disable */ 0, /* page */ @@ -542,7 +505,7 @@ mga4xxdrawinit, }; -VGAcur vgamga4xxcur = { +VGAcur vgamga4xxcur={ "mga4xxhwgc", dac4xxenable, dac4xxdisable,