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.
This commit is contained in:
cinap_lenrek 2020-12-27 23:08:59 +01:00
parent 874e71c8dc
commit 806353ec9e
15 changed files with 352 additions and 659 deletions

View file

@ -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

View file

@ -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;

View file

@ -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);
}

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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 */
};

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -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 */
};

View file

@ -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;

View file

@ -540,7 +540,7 @@ savageinit(VGAscr *scr)
/* set bitmap descriptors */
bd = (scr->gscreen->depth<<DepthShift) |
(Dx(scr->gscreen->r)<<StrideShift) | BlockWriteDis
(scr->width<<StrideShift) | BlockWriteDis
| BDS64;
*(ulong*)(mmio+GBD1) = 0;

View file

@ -459,14 +459,9 @@ t2r4blank(VGAscr *scr, int blank)
static void
t2r4drawinit(VGAscr *scr)
{
ulong pitch;
int depth;
int fmt;
ulong *d;
pitch = Dx(scr->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;