From 806353ec9eda162a3ff13cad1e5228c58cd67566 Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Sun, 27 Dec 2020 23:08:59 +0100 Subject: [PATCH] devvga: implement screen tilting, remove panning and overlays Tilting allows using left/right rotated or invetrted display orientation. This can be changed at runtime such as: echo tilt right > /dev/vgactl This removes the old panning and vga overlays as they are only implemented with some ancient vga controllers. --- sys/man/3/vga | 74 ++------ sys/src/9/pc/devvga.c | 151 +++++----------- sys/src/9/pc/screen.c | 330 +++++++++++++++++++++++++--------- sys/src/9/pc/screen.h | 19 +- sys/src/9/pc/vgact65545.c | 2 +- sys/src/9/pc/vgacyber938x.c | 2 +- sys/src/9/pc/vgaet4000.c | 2 +- sys/src/9/pc/vgamach64xx.c | 348 +----------------------------------- sys/src/9/pc/vgamga4xx.c | 6 +- sys/src/9/pc/vganeomagic.c | 24 +-- sys/src/9/pc/vganvidia.c | 6 +- sys/src/9/pc/vgaradeon.c | 14 +- sys/src/9/pc/vgas3.c | 22 +-- sys/src/9/pc/vgasavage.c | 2 +- sys/src/9/pc/vgat2r4.c | 9 +- 15 files changed, 352 insertions(+), 659 deletions(-) diff --git a/sys/man/3/vga b/sys/man/3/vga index e3164c08e..993f9767b 100644 --- a/sys/man/3/vga +++ b/sys/man/3/vga @@ -6,8 +6,6 @@ vga \- VGA controller device .B bind #v /dev .B /dev/vgactl -.B /dev/vgaovl -.B /dev/vgaovlctl .fi .SH DESCRIPTION The VGA device allows configuration of a graphics controller @@ -48,31 +46,25 @@ pixels wide by .I Y pixels high. This message is optional; -it is used to implement panning and to accommodate -displays that require the in-memory screen image -to have certain alignment properties. +it is used to accommodate displays that require the +in-memory screen image to have certain alignment properties. For example, a 1400x1050 screen with a 1408x1050 in-memory image will use .B "size 1408x1050 but .BR "actualsize 1400x1050" . .TP -.BI panning " mode" -Depending on whether -.I mode -is -.B on -or -.BR off , -enable or disable panning in a virtual screen. -If panning is on and the screen's -.B size -is larger than its -.BR actualsize , -the displayed portion of the screen will pan to follow the mouse. -Setting the panning mode after the first attach of the -.B #i -driver has no effect. +.BI tilt " value" +Set the tilt of the screen, +altering the screen's orientation. +The +.I value +can be one of: +.BR none , +.BR left , +.B inverted +and +.BR right . .TP .BI type " ctlr" Set the type of VGA controller being used. @@ -206,46 +198,6 @@ This must be sent after setting the Reading .B vgactl returns the current settings, one per line. -.PP -Some VGA cards support overlay graphics. -Writing strings to -.B vgaovlctl -configures such cards. -The following are valid overlay control commands: -.TP -.BI openctl -opens the overlay device. -.TP -.BI configure " w h format" -allocates resources inside the driver to support an overlay area -of width -.I w -and height -.I h -pixels. Currently, the only supported -.I format -is -.B YUYV -packed. -In -.B YUYV -two pixels are encoded by their separate Y values -and their combined U and V values. -The size of the two pixels is 32 bits. -.TP -.BI enable " x y w h" -enables drawing data on the display through the overlay mode. The data -is drawn at position -.IR x , y -and has a width and height of -.IR w , h -respectively. -.TP -.BI closectl -terminates overlay control. -.PP -Overlay data can be written to -.BR vgaovl . .SH EXAMPLES The following disables hardware acceleration. .IP diff --git a/sys/src/9/pc/devvga.c b/sys/src/9/pc/devvga.c index cb97a4901..07f2c407c 100644 --- a/sys/src/9/pc/devvga.c +++ b/sys/src/9/pc/devvga.c @@ -19,15 +19,11 @@ enum { Qdir, Qvgactl, - Qvgaovl, - Qvgaovlctl, }; static Dirtab vgadir[] = { - ".", { Qdir, 0, QTDIR }, 0, 0550, - "vgactl", { Qvgactl, 0 }, 0, 0660, - "vgaovl", { Qvgaovl, 0 }, 0, 0660, - "vgaovlctl", { Qvgaovlctl, 0 }, 0, 0660, + ".", { Qdir, 0, QTDIR }, 0, 0550, + "vgactl", { Qvgactl, 0 }, 0, 0660, }; enum { @@ -38,12 +34,12 @@ enum { CMhwgc, CMlinear, CMpalettedepth, - CMpanning, CMsize, CMtextmode, CMtype, CMsoftscreen, CMpcidev, + CMtilt, }; static Cmdtab vgactlmsg[] = { @@ -54,12 +50,12 @@ static Cmdtab vgactlmsg[] = { CMhwgc, "hwgc", 2, CMlinear, "linear", 0, CMpalettedepth, "palettedepth", 2, - CMpanning, "panning", 2, CMsize, "size", 3, CMtextmode, "textmode", 1, CMtype, "type", 2, CMsoftscreen, "softscreen", 2, CMpcidev, "pcidev", 2, + CMtilt, "tilt", 2, }; static void @@ -120,35 +116,12 @@ vgastat(Chan* c, uchar* dp, int n) static Chan* vgaopen(Chan* c, int omode) { - VGAscr *scr; - static char *openctl = "openctl\n"; - - scr = &vgascreen[0]; - if ((ulong)c->qid.path == Qvgaovlctl) { - if (scr->dev && scr->dev->ovlctl) - scr->dev->ovlctl(scr, c, openctl, strlen(openctl)); - else - error(Enonexist); - } return devopen(c, omode, vgadir, nelem(vgadir), devgen); } static void -vgaclose(Chan* c) +vgaclose(Chan*) { - VGAscr *scr; - static char *closectl = "closectl\n"; - - scr = &vgascreen[0]; - if((ulong)c->qid.path == Qvgaovlctl) - if(scr->dev && scr->dev->ovlctl){ - if(waserror()){ - print("ovlctl error: %s\n", up->errstr); - return; - } - scr->dev->ovlctl(scr, c, closectl, strlen(closectl)); - poperror(); - } } static long @@ -176,19 +149,20 @@ vgaread(Chan* c, void* a, long n, vlong off) p = seprint(p, e, "type %s\n", scr->dev != nil ? scr->dev->name : "cga"); if(scr->gscreen != nil) { + Rectangle r; + p = seprint(p, e, "size %dx%dx%d %s\n", - scr->gscreen->r.max.x, scr->gscreen->r.max.y, - scr->gscreen->depth, chantostr(chbuf, scr->gscreen->chan)); - if(Dx(scr->gscreen->r) != Dx(physgscreenr) - || Dy(scr->gscreen->r) != Dy(physgscreenr)) - p = seprint(p, e, "actualsize %dx%d\n", - physgscreenr.max.x, physgscreenr.max.y); + scr->width, scr->height, scr->gscreen->depth, + chantostr(chbuf, scr->gscreen->chan)); + r = actualscreensize(scr); + if(scr->width != r.max.x || scr->height != r.max.y) + p = seprint(p, e, "actualsize %dx%d\n", r.max.x, r.max.y); + p = seprint(p, e, "tilt %s\n", tiltstr[scr->tilt]); } p = seprint(p, e, "hwgc %s\n", scr->cur != nil ? scr->cur->name : "off"); p = seprint(p, e, "hwaccel %s\n", hwaccel ? "on" : "off"); p = seprint(p, e, "hwblank %s\n", hwblank ? "on" : "off"); - p = seprint(p, e, "panning %s\n", panning ? "on" : "off"); p = seprint(p, e, "addr p 0x%.8llux v %#p size %#ux\n", scr->paddr, scr->vaddr, scr->apsize); p = seprint(p, e, "softscreen %s\n", scr->softscreen ? "on" : "off"); @@ -199,11 +173,6 @@ vgaread(Chan* c, void* a, long n, vlong off) return n; - case Qvgaovl: - case Qvgaovlctl: - error(Ebadusefd); - break; - default: error(Egreg); break; @@ -216,18 +185,16 @@ static char Ebusy[] = "vga already configured"; static char Enoscreen[] = "set the screen size first"; static void -vgactl(Cmdbuf *cb) +vgactl(VGAscr *scr, Cmdbuf *cb) { - int align, i, size, x, y, z; + int align, size, tilt, z, i; Rectangle r; char *chanstr, *p; ulong chan; Cmdtab *ct; - VGAscr *scr; extern VGAdev *vgadev[]; extern VGAcur *vgacur[]; - scr = &vgascreen[0]; ct = lookupcmd(cb, vgactlmsg, nelem(vgactlmsg)); switch(ct->index){ case CMhwgc: @@ -298,14 +265,15 @@ vgactl(Cmdbuf *cb) return; case CMsize: - x = strtoul(cb->f[1], &p, 0); + r.min = ZP; + r.max.x = strtoul(cb->f[1], &p, 0); if(*p) p++; - y = strtoul(p, &p, 0); + r.max.y = strtoul(p, &p, 0); if(*p) p++; z = strtoul(p, &p, 0); - if(badrect(Rect(0,0,x,y))) + if(badrect(r)) error(Ebadarg); chanstr = cb->f[2]; if((chan = strtochan(chanstr)) == 0) @@ -313,32 +281,30 @@ vgactl(Cmdbuf *cb) if(chantodepth(chan) != z) error("depth, channel do not match"); deletescreenimage(); - if(screensize(x, y, z, chan)) - error(Egreg); - bootscreenconf(scr); + setscreensize(scr, r.max.x, r.max.y, z, chan, scr->tilt); return; case CMactualsize: if(scr->gscreen == nil) error(Enoscreen); - x = strtoul(cb->f[1], &p, 0); + r.min = ZP; + r.max.x = strtoul(cb->f[1], &p, 0); if(*p) p++; - y = strtoul(p, nil, 0); - r = Rect(0,0,x,y); + r.max.y = strtoul(p, nil, 0); if(badrect(r)) error(Ebadarg); - if(!rectinrect(r, scr->gscreen->r)) + if(r.max.x > scr->width || r.max.y > scr->height) error("physical screen bigger than virtual"); deletescreenimage(); - physgscreenr = r; + setactualsize(scr, r); goto Resized; case CMpalettedepth: - x = strtoul(cb->f[1], &p, 0); - if(x != 8 && x != 6) + z = strtoul(cb->f[1], &p, 0); + if(z != 8 && z != 6) error(Ebadarg); - scr->palettedepth = x; + scr->palettedepth = z; return; case CMsoftscreen: @@ -348,17 +314,22 @@ vgactl(Cmdbuf *cb) scr->softscreen = 0; else break; + if(0){ + case CMtilt: + for(tilt = 0; tilt < nelem(tiltstr); tilt++) + if(strcmp(cb->f[1], tiltstr[tilt]) == 0) + break; + } else { + tilt = scr->tilt; + } if(scr->gscreen == nil) return; - r = physgscreenr; - x = scr->gscreen->r.max.x; - y = scr->gscreen->r.max.y; - z = scr->gscreen->depth; + r = actualscreensize(scr); chan = scr->gscreen->chan; + z = scr->gscreen->depth; deletescreenimage(); - if(screensize(x, y, z, chan)) - error(Egreg); - physgscreenr = r; + setscreensize(scr, scr->width, scr->height, z, chan, tilt); + setactualsize(scr, r); /* no break */ case CMdrawinit: if(scr->gscreen == nil) @@ -368,7 +339,6 @@ vgactl(Cmdbuf *cb) hwblank = scr->blank != nil; hwaccel = scr->fill != nil || scr->scroll != nil; Resized: - scr->gscreen->clipr = panning ? scr->gscreen->r : physgscreenr; vgascreenwin(scr); resetscreenimage(); return; @@ -381,27 +351,10 @@ vgactl(Cmdbuf *cb) align = 0; else align = strtoul(cb->f[2], 0, 0); - if(screenaperture(size, align) < 0) + if(screenaperture(scr, size, align) < 0) error("not enough free address space"); return; - case CMpanning: - if(strcmp(cb->f[1], "on") == 0){ - if(scr->cur == nil) - error("set cursor first"); - if(!scr->cur->doespanning) - error("panning not supported"); - panning = 1; - } - else if(strcmp(cb->f[1], "off") == 0){ - panning = 0; - }else - break; - if(scr->gscreen == nil) - return; - deletescreenimage(); - goto Resized; - case CMhwaccel: if(strcmp(cb->f[1], "on") == 0) hwaccel = 1; @@ -424,14 +377,11 @@ vgactl(Cmdbuf *cb) cmderror(cb, "bad VGA control message"); } -char Enooverlay[] = "No overlay support"; - static long vgawrite(Chan* c, void* a, long n, vlong off) { ulong offset = off; Cmdbuf *cb; - VGAscr *scr; switch((ulong)c->qid.path){ @@ -446,28 +396,11 @@ vgawrite(Chan* c, void* a, long n, vlong off) free(cb); nexterror(); } - vgactl(cb); + vgactl(&vgascreen[0], cb); poperror(); free(cb); return n; - case Qvgaovl: - scr = &vgascreen[0]; - if (scr->dev == nil || scr->dev->ovlwrite == nil) { - error(Enooverlay); - break; - } - return scr->dev->ovlwrite(scr, a, n, off); - - case Qvgaovlctl: - scr = &vgascreen[0]; - if (scr->dev == nil || scr->dev->ovlctl == nil) { - error(Enooverlay); - break; - } - scr->dev->ovlctl(scr, c, a, n); - return n; - default: error(Egreg); break; diff --git a/sys/src/9/pc/screen.c b/sys/src/9/pc/screen.c index 947c9aee0..8efb9fc50 100644 --- a/sys/src/9/pc/screen.c +++ b/sys/src/9/pc/screen.c @@ -16,16 +16,125 @@ extern VGAcur vgasoftcur; -Rectangle physgscreenr; - Memimage *gscreen; VGAscr vgascreen[1]; -int -screensize(int x, int y, int, ulong chan) +char *tiltstr[4] = { + "none", + "left", + "inverted", + "right", +}; + +static Point +tiltpt(int tilt, Point dim, Point p) { - VGAscr *scr; + switch(tilt&3){ + case 1: return Pt(dim.y-p.y-1, p.x); + case 2: return Pt(dim.x-p.x-1, dim.y-p.y-1); + case 3: return Pt(p.y, dim.x-p.x-1); + } + return p; +} + +static Rectangle +tiltrect(int tilt, Point dim, Rectangle r) +{ + switch(tilt&3){ + case 1: return Rect(dim.y-r.max.y, r.min.x, dim.y-r.min.y, r.max.x); + case 2: return Rect(dim.x-r.max.x, dim.y-r.max.y, dim.x-r.min.x, dim.y-r.min.y); + case 3: return Rect(r.min.y, dim.x-r.max.x, r.max.y, dim.x-r.min.x); + } + return r; +} + +static Point +tiltsize(int tilt, Point dim) +{ + return (tilt & 1) != 0 ? Pt(dim.y, dim.x) : dim; +} + +Rectangle +actualscreensize(VGAscr *scr) +{ + return Rpt(ZP, tiltsize(-scr->tilt, scr->gscreen->clipr.max)); +} + +void +setactualsize(VGAscr *scr, Rectangle r) +{ + qlock(&drawlock); + + r.min = ZP; + r.max = tiltsize(scr->tilt, r.max); + if(rectclip(&r, scr->gscreen->r) == 0){ + qunlock(&drawlock); + return; + } + scr->gscreen->clipr = r; + + qunlock(&drawlock); +} + +static char* +setscreensize0(VGAscr *scr, int width, int height, int depth, ulong chan, int tilt) +{ + int bpp, pitch; + + scr->gscreendata = nil; + scr->gscreen = nil; + if(gscreen != nil){ + freememimage(gscreen); + gscreen = nil; + } + if(scr->paddr == 0){ + if(scr->dev && scr->dev->page){ + scr->vaddr = KADDR(VGAMEM()); + scr->apsize = 1<<16; + } + scr->softscreen = 1; + } + + depth = chantodepth(chan); + bpp = (depth+7) / 8; + pitch = ((width * depth+31) & ~31) / 8; + + if(tilt) + scr->softscreen = 1; + if(scr->softscreen){ + gscreen = allocmemimage(Rpt(ZP, tiltsize(tilt, Pt(width, height))), chan); + scr->useflush = 1; + }else{ + static Memdata md; + + md.ref = 1; + if((md.bdata = scr->vaddr) == 0) + error("framebuffer not maped"); + gscreen = allocmemimaged(Rpt(ZP, Pt(width, height)), chan, &md); + scr->useflush = scr->dev && scr->dev->flush; + } + if(gscreen == nil) + return "no memory for vga memimage"; + + scr->bpp = bpp; + scr->pitch = pitch; + scr->width = width; + scr->height = height; + scr->tilt = tilt & 3; + + scr->palettedepth = 6; /* default */ + scr->memdefont = getmemdefont(); + scr->gscreen = gscreen; + scr->gscreendata = gscreen->data; + + return nil; +} + +void +setscreensize(VGAscr *scr, int x, int y, int z, ulong chan, int tilt) +{ + char *err; qlock(&drawlock); if(waserror()){ @@ -42,68 +151,37 @@ screensize(int x, int y, int, ulong chan) nexterror(); } - scr = &vgascreen[0]; - scr->gscreendata = nil; - scr->gscreen = nil; - if(gscreen){ - freememimage(gscreen); - gscreen = nil; - } - - if(scr->paddr == 0){ - if(scr->dev && scr->dev->page){ - scr->vaddr = KADDR(VGAMEM()); - scr->apsize = 1<<16; - } - scr->softscreen = 1; - } - if(scr->softscreen){ - gscreen = allocmemimage(Rect(0,0,x,y), chan); - scr->useflush = 1; - }else{ - static Memdata md; - - md.ref = 1; - if((md.bdata = scr->vaddr) == 0) - error("framebuffer not maped"); - gscreen = allocmemimaged(Rect(0,0,x,y), chan, &md); - scr->useflush = scr->dev && scr->dev->flush; - } - if(gscreen == nil) - error("no memory for vga memimage"); - - scr->palettedepth = 6; /* default */ - scr->memdefont = getmemdefont(); - scr->gscreen = gscreen; - scr->gscreendata = gscreen->data; - - physgscreenr = gscreen->r; + err = setscreensize0(scr, x, y, z, chan, tilt); + if(err != nil) + error(err); vgaimageinit(chan); + bootscreenconf(scr); unlock(&vgascreenlock); poperror(); drawcmap(); + if(scr->cur && scr->cur != &vgasoftcur){ + cursoroff(); + setcursor(&cursor); + cursoron(); + } + qunlock(&drawlock); poperror(); - - return 0; } int -screenaperture(int size, int align) +screenaperture(VGAscr *scr, int size, int align) { - VGAscr *scr; uvlong pa; - scr = &vgascreen[0]; - - if(scr->paddr) /* set up during enable */ + if(size == 0) return 0; - if(size == 0) + if(scr->paddr) /* set up during enable */ return 0; if(scr->dev && scr->dev->linear){ @@ -152,19 +230,61 @@ flushmemscreen(Rectangle r) { VGAscr *scr; uchar *sp, *disp, *sdisp, *edisp; - int y, len, incs, off, page; + int x, y, len, incs, off, page; scr = &vgascreen[0]; if(scr->gscreen == nil || scr->useflush == 0) return; - if(rectclip(&r, scr->gscreen->r) == 0) + if(rectclip(&r, scr->gscreen->clipr) == 0) return; + + if(scr->tilt){ + Point size; + + /* only supported on linear framebuffer */ + disp = scr->vaddr; + if(scr->paddr == 0 || disp == nil) + return; + + size = scr->gscreen->clipr.max; + r = tiltrect(-scr->tilt, size, r); + size = tiltsize(-scr->tilt, size); + sp = byteaddr(scr->gscreen, tiltpt(scr->tilt, size, r.min)); + incs = byteaddr(scr->gscreen, tiltpt(scr->tilt, size, Pt(r.min.x+1, r.min.y))) - sp; + + for(;;){ + sdisp = disp + r.min.y * scr->pitch; + for(x = r.min.x; x < r.max.x; x++, sp += incs){ + switch(scr->bpp){ + case 4: + ((ulong*)sdisp)[x] = *(ulong*)sp; + break; + case 3: + sdisp[x*3+0] = sp[0]; + sdisp[x*3+1] = sp[1]; + sdisp[x*3+2] = sp[2]; + break; + case 2: + ((ushort*)sdisp)[x] = *(ushort*)sp; + break; + case 1: + sdisp[x] = sp[0]; + break; + } + } + if(++r.min.y >= r.max.y) + break; + sp = byteaddr(scr->gscreen, tiltpt(scr->tilt, size, r.min)); + } + return; + } + if(scr->dev && scr->dev->flush){ scr->dev->flush(scr, r); return; } disp = scr->vaddr; - incs = scr->gscreen->width*sizeof(ulong); + incs = scr->pitch; off = (r.min.x*scr->gscreen->depth) / 8; len = (r.max.x*scr->gscreen->depth + 7) / 8; len -= off; @@ -299,16 +419,48 @@ setcolor(ulong p, ulong r, ulong g, ulong b) return setpalette(p, r, g, b); } +static void +tiltcursor(int t, Cursor *src, Cursor *dst) +{ + static Point dim = {16, 16}; + uint i, j, im, jm; + Point p; + + for(i = 0; i < 16*16; i++){ + p = tiltpt(t, dim, Pt(i&15,i>>4)); + j = p.y<<4 | p.x; + im = 0x80>>(i&7); + jm = 0x80>>(j&7); + if(src->clr[i>>3] & im) + dst->clr[j>>3] |= jm; + else + dst->clr[j>>3] &= ~jm; + if(src->set[i>>3] & im) + dst->set[j>>3] |= jm; + else + dst->set[j>>3] &= ~jm; + } + + p = Pt(-src->offset.x & 15, -src->offset.y & 15); + p = tiltpt(t, dim, p); + dst->offset = Pt(-p.x, -p.y); +} + void cursoron(void) { VGAscr *scr; VGAcur *cur; + Point p; scr = &vgascreen[0]; cur = scr->cur; - if(cur && cur->move) - cur->move(scr, mousexy()); + if(cur && cur->move){ + p = mousexy(); + if(scr->tilt && cur != &vgasoftcur) + p = tiltpt(-scr->tilt, scr->gscreen->clipr.max, p); + cur->move(scr, p); + } } void @@ -324,13 +476,18 @@ setcursor(Cursor* curs) scr = &vgascreen[0]; cur = scr->cur; - if(cur && cur->load) + if(cur && cur->load){ + if(scr->tilt && cur != &vgasoftcur){ + static Cursor tmp; + tiltcursor(-scr->tilt, curs, &tmp); + curs = &tmp; + } cur->load(scr, curs); + } } int hwaccel = 0; int hwblank = 0; -int panning = 0; int hwdraw(Memdrawparam *par) @@ -358,7 +515,7 @@ hwdraw(Memdrawparam *par) if(mask && mask->data->bdata == scrd->bdata) swcursoravoid(par->mr); } - if(!hwaccel || scr->softscreen) + if(!hwaccel || scr->softscreen || scr->tilt) return 0; if(dst->data->bdata != scrd->bdata || src == nil || mask == nil) return 0; @@ -396,13 +553,13 @@ blankscreen(int blank) { VGAscr *scr; + if(!hwblank) + return; scr = &vgascreen[0]; - if(hwblank){ - if(scr->blank) - scr->blank(scr, blank); - else - vgablank(scr, blank); - } + if(scr->blank) + scr->blank(scr, blank); + else + vgablank(scr, blank); } static char* @@ -461,6 +618,8 @@ vgalinearpci0(VGAscr *scr) Pcidev *p; p = scr->pci; + if(p == nil) + return "no pci card"; /* * Scan for largest memory region on card. @@ -575,7 +734,7 @@ void bootscreeninit(void) { VGAscr *scr; - int x, y, z; + int x, y, z, tilt; uvlong pa; ulong chan, sz; char *s, *p, *err; @@ -608,34 +767,36 @@ bootscreeninit(void) pa = strtoull(p+1, &s, 0); if(pa == 0) return; - if(*s++ == ' ') - sz = strtoul(s, nil, 0); + if(*s == ' ') + sz = strtoul(s+1, nil, 0); if(sz < x * y * (z+7)/8) sz = x * y * (z+7)/8; - /* map framebuffer */ + tilt = 0; + if((p = getconf("tiltscreen")) != nil){ + for(; tilt < nelem(tiltstr); tilt++) + if(strcmp(p, tiltstr[tilt]) == 0) + break; + tilt &= 3; + } + scr = &vgascreen[0]; + scr->dev = nil; + scr->softscreen = 1; + if((err = bootmapfb(scr, pa, sz)) != nil){ print("bootmapfb: %s\n", err); return; } - if(memimageinit() < 0) + if(memimageinit() < 0){ + print("memimageinit failed\n"); return; - - gscreen = allocmemimage(Rect(0,0,x,y), chan); - if(gscreen == nil) + } + if((err = setscreensize0(scr, x, y, z, chan, tilt)) != nil){ + print("setscreensize0: %s\n", err); return; - - scr->palettedepth = 6; /* default */ - scr->memdefont = getmemdefont(); - scr->gscreen = gscreen; - scr->gscreendata = gscreen->data; - scr->softscreen = 1; - scr->useflush = 1; - scr->dev = nil; - - physgscreenr = gscreen->r; + } vgaimageinit(chan); vgascreenwin(scr); @@ -659,10 +820,11 @@ bootscreenconf(VGAscr *scr) char conf[100], chan[30]; conf[0] = '\0'; - if(scr != nil && scr->paddr != 0 && scr->gscreen != nil) + if(scr != nil && scr->paddr != 0 && scr->gscreen != nil){ snprint(conf, sizeof(conf), "%dx%dx%d %s 0x%.8llux %d\n", - scr->gscreen->r.max.x, scr->gscreen->r.max.y, - scr->gscreen->depth, chantostr(chan, scr->gscreen->chan), + scr->width, scr->height, scr->gscreen->depth, chantostr(chan, scr->gscreen->chan), scr->paddr, scr->apsize); + ksetenv("tiltscreen", tiltstr[scr->tilt], 1); + } ksetenv("*bootscreen", conf, 1); } diff --git a/sys/src/9/pc/screen.h b/sys/src/9/pc/screen.h index 5f6c8ecf5..7e0e97628 100644 --- a/sys/src/9/pc/screen.h +++ b/sys/src/9/pc/screen.h @@ -75,8 +75,6 @@ struct VGAcur { void (*disable)(VGAscr*); void (*load)(VGAscr*, Cursor*); int (*move)(VGAscr*, Point); - - int doespanning; }; /* @@ -96,6 +94,12 @@ struct VGAscr { void* vaddr; int apsize; + int bpp; + int pitch; + + int width; + int height; + ulong io; /* device specific registers */ ulong *mmio; @@ -110,8 +114,8 @@ struct VGAscr { int (*scroll)(VGAscr*, Rectangle, Rectangle); void (*blank)(VGAscr*, int); ulong id; /* internal identifier for driver use */ - int overlayinit; int softscreen; + int tilt; }; extern VGAscr vgascreen[]; @@ -128,16 +132,17 @@ extern void mouseredraw(void); /* screen.c */ extern int hwaccel; /* use hw acceleration */ extern int hwblank; /* use hw blanking */ -extern int panning; /* use virtual screen panning */ +extern char *tiltstr[4]; +extern Rectangle actualscreensize(VGAscr*); +extern void setactualsize(VGAscr*, Rectangle); +extern void setscreensize(VGAscr*, int, int, int, ulong, int); extern void addvgaseg(char*, uvlong, ulong); extern Memdata* attachscreen(Rectangle*, ulong*, int*, int*, int*); extern void flushmemscreen(Rectangle); extern void cursoron(void); extern void cursoroff(void); extern void setcursor(Cursor*); -extern int screensize(int, int, int, ulong); -extern int screenaperture(int, int); -extern Rectangle physgscreenr; /* actual monitor size */ +extern int screenaperture(VGAscr*, int, int); extern void blankscreen(int); extern char* rgbmask2chan(char *buf, int depth, u32int rm, u32int gm, u32int bm); extern void bootscreeninit(void); diff --git a/sys/src/9/pc/vgact65545.c b/sys/src/9/pc/vgact65545.c index 2696f365f..cc10a4222 100644 --- a/sys/src/9/pc/vgact65545.c +++ b/sys/src/9/pc/vgact65545.c @@ -34,7 +34,7 @@ ct65545enable(VGAscr* scr) * Find a place for the cursor data in display memory. * Must be on a 1024-byte boundary. */ - storage = ROUND(scr->gscreen->width*sizeof(ulong)*scr->gscreen->r.max.y, 1024); + storage = ROUND(scr->pitch*scr->height, 1024); outl(0xB3D0, storage); scr->storage = storage; diff --git a/sys/src/9/pc/vgacyber938x.c b/sys/src/9/pc/vgacyber938x.c index 4259f06de..cd06f77a6 100644 --- a/sys/src/9/pc/vgacyber938x.c +++ b/sys/src/9/pc/vgacyber938x.c @@ -170,7 +170,7 @@ cyber938xcurenable(VGAscr* scr) /* * Find a place for the cursor data in display memory. */ - storage = ((scr->gscreen->width*sizeof(ulong)*scr->gscreen->r.max.y+1023)/1024); + storage = ((scr->pitch*scr->height+1023)/1024); vgaxo(Crtx, 0x44, storage & 0xFF); vgaxo(Crtx, 0x45, (storage>>8) & 0xFF); storage *= 1024; diff --git a/sys/src/9/pc/vgaet4000.c b/sys/src/9/pc/vgaet4000.c index 67a692981..7ed9e884e 100644 --- a/sys/src/9/pc/vgaet4000.c +++ b/sys/src/9/pc/vgaet4000.c @@ -79,7 +79,7 @@ et4000enable(VGAscr *scr) * 1024-byte boundary so that there's no danger of it * crossing a page. */ - scr->storage = (scr->gscreen->width*sizeof(ulong)*scr->gscreen->r.max.y+1023)/1024; + scr->storage = (scr->pitch*scr->height+1023)/1024; scr->storage *= 1024/4; outb(0x217A, 0xE8); outb(0x217B, scr->storage & 0xFF); diff --git a/sys/src/9/pc/vgamach64xx.c b/sys/src/9/pc/vgamach64xx.c index 0f1606c24..6fbbbad97 100644 --- a/sys/src/9/pc/vgamach64xx.c +++ b/sys/src/9/pc/vgamach64xx.c @@ -80,12 +80,6 @@ char Enotconfigured[] = "device not configured"; #define HOST_MEM_MODE_V 0xC0000000 #define HOST_MEM_MODE_NORMAL HOST_YUV_APERTURE_UPPER -static Chan *ovl_chan; /* Channel of controlling process */ -static int ovl_width; /* Width of input overlay buffer */ -static int ovl_height; /* Height of input overlay buffer */ -static int ovl_format; /* Overlay format */ -static ulong ovl_fib; /* Frame in bytes */ - enum { VTGTB1S1 = 0x01, /* Asic description for VTB1S1 and GTB1S1. */ VT4GTIIC = 0x3A, /* asic descr for VT4 and RAGE IIC */ @@ -117,7 +111,6 @@ struct Mach64types { static ulong mach64refclock; static Mach64types *mach64type; static int mach64revb; /* Revision B or greater? */ -static ulong mach64overlay; /* Overlay buffer */ static Mach64types mach64s[] = { ('C'<<8)|'T', 0, 1350000, /*?*/ 0, /* 4354: CT */ @@ -480,69 +473,10 @@ ptalmostinrect(Point p, Rectangle r) p.y>=r.min.y && p.y<=r.max.y; } -/* - * If necessary, translate the rectangle physr - * some multiple of [dx dy] so that it includes p. - * Return 1 if the rectangle changed. - */ -static int -screenpan(Point p, Rectangle *physr, int dx, int dy) -{ - int d; - - if(ptalmostinrect(p, *physr)) - return 0; - - if(p.y < physr->min.y){ - d = physr->min.y - (p.y&~(dy-1)); - physr->min.y -= d; - physr->max.y -= d; - } - if(p.y > physr->max.y){ - d = ((p.y+dy-1)&~(dy-1)) - physr->max.y; - physr->min.y += d; - physr->max.y += d; - } - - if(p.x < physr->min.x){ - d = physr->min.x - (p.x&~(dx-1)); - physr->min.x -= d; - physr->max.x -= d; - } - if(p.x > physr->max.x){ - d = ((p.x+dx-1)&~(dx-1)) - physr->max.x; - physr->min.x += d; - physr->max.x += d; - } - return 1; -} - static int mach64xxcurmove(VGAscr* scr, Point p) { int x, xo, y, yo; - int dx; - ulong off, pitch; - - /* - * If the point we want to display is outside the current - * screen rectangle, pan the screen to display it. - * - * We have to move in 64-bit chunks. - */ - if(scr->gscreen->depth == 24) - dx = (64*3)/24; - else - dx = 64 / scr->gscreen->depth; - - if(panning && screenpan(p, &physgscreenr, dx, 1)){ - off = (physgscreenr.min.y*Dx(scr->gscreen->r)+physgscreenr.min.x)/dx; - pitch = Dx(scr->gscreen->r)/8; - iow32(scr, CrtcOffPitch, (pitch<<22)|off); - } - - p.x -= physgscreenr.min.x; - p.y -= physgscreenr.min.y; /* * Mustn't position the cursor offscreen even partially, @@ -589,7 +523,7 @@ mach64xxcurenable(VGAscr* scr) * Find a place for the cursor data in display memory. * Must be 64-bit aligned. */ - storage = (scr->gscreen->width*sizeof(ulong)*scr->gscreen->r.max.y+7)/8; + storage = (scr->pitch*scr->height+7)/8; iow32(scr, CurOffset, storage); scr->storage = storage*8; @@ -643,64 +577,23 @@ resetengine(VGAscr *scr) iow32(scr, BusCntl, ior32(scr, BusCntl)|0x00A00000); } -static void -init_overlayclock(VGAscr *scr) -{ - uchar *cc, save, pll_ref_div, pll_vclk_cntl, vclk_post_div, - vclk_fb_div, ecp_div; - int i; - ulong dotclock; - - /* Taken from GLX */ - /* Get monitor dotclock, check for Overlay Scaler clock limit */ - cc = (uchar *)&scr->mmio[mmoffset[ClockCntl]]; - save = cc[1]; i = cc[0] & 3; - cc[1] = 2<<2; pll_ref_div = cc[2]; - cc[1] = 5<<2; pll_vclk_cntl = cc[2]; - cc[1] = 6<<2; vclk_post_div = (cc[2]>>(i+i)) & 3; - cc[1] = (7+i)<<2; vclk_fb_div = cc[2]; - - dotclock = 2 * mach64refclock * vclk_fb_div / - (pll_ref_div * (1 << vclk_post_div)); - /* ecp_div: 0=dotclock, 1=dotclock/2, 2=dotclock/4 */ - ecp_div = dotclock / mach64type->m64_ovlclock; - if (ecp_div>2) ecp_div = 2; - - /* Force a scaler clock factor of 1 if refclock * - * is unknown (VCLK_SRC not PLLVCLK) */ - if ((pll_vclk_cntl & 0x03) != 0x03) - ecp_div = 0; - if ((pll_vclk_cntl & 0x30) != ecp_div<<4) { - cc[1] = (5<<2)|2; - cc[2] = (pll_vclk_cntl&0xCF) | (ecp_div<<4); - } - - /* Restore PLL Register Index */ - cc[1] = save; -} - static void initengine(VGAscr *scr) { - ulong pitch; uchar *bios; ushort table; - pitch = Dx(scr->gscreen->r)/8; - if(scr->gscreen->depth == 24) - pitch *= 3; - resetengine(scr); waitforfifo(scr, 14); iow32(scr, ContextMask, ~0); - iow32(scr, DstOffPitch, pitch<<22); + iow32(scr, DstOffPitch, scr->pitch<<22); iow32(scr, DstYX, 0); iow32(scr, DstHeight, 0); iow32(scr, DstBresErr, 0); iow32(scr, DstBresInc, 0); iow32(scr, DstBresDec, 0); iow32(scr, DstCntl, 0x23); - iow32(scr, SrcOffPitch, pitch<<22); + iow32(scr, SrcOffPitch, scr->pitch<<22); iow32(scr, SrcYX, 0); iow32(scr, SrcHeight1Width1, 1); iow32(scr, SrcYXstart, 0); @@ -793,19 +686,16 @@ initengine(VGAscr *scr) static int mach64hwfill(VGAscr *scr, Rectangle r, ulong sval) { - ulong pitch; ulong ctl; /* shouldn't happen */ if(scr->io == 0x2EC || scr->io == 0x1C8 || scr->io == 0) return 0; - pitch = Dx(scr->gscreen->r)/8; ctl = 1|2; /* left-to-right, top-to-bottom */ if(scr->gscreen->depth == 24){ r.min.x *= 3; r.max.x *= 3; - pitch *= 3; ctl |= (1<<7)|(((r.min.x/4)%6)<<8); } @@ -817,7 +707,7 @@ mach64hwfill(VGAscr *scr, Rectangle r, ulong sval) iow32(scr, ClrCmpCntl, 0x00000000); iow32(scr, ScLeftRight, 0x1FFF0000); iow32(scr, ScTopBottom, 0x1FFF0000); - iow32(scr, DstOffPitch, pitch<<22); + iow32(scr, DstOffPitch, scr->pitch<<22); iow32(scr, DstCntl, ctl); iow32(scr, DstYX, (r.min.x<<16)|r.min.y); iow32(scr, DstHeightWidth, (Dx(r)<<16)|Dy(r)); @@ -829,17 +719,14 @@ mach64hwfill(VGAscr *scr, Rectangle r, ulong sval) static int mach64hwscroll(VGAscr *scr, Rectangle r, Rectangle sr) { - ulong pitch; Point dp, sp; ulong ctl; int dx, dy; dx = Dx(r); dy = Dy(r); - pitch = Dx(scr->gscreen->r)/8; if(scr->gscreen->depth == 24){ dx *= 3; - pitch *= 3; r.min.x *= 3; sr.min.x *= 3; } @@ -875,11 +762,11 @@ mach64hwscroll(VGAscr *scr, Rectangle r, Rectangle sr) iow32(scr, ClrCmpCntl, 0x00000000); waitforfifo(scr, 8); - iow32(scr, SrcOffPitch, pitch<<22); + iow32(scr, SrcOffPitch, scr->pitch<<22); iow32(scr, SrcCntl, 0x00000000); iow32(scr, SrcYX, (sp.x<<16)|sp.y); iow32(scr, SrcWidth1, dx); - iow32(scr, DstOffPitch, pitch<<22); + iow32(scr, DstOffPitch, scr->pitch<<22); iow32(scr, DstCntl, ctl); iow32(scr, DstYX, (dp.x<<16)|dp.y); @@ -957,222 +844,6 @@ mach64xxdrawinit(VGAscr *scr) } } -static void -ovl_configure(VGAscr *scr, Chan *c, char **field) -{ - int w, h; - char *format; - - w = (int)strtol(field[1], nil, 0); - h = (int)strtol(field[2], nil, 0); - format = field[3]; - - if (c != ovl_chan) - error(Einuse); - if (strcmp(format, "YUYV")) - error(Eunsupportedformat); - - ovl_width = w; - ovl_height = h; - ovl_fib = w * h * sizeof(ushort); - - waitforidle(scr); - scr->mmio[mmoffset[BusCntl]] |= 0x08000000; /* Enable regblock 1 */ - scr->mmio[mmoffset[OverlayScaleCntl]] = - SCALE_ZERO_EXTEND|SCALE_RED_TEMP_6500K| - SCALE_HORZ_BLEND|SCALE_VERT_BLEND; - scr->mmio[mmoffset[!mach64revb? Buf0Pitch: ScalerBuf0Pitch]] = w; - scr->mmio[mmoffset[CaptureConfig]] = - SCALER_FRAME_READ_MODE_FULL| - SCALER_BUF_MODE_SINGLE| - SCALER_BUF_NEXT_0; - scr->mmio[mmoffset[OverlayKeyCntl]] = !mach64revb? - OVERLAY_MIX_ALWAYS_V|(OVERLAY_EXCLUSIVE_NORMAL << 28): - 0x011; - - if (mach64type->m64_pro) { - waitforfifo(scr, 6); - - /* set the scaler co-efficient registers */ - scr->mmio[mmoffset[ScalerColourCntl]] = - (0x00) | (0x10 << 8) | (0x10 << 16); - scr->mmio[mmoffset[ScalerHCoef0]] = - (0x00) | (0x20 << 8); - scr->mmio[mmoffset[ScalerHCoef1]] = - (0x0D) | (0x20 << 8) | (0x06 << 16) | (0x0D << 24); - scr->mmio[mmoffset[ScalerHCoef2]] = - (0x0D) | (0x1C << 8) | (0x0A << 16) | (0x0D << 24); - scr->mmio[mmoffset[ScalerHCoef3]] = - (0x0C) | (0x1A << 8) | (0x0E << 16) | (0x0C << 24); - scr->mmio[mmoffset[ScalerHCoef4]] = - (0x0C) | (0x14 << 8) | (0x14 << 16) | (0x0C << 24); - } - - waitforfifo(scr, 3); - scr->mmio[mmoffset[VideoFormat]] = SCALE_IN_YVYU422 | - (!mach64revb? 0xC: 0); - - if (mach64overlay == 0) - mach64overlay = scr->storage + 64 * 64 * sizeof(uchar); - scr->mmio[mmoffset[!mach64revb? Buf0Offset: ScalerBuf0Offset]] = - mach64overlay; -} - -static void -ovl_enable(VGAscr *scr, Chan *c, char **field) -{ - int x, y, w, h; - long h_inc, v_inc; - - x = (int)strtol(field[1], nil, 0); - y = (int)strtol(field[2], nil, 0); - w = (int)strtol(field[3], nil, 0); - h = (int)strtol(field[4], nil, 0); - - if (x < 0 || x + w > physgscreenr.max.x || - y < 0 || y + h > physgscreenr.max.y) - error(Ebadarg); - - if (c != ovl_chan) - error(Einuse); - if (scr->mmio[mmoffset[CrtcGenCntl]] & 1) { /* double scan enable */ - y *= 2; - h *= 2; - } - - waitforfifo(scr, 2); - scr->mmio[mmoffset[OverlayYX]] = - ((x & 0xFFFF) << 16) | (y & 0xFFFF); - scr->mmio[mmoffset[OverlayYXEnd]] = - (((x + w) & 0xFFFF) << 16) | ((y + h) & 0xFFFF); - - h_inc = (ovl_width << 12) / (w >> 1); /* ??? */ - v_inc = (ovl_height << 12) / h; - waitforfifo(scr, 2); - scr->mmio[mmoffset[OverlayScaleInc]] = - ((h_inc & 0xFFFF) << 16) | (v_inc & 0xFFFF); - scr->mmio[mmoffset[ScalerHeightWidth]] = - ((ovl_width & 0xFFFF) << 16) | (ovl_height & 0xFFFF); - waitforidle(scr); - scr->mmio[mmoffset[OverlayScaleCntl]] |= - (SCALE_ENABLE|OVERLAY_ENABLE); -} - -static void -ovl_status(VGAscr *scr, Chan *, char **field) -{ - pprint("%s: %s %.4uX, VT/GT %s, PRO %s, ovlclock %lud, rev B %s, refclock %ld\n", - scr->dev->name, field[0], mach64type->m64_id, - mach64type->m64_vtgt? "yes": "no", - mach64type->m64_pro? "yes": "no", - mach64type->m64_ovlclock, - mach64revb? "yes": "no", - mach64refclock); - pprint("%s: storage @%.8luX, aperture @%8.ullX, ovl buf @%.8ulX\n", - scr->dev->name, scr->storage, scr->paddr, - mach64overlay); -} - -static void -ovl_openctl(VGAscr *, Chan *c, char **) -{ - if (ovl_chan) - error(Einuse); - ovl_chan = c; -} - -static void -ovl_closectl(VGAscr *scr, Chan *c, char **) -{ - if (c != ovl_chan) return; - - waitforidle(scr); - scr->mmio[mmoffset[OverlayScaleCntl]] &= - ~(SCALE_ENABLE|OVERLAY_ENABLE); - ovl_chan = nil; - ovl_width = ovl_height = ovl_fib = 0; -} - -enum -{ - CMclosectl, - CMconfigure, - CMenable, - CMopenctl, - CMstatus, -}; - -static void (*ovl_cmds[])(VGAscr *, Chan *, char **) = -{ - [CMclosectl] ovl_closectl, - [CMconfigure] ovl_configure, - [CMenable] ovl_enable, - [CMopenctl] ovl_openctl, - [CMstatus] ovl_status, -}; - -static Cmdtab mach64xxcmd[] = -{ - CMclosectl, "closectl", 1, - CMconfigure, "configure", 4, - CMenable, "enable", 5, - CMopenctl, "openctl", 1, - CMstatus, "status", 1, -}; - -static void -mach64xxovlctl(VGAscr *scr, Chan *c, void *a, int n) -{ - Cmdbuf *cb; - Cmdtab *ct; - - if(!mach64type->m64_vtgt) - error(Enodev); - - if(!scr->overlayinit){ - scr->overlayinit = 1; - init_overlayclock(scr); - } - cb = parsecmd(a, n); - if(waserror()){ - free(cb); - nexterror(); - } - - ct = lookupcmd(cb, mach64xxcmd, nelem(mach64xxcmd)); - - ovl_cmds[ct->index](scr, c, cb->f); - - poperror(); - free(cb); -} - -static int -mach64xxovlwrite(VGAscr *scr, void *a, int len, vlong offs) -{ - uchar *src; - int _len; - - if (ovl_chan == nil) return len; /* Acts as a /dev/null */ - - /* Calculate the destination address */ - _len = len; - src = (uchar *)a; - while (len > 0) { - ulong _offs; - int nb; - - _offs = (ulong)(offs % ovl_fib); - nb = (_offs + len > ovl_fib)? ovl_fib - _offs: len; - memmove((uchar *)scr->vaddr + mach64overlay + _offs, - src, nb); - offs += nb; - src += nb; - len -= nb; - } - return _len; -} - VGAdev vgamach64xxdev = { "mach64xx", @@ -1180,10 +851,7 @@ VGAdev vgamach64xxdev = { 0, /* disable */ 0, /* page */ mach64xxlinear, /* linear */ - mach64xxdrawinit, /* drawinit */ - 0, - mach64xxovlctl, /* overlay control */ - mach64xxovlwrite, /* write the overlay */ + mach64xxdrawinit, /* drawinit */ }; VGAcur vgamach64xxcur = { @@ -1193,7 +861,5 @@ VGAcur vgamach64xxcur = { mach64xxcurdisable, /* disable */ mach64xxcurload, /* load */ mach64xxcurmove, /* move */ - - 1 /* doespanning */ }; diff --git a/sys/src/9/pc/vgamga4xx.c b/sys/src/9/pc/vgamga4xx.c index 30bcf7822..5799e023b 100644 --- a/sys/src/9/pc/vgamga4xx.c +++ b/sys/src/9/pc/vgamga4xx.c @@ -405,7 +405,6 @@ static int mga4xxscroll(VGAscr *scr, Rectangle dr, Rectangle sr) { uchar * mga; - int pitch; int width, height; ulong start, end, sgn; Point sp, dp; @@ -421,7 +420,6 @@ mga4xxscroll(VGAscr *scr, Rectangle dr, Rectangle sr) if(eqpt(sp, dp)) return 1; - pitch = Dx(scr->gscreen->r); width = Dx(sr); height = Dy(sr); sgn = 0; @@ -433,7 +431,7 @@ mga4xxscroll(VGAscr *scr, Rectangle dr, Rectangle sr) } width--; - start = end = sp.x + (sp.y * pitch); + start = end = sp.x + (sp.y * scr->width); if(dp.x > sp.x && dp.x < sp.x + width){ start += width; @@ -445,7 +443,7 @@ mga4xxscroll(VGAscr *scr, Rectangle dr, Rectangle sr) mga_fifo(mga, 8); mgawrite32(mga, DWGCTL, 0); mgawrite32(mga, SGN, sgn); - mgawrite32(mga, AR5, sgn & SGN_UP ? -pitch : pitch); + mgawrite32(mga, AR5, sgn & SGN_UP ? -scr->width : scr->width); mgawrite32(mga, AR0, end); mgawrite32(mga, AR3, start); mgawrite32(mga, FXBNDRY, ((dp.x + width) << 16) | dp.x); diff --git a/sys/src/9/pc/vganeomagic.c b/sys/src/9/pc/vganeomagic.c index 1cc2a02d9..ad7208f6a 100644 --- a/sys/src/9/pc/vganeomagic.c +++ b/sys/src/9/pc/vganeomagic.c @@ -376,8 +376,8 @@ neomagichwfill(VGAscr *scr, Rectangle r, ulong sval) | NEO_BC3_SKIP_MAPPING | GXcopy; mmio[DstStartOff] = scr->paddr - + r.min.y*scr->gscreen->width*sizeof(ulong) - + r.min.x*scr->gscreen->depth/BI2BY; + + r.min.y*scr->pitch + + r.min.x*scr->bpp; mmio[XYExt] = (Dy(r) << 16) | (Dx(r) & 0xffff); waitforidle(scr); return 1; @@ -387,13 +387,9 @@ static int neomagichwscroll(VGAscr *scr, Rectangle r, Rectangle sr) { ulong *mmio; - int pitch, pixel; mmio = scr->mmio; - pitch = scr->gscreen->width*sizeof(ulong); - pixel = scr->gscreen->depth/BI2BY; - waitforfifo(scr, 4); if (r.min.y < sr.min.y || (r.min.y == sr.min.y && r.min.x < sr.min.x)) { /* start from upper-left */ @@ -402,9 +398,9 @@ neomagichwscroll(VGAscr *scr, Rectangle r, Rectangle sr) | NEO_BC3_SKIP_MAPPING | GXcopy; mmio[SrcStartOff] = scr->paddr - + sr.min.y*pitch + sr.min.x*pixel; + + sr.min.y*scr->pitch + sr.min.x*scr->bpp; mmio[DstStartOff] = scr->paddr - + r.min.y*pitch + r.min.x*pixel; + + r.min.y*scr->pitch + r.min.x*scr->bpp; } else { /* start from lower-right */ mmio[BltCntl] = neomagicbltflags @@ -415,9 +411,9 @@ neomagichwscroll(VGAscr *scr, Rectangle r, Rectangle sr) | NEO_BC3_SKIP_MAPPING | GXcopy; mmio[SrcStartOff] = scr->paddr - + (sr.max.y-1)*pitch + (sr.max.x-1)*pixel; + + (sr.max.y-1)*scr->pitch + (sr.max.x-1)*scr->bpp; mmio[DstStartOff] = scr->paddr - + (r.max.y-1)*pitch + (r.max.x-1)*pixel; + + (r.max.y-1)*scr->pitch + (r.max.x-1)*scr->bpp; } mmio[XYExt] = (Dy(r) << 16) | (Dx(r) & 0xffff); waitforidle(scr); @@ -428,12 +424,10 @@ static void neomagicdrawinit(VGAscr *scr) { ulong *mmio; - uint bltmode, pitch; + uint bltmode; mmio = scr->mmio; - pitch = scr->gscreen->width*sizeof(ulong); - neomagicbltflags = bltmode = 0; switch(scr->gscreen->depth) { @@ -450,7 +444,7 @@ neomagicdrawinit(VGAscr *scr) return; } - switch(Dx(scr->gscreen->r)) { + switch(scr->width) { case 320: bltmode |= NEO_MODE1_X_320; neomagicbltflags |= NEO_BC1_X_320; @@ -486,7 +480,7 @@ neomagicdrawinit(VGAscr *scr) waitforidle(scr); mmio[BltStat] = bltmode << 16; - mmio[Pitch] = (pitch << 16) | (pitch & 0xffff); + mmio[Pitch] = (scr->pitch << 16) | (scr->pitch & 0xffff); scr->fill = neomagichwfill; scr->scroll = neomagichwscroll; diff --git a/sys/src/9/pc/vganvidia.c b/sys/src/9/pc/vganvidia.c index 0d20f43a8..3267e6b52 100644 --- a/sys/src/9/pc/vganvidia.c +++ b/sys/src/9/pc/vganvidia.c @@ -343,13 +343,11 @@ static int nvresetgraphics(VGAscr *scr) { ulong surfaceFormat, patternFormat, rectFormat, lineFormat; - int pitch, i; + int i; if(scr->paddr == 0) return -1; - pitch = scr->gscreen->width*sizeof(ulong); - /* * DMA is at the end of the virtual window, * but we might have cut it short when mapping it. @@ -416,7 +414,7 @@ nvresetgraphics(VGAscr *scr) nvdmastart(scr, SURFACE_FORMAT, 4); nvdmanext(surfaceFormat); - nvdmanext(pitch | (pitch << 16)); + nvdmanext(scr->pitch | (scr->pitch << 16)); nvdmanext(0); nvdmanext(0); diff --git a/sys/src/9/pc/vgaradeon.c b/sys/src/9/pc/vgaradeon.c index e23d90753..95449b56e 100644 --- a/sys/src/9/pc/vgaradeon.c +++ b/sys/src/9/pc/vgaradeon.c @@ -350,7 +350,7 @@ radeonscroll(VGAscr*scr, Rectangle dst, Rectangle src) static void radeondrawinit(VGAscr*scr) { - ulong bpp, dtype, i, pitch, clock_cntl_index, mclk_cntl, rbbm_soft_reset; + ulong dtype, i, clock_cntl_index, mclk_cntl, rbbm_soft_reset; if (scr->mmio == 0) return; @@ -359,19 +359,15 @@ radeondrawinit(VGAscr*scr) case 6: case 8: dtype = 2; - bpp = 1; break; case 15: dtype = 3; - bpp = 2; break; case 16: dtype = 4; - bpp = 2; break; case 32: dtype = 6; - bpp = 4; break; default: return; @@ -413,11 +409,10 @@ radeondrawinit(VGAscr*scr) radeonwaitfifo(scr, 1); OUTREG(scr->mmio, RB2D_DSTCACHE_MODE, 0); - pitch = Dx(scr->gscreen->r) * bpp; radeonwaitfifo(scr, 4); - OUTREG(scr->mmio, DEFAULT_PITCH, pitch); - OUTREG(scr->mmio, DST_PITCH, pitch); - OUTREG(scr->mmio, SRC_PITCH, pitch); + OUTREG(scr->mmio, DEFAULT_PITCH, scr->pitch); + OUTREG(scr->mmio, DST_PITCH, scr->pitch); + OUTREG(scr->mmio, SRC_PITCH, scr->pitch); OUTREG(scr->mmio, DST_PITCH_OFFSET_C, 0); radeonwaitfifo(scr, 3); @@ -501,5 +496,4 @@ VGAcur vgaradeoncur = { radeoncurdisable, radeoncurload, radeoncurmove, - 0 /* doespanning */ }; diff --git a/sys/src/9/pc/vgas3.c b/sys/src/9/pc/vgas3.c index 710756d7c..e6e400fda 100644 --- a/sys/src/9/pc/vgas3.c +++ b/sys/src/9/pc/vgas3.c @@ -309,7 +309,7 @@ s3enable(VGAscr* scr) * Find a place for the cursor data in display memory. * Must be on a 1024-byte boundary. */ - storage = (scr->gscreen->width*sizeof(ulong)*scr->gscreen->r.max.y+1023)/1024; + storage = (scr->pitch*scr->height+1023)/1024; vgaxo(Crtx, 0x4C, storage>>8); vgaxo(Crtx, 0x4D, storage & 0xFF); storage *= 1024; @@ -420,14 +420,12 @@ hwscroll(VGAscr *scr, Rectangle r, Rectangle sr) { enum { Bitbltop = 0xCC }; /* copy source */ ulong *mmio; - ulong cmd, stride; + ulong cmd; Point dp, sp; - int did, d; + int did; - d = scr->gscreen->depth; - did = (d-8)/8; + did = (scr->gscreen->depth-8)/8; cmd = 0x00000020|(Bitbltop<<17)|(did<<2); - stride = Dx(scr->gscreen->r)*d/8; if(r.min.x <= sr.min.x){ cmd |= 1<<25; @@ -452,7 +450,7 @@ hwscroll(VGAscr *scr, Rectangle r, Rectangle sr) waitforfifo(scr, 7); mmio[SrcBase] = scr->paddr; mmio[DstBase] = scr->paddr; - mmio[Stride] = (stride<<16)|stride; + mmio[Stride] = (scr->pitch<<16)|scr->pitch; mmio[WidthHeight] = ((Dx(r)-1)<<16)|Dy(r); mmio[SrcXY] = (sp.x<<16)|sp.y; mmio[DestXY] = (dp.x<<16)|dp.y; @@ -466,20 +464,18 @@ hwfill(VGAscr *scr, Rectangle r, ulong sval) { enum { Bitbltop = 0xCC }; /* copy source */ ulong *mmio; - ulong cmd, stride; - int did, d; + ulong cmd; + int did; - d = scr->gscreen->depth; - did = (d-8)/8; + did = (scr->gscreen->depth-8)/8; cmd = 0x16000120|(Bitbltop<<17)|(did<<2); - stride = Dx(scr->gscreen->r)*d/8; mmio = scr->mmio; waitforlinearfifo(scr); waitforfifo(scr, 8); mmio[SrcBase] = scr->paddr; mmio[DstBase] = scr->paddr; mmio[DstBase] = scr->paddr; - mmio[Stride] = (stride<<16)|stride; + mmio[Stride] = (scr->pitch<<16)|scr->pitch; mmio[FgrdData] = sval; mmio[WidthHeight] = ((Dx(r)-1)<<16)|Dy(r); mmio[DestXY] = (r.min.x<<16)|r.min.y; diff --git a/sys/src/9/pc/vgasavage.c b/sys/src/9/pc/vgasavage.c index f4c7f9f77..ce54c9937 100644 --- a/sys/src/9/pc/vgasavage.c +++ b/sys/src/9/pc/vgasavage.c @@ -540,7 +540,7 @@ savageinit(VGAscr *scr) /* set bitmap descriptors */ bd = (scr->gscreen->depth<gscreen->r)<width<gscreen->r); - depth = scr->gscreen->depth; - switch(scr->gscreen->chan){ case RGB16: fmt = 3; @@ -488,8 +483,8 @@ t2r4drawinit(VGAscr *scr) d[BufCtl] = fmt<<24; d[DeSorg] = 0; d[DeDorg] = 0; - d[DeSptch] = (pitch*depth)/8; - d[DeDptch] = (pitch*depth)/8; + d[DeSptch] = scr->pitch; + d[DeDptch] = scr->pitch; d[CmdClp] = 0; /* 2 = inside rectangle */ d[Mask] = ~0; d[DeKey] = 0;