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:
parent
874e71c8dc
commit
806353ec9e
15 changed files with 352 additions and 659 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 */
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue