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 bind #v /dev
|
||||||
|
|
||||||
.B /dev/vgactl
|
.B /dev/vgactl
|
||||||
.B /dev/vgaovl
|
|
||||||
.B /dev/vgaovlctl
|
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The VGA device allows configuration of a graphics controller
|
The VGA device allows configuration of a graphics controller
|
||||||
|
@ -48,31 +46,25 @@ pixels wide by
|
||||||
.I Y
|
.I Y
|
||||||
pixels high.
|
pixels high.
|
||||||
This message is optional;
|
This message is optional;
|
||||||
it is used to implement panning and to accommodate
|
it is used to accommodate displays that require the
|
||||||
displays that require the in-memory screen image
|
in-memory screen image to have certain alignment properties.
|
||||||
to have certain alignment properties.
|
|
||||||
For example, a 1400x1050 screen with a 1408x1050 in-memory image
|
For example, a 1400x1050 screen with a 1408x1050 in-memory image
|
||||||
will use
|
will use
|
||||||
.B "size 1408x1050
|
.B "size 1408x1050
|
||||||
but
|
but
|
||||||
.BR "actualsize 1400x1050" .
|
.BR "actualsize 1400x1050" .
|
||||||
.TP
|
.TP
|
||||||
.BI panning " mode"
|
.BI tilt " value"
|
||||||
Depending on whether
|
Set the tilt of the screen,
|
||||||
.I mode
|
altering the screen's orientation.
|
||||||
is
|
The
|
||||||
.B on
|
.I value
|
||||||
or
|
can be one of:
|
||||||
.BR off ,
|
.BR none ,
|
||||||
enable or disable panning in a virtual screen.
|
.BR left ,
|
||||||
If panning is on and the screen's
|
.B inverted
|
||||||
.B size
|
and
|
||||||
is larger than its
|
.BR right .
|
||||||
.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.
|
|
||||||
.TP
|
.TP
|
||||||
.BI type " ctlr"
|
.BI type " ctlr"
|
||||||
Set the type of VGA controller being used.
|
Set the type of VGA controller being used.
|
||||||
|
@ -206,46 +198,6 @@ This must be sent after setting the
|
||||||
Reading
|
Reading
|
||||||
.B vgactl
|
.B vgactl
|
||||||
returns the current settings, one per line.
|
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
|
.SH EXAMPLES
|
||||||
The following disables hardware acceleration.
|
The following disables hardware acceleration.
|
||||||
.IP
|
.IP
|
||||||
|
|
|
@ -19,15 +19,11 @@
|
||||||
enum {
|
enum {
|
||||||
Qdir,
|
Qdir,
|
||||||
Qvgactl,
|
Qvgactl,
|
||||||
Qvgaovl,
|
|
||||||
Qvgaovlctl,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static Dirtab vgadir[] = {
|
static Dirtab vgadir[] = {
|
||||||
".", { Qdir, 0, QTDIR }, 0, 0550,
|
".", { Qdir, 0, QTDIR }, 0, 0550,
|
||||||
"vgactl", { Qvgactl, 0 }, 0, 0660,
|
"vgactl", { Qvgactl, 0 }, 0, 0660,
|
||||||
"vgaovl", { Qvgaovl, 0 }, 0, 0660,
|
|
||||||
"vgaovlctl", { Qvgaovlctl, 0 }, 0, 0660,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -38,12 +34,12 @@ enum {
|
||||||
CMhwgc,
|
CMhwgc,
|
||||||
CMlinear,
|
CMlinear,
|
||||||
CMpalettedepth,
|
CMpalettedepth,
|
||||||
CMpanning,
|
|
||||||
CMsize,
|
CMsize,
|
||||||
CMtextmode,
|
CMtextmode,
|
||||||
CMtype,
|
CMtype,
|
||||||
CMsoftscreen,
|
CMsoftscreen,
|
||||||
CMpcidev,
|
CMpcidev,
|
||||||
|
CMtilt,
|
||||||
};
|
};
|
||||||
|
|
||||||
static Cmdtab vgactlmsg[] = {
|
static Cmdtab vgactlmsg[] = {
|
||||||
|
@ -54,12 +50,12 @@ static Cmdtab vgactlmsg[] = {
|
||||||
CMhwgc, "hwgc", 2,
|
CMhwgc, "hwgc", 2,
|
||||||
CMlinear, "linear", 0,
|
CMlinear, "linear", 0,
|
||||||
CMpalettedepth, "palettedepth", 2,
|
CMpalettedepth, "palettedepth", 2,
|
||||||
CMpanning, "panning", 2,
|
|
||||||
CMsize, "size", 3,
|
CMsize, "size", 3,
|
||||||
CMtextmode, "textmode", 1,
|
CMtextmode, "textmode", 1,
|
||||||
CMtype, "type", 2,
|
CMtype, "type", 2,
|
||||||
CMsoftscreen, "softscreen", 2,
|
CMsoftscreen, "softscreen", 2,
|
||||||
CMpcidev, "pcidev", 2,
|
CMpcidev, "pcidev", 2,
|
||||||
|
CMtilt, "tilt", 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -120,35 +116,12 @@ vgastat(Chan* c, uchar* dp, int n)
|
||||||
static Chan*
|
static Chan*
|
||||||
vgaopen(Chan* c, int omode)
|
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);
|
return devopen(c, omode, vgadir, nelem(vgadir), devgen);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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
|
static long
|
||||||
|
@ -176,19 +149,20 @@ vgaread(Chan* c, void* a, long n, vlong off)
|
||||||
p = seprint(p, e, "type %s\n",
|
p = seprint(p, e, "type %s\n",
|
||||||
scr->dev != nil ? scr->dev->name : "cga");
|
scr->dev != nil ? scr->dev->name : "cga");
|
||||||
if(scr->gscreen != nil) {
|
if(scr->gscreen != nil) {
|
||||||
|
Rectangle r;
|
||||||
|
|
||||||
p = seprint(p, e, "size %dx%dx%d %s\n",
|
p = seprint(p, e, "size %dx%dx%d %s\n",
|
||||||
scr->gscreen->r.max.x, scr->gscreen->r.max.y,
|
scr->width, scr->height, scr->gscreen->depth,
|
||||||
scr->gscreen->depth, chantostr(chbuf, scr->gscreen->chan));
|
chantostr(chbuf, scr->gscreen->chan));
|
||||||
if(Dx(scr->gscreen->r) != Dx(physgscreenr)
|
r = actualscreensize(scr);
|
||||||
|| Dy(scr->gscreen->r) != Dy(physgscreenr))
|
if(scr->width != r.max.x || scr->height != r.max.y)
|
||||||
p = seprint(p, e, "actualsize %dx%d\n",
|
p = seprint(p, e, "actualsize %dx%d\n", r.max.x, r.max.y);
|
||||||
physgscreenr.max.x, physgscreenr.max.y);
|
p = seprint(p, e, "tilt %s\n", tiltstr[scr->tilt]);
|
||||||
}
|
}
|
||||||
p = seprint(p, e, "hwgc %s\n",
|
p = seprint(p, e, "hwgc %s\n",
|
||||||
scr->cur != nil ? scr->cur->name : "off");
|
scr->cur != nil ? scr->cur->name : "off");
|
||||||
p = seprint(p, e, "hwaccel %s\n", hwaccel ? "on" : "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, "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",
|
p = seprint(p, e, "addr p 0x%.8llux v %#p size %#ux\n",
|
||||||
scr->paddr, scr->vaddr, scr->apsize);
|
scr->paddr, scr->vaddr, scr->apsize);
|
||||||
p = seprint(p, e, "softscreen %s\n", scr->softscreen ? "on" : "off");
|
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;
|
return n;
|
||||||
|
|
||||||
case Qvgaovl:
|
|
||||||
case Qvgaovlctl:
|
|
||||||
error(Ebadusefd);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
error(Egreg);
|
error(Egreg);
|
||||||
break;
|
break;
|
||||||
|
@ -216,18 +185,16 @@ static char Ebusy[] = "vga already configured";
|
||||||
static char Enoscreen[] = "set the screen size first";
|
static char Enoscreen[] = "set the screen size first";
|
||||||
|
|
||||||
static void
|
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;
|
Rectangle r;
|
||||||
char *chanstr, *p;
|
char *chanstr, *p;
|
||||||
ulong chan;
|
ulong chan;
|
||||||
Cmdtab *ct;
|
Cmdtab *ct;
|
||||||
VGAscr *scr;
|
|
||||||
extern VGAdev *vgadev[];
|
extern VGAdev *vgadev[];
|
||||||
extern VGAcur *vgacur[];
|
extern VGAcur *vgacur[];
|
||||||
|
|
||||||
scr = &vgascreen[0];
|
|
||||||
ct = lookupcmd(cb, vgactlmsg, nelem(vgactlmsg));
|
ct = lookupcmd(cb, vgactlmsg, nelem(vgactlmsg));
|
||||||
switch(ct->index){
|
switch(ct->index){
|
||||||
case CMhwgc:
|
case CMhwgc:
|
||||||
|
@ -298,14 +265,15 @@ vgactl(Cmdbuf *cb)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case CMsize:
|
case CMsize:
|
||||||
x = strtoul(cb->f[1], &p, 0);
|
r.min = ZP;
|
||||||
|
r.max.x = strtoul(cb->f[1], &p, 0);
|
||||||
if(*p)
|
if(*p)
|
||||||
p++;
|
p++;
|
||||||
y = strtoul(p, &p, 0);
|
r.max.y = strtoul(p, &p, 0);
|
||||||
if(*p)
|
if(*p)
|
||||||
p++;
|
p++;
|
||||||
z = strtoul(p, &p, 0);
|
z = strtoul(p, &p, 0);
|
||||||
if(badrect(Rect(0,0,x,y)))
|
if(badrect(r))
|
||||||
error(Ebadarg);
|
error(Ebadarg);
|
||||||
chanstr = cb->f[2];
|
chanstr = cb->f[2];
|
||||||
if((chan = strtochan(chanstr)) == 0)
|
if((chan = strtochan(chanstr)) == 0)
|
||||||
|
@ -313,32 +281,30 @@ vgactl(Cmdbuf *cb)
|
||||||
if(chantodepth(chan) != z)
|
if(chantodepth(chan) != z)
|
||||||
error("depth, channel do not match");
|
error("depth, channel do not match");
|
||||||
deletescreenimage();
|
deletescreenimage();
|
||||||
if(screensize(x, y, z, chan))
|
setscreensize(scr, r.max.x, r.max.y, z, chan, scr->tilt);
|
||||||
error(Egreg);
|
|
||||||
bootscreenconf(scr);
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case CMactualsize:
|
case CMactualsize:
|
||||||
if(scr->gscreen == nil)
|
if(scr->gscreen == nil)
|
||||||
error(Enoscreen);
|
error(Enoscreen);
|
||||||
x = strtoul(cb->f[1], &p, 0);
|
r.min = ZP;
|
||||||
|
r.max.x = strtoul(cb->f[1], &p, 0);
|
||||||
if(*p)
|
if(*p)
|
||||||
p++;
|
p++;
|
||||||
y = strtoul(p, nil, 0);
|
r.max.y = strtoul(p, nil, 0);
|
||||||
r = Rect(0,0,x,y);
|
|
||||||
if(badrect(r))
|
if(badrect(r))
|
||||||
error(Ebadarg);
|
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");
|
error("physical screen bigger than virtual");
|
||||||
deletescreenimage();
|
deletescreenimage();
|
||||||
physgscreenr = r;
|
setactualsize(scr, r);
|
||||||
goto Resized;
|
goto Resized;
|
||||||
|
|
||||||
case CMpalettedepth:
|
case CMpalettedepth:
|
||||||
x = strtoul(cb->f[1], &p, 0);
|
z = strtoul(cb->f[1], &p, 0);
|
||||||
if(x != 8 && x != 6)
|
if(z != 8 && z != 6)
|
||||||
error(Ebadarg);
|
error(Ebadarg);
|
||||||
scr->palettedepth = x;
|
scr->palettedepth = z;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case CMsoftscreen:
|
case CMsoftscreen:
|
||||||
|
@ -348,17 +314,22 @@ vgactl(Cmdbuf *cb)
|
||||||
scr->softscreen = 0;
|
scr->softscreen = 0;
|
||||||
else
|
else
|
||||||
break;
|
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)
|
if(scr->gscreen == nil)
|
||||||
return;
|
return;
|
||||||
r = physgscreenr;
|
r = actualscreensize(scr);
|
||||||
x = scr->gscreen->r.max.x;
|
|
||||||
y = scr->gscreen->r.max.y;
|
|
||||||
z = scr->gscreen->depth;
|
|
||||||
chan = scr->gscreen->chan;
|
chan = scr->gscreen->chan;
|
||||||
|
z = scr->gscreen->depth;
|
||||||
deletescreenimage();
|
deletescreenimage();
|
||||||
if(screensize(x, y, z, chan))
|
setscreensize(scr, scr->width, scr->height, z, chan, tilt);
|
||||||
error(Egreg);
|
setactualsize(scr, r);
|
||||||
physgscreenr = r;
|
|
||||||
/* no break */
|
/* no break */
|
||||||
case CMdrawinit:
|
case CMdrawinit:
|
||||||
if(scr->gscreen == nil)
|
if(scr->gscreen == nil)
|
||||||
|
@ -368,7 +339,6 @@ vgactl(Cmdbuf *cb)
|
||||||
hwblank = scr->blank != nil;
|
hwblank = scr->blank != nil;
|
||||||
hwaccel = scr->fill != nil || scr->scroll != nil;
|
hwaccel = scr->fill != nil || scr->scroll != nil;
|
||||||
Resized:
|
Resized:
|
||||||
scr->gscreen->clipr = panning ? scr->gscreen->r : physgscreenr;
|
|
||||||
vgascreenwin(scr);
|
vgascreenwin(scr);
|
||||||
resetscreenimage();
|
resetscreenimage();
|
||||||
return;
|
return;
|
||||||
|
@ -381,27 +351,10 @@ vgactl(Cmdbuf *cb)
|
||||||
align = 0;
|
align = 0;
|
||||||
else
|
else
|
||||||
align = strtoul(cb->f[2], 0, 0);
|
align = strtoul(cb->f[2], 0, 0);
|
||||||
if(screenaperture(size, align) < 0)
|
if(screenaperture(scr, size, align) < 0)
|
||||||
error("not enough free address space");
|
error("not enough free address space");
|
||||||
return;
|
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:
|
case CMhwaccel:
|
||||||
if(strcmp(cb->f[1], "on") == 0)
|
if(strcmp(cb->f[1], "on") == 0)
|
||||||
hwaccel = 1;
|
hwaccel = 1;
|
||||||
|
@ -424,14 +377,11 @@ vgactl(Cmdbuf *cb)
|
||||||
cmderror(cb, "bad VGA control message");
|
cmderror(cb, "bad VGA control message");
|
||||||
}
|
}
|
||||||
|
|
||||||
char Enooverlay[] = "No overlay support";
|
|
||||||
|
|
||||||
static long
|
static long
|
||||||
vgawrite(Chan* c, void* a, long n, vlong off)
|
vgawrite(Chan* c, void* a, long n, vlong off)
|
||||||
{
|
{
|
||||||
ulong offset = off;
|
ulong offset = off;
|
||||||
Cmdbuf *cb;
|
Cmdbuf *cb;
|
||||||
VGAscr *scr;
|
|
||||||
|
|
||||||
switch((ulong)c->qid.path){
|
switch((ulong)c->qid.path){
|
||||||
|
|
||||||
|
@ -446,28 +396,11 @@ vgawrite(Chan* c, void* a, long n, vlong off)
|
||||||
free(cb);
|
free(cb);
|
||||||
nexterror();
|
nexterror();
|
||||||
}
|
}
|
||||||
vgactl(cb);
|
vgactl(&vgascreen[0], cb);
|
||||||
poperror();
|
poperror();
|
||||||
free(cb);
|
free(cb);
|
||||||
return n;
|
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:
|
default:
|
||||||
error(Egreg);
|
error(Egreg);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -16,16 +16,125 @@
|
||||||
|
|
||||||
extern VGAcur vgasoftcur;
|
extern VGAcur vgasoftcur;
|
||||||
|
|
||||||
Rectangle physgscreenr;
|
|
||||||
|
|
||||||
Memimage *gscreen;
|
Memimage *gscreen;
|
||||||
|
|
||||||
VGAscr vgascreen[1];
|
VGAscr vgascreen[1];
|
||||||
|
|
||||||
int
|
char *tiltstr[4] = {
|
||||||
screensize(int x, int y, int, ulong chan)
|
"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);
|
qlock(&drawlock);
|
||||||
if(waserror()){
|
if(waserror()){
|
||||||
|
@ -42,68 +151,37 @@ screensize(int x, int y, int, ulong chan)
|
||||||
nexterror();
|
nexterror();
|
||||||
}
|
}
|
||||||
|
|
||||||
scr = &vgascreen[0];
|
err = setscreensize0(scr, x, y, z, chan, tilt);
|
||||||
scr->gscreendata = nil;
|
if(err != nil)
|
||||||
scr->gscreen = nil;
|
error(err);
|
||||||
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;
|
|
||||||
|
|
||||||
vgaimageinit(chan);
|
vgaimageinit(chan);
|
||||||
|
bootscreenconf(scr);
|
||||||
|
|
||||||
unlock(&vgascreenlock);
|
unlock(&vgascreenlock);
|
||||||
poperror();
|
poperror();
|
||||||
|
|
||||||
drawcmap();
|
drawcmap();
|
||||||
|
|
||||||
|
if(scr->cur && scr->cur != &vgasoftcur){
|
||||||
|
cursoroff();
|
||||||
|
setcursor(&cursor);
|
||||||
|
cursoron();
|
||||||
|
}
|
||||||
|
|
||||||
qunlock(&drawlock);
|
qunlock(&drawlock);
|
||||||
poperror();
|
poperror();
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
screenaperture(int size, int align)
|
screenaperture(VGAscr *scr, int size, int align)
|
||||||
{
|
{
|
||||||
VGAscr *scr;
|
|
||||||
uvlong pa;
|
uvlong pa;
|
||||||
|
|
||||||
scr = &vgascreen[0];
|
if(size == 0)
|
||||||
|
|
||||||
if(scr->paddr) /* set up during enable */
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if(size == 0)
|
if(scr->paddr) /* set up during enable */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if(scr->dev && scr->dev->linear){
|
if(scr->dev && scr->dev->linear){
|
||||||
|
@ -152,19 +230,61 @@ flushmemscreen(Rectangle r)
|
||||||
{
|
{
|
||||||
VGAscr *scr;
|
VGAscr *scr;
|
||||||
uchar *sp, *disp, *sdisp, *edisp;
|
uchar *sp, *disp, *sdisp, *edisp;
|
||||||
int y, len, incs, off, page;
|
int x, y, len, incs, off, page;
|
||||||
|
|
||||||
scr = &vgascreen[0];
|
scr = &vgascreen[0];
|
||||||
if(scr->gscreen == nil || scr->useflush == 0)
|
if(scr->gscreen == nil || scr->useflush == 0)
|
||||||
return;
|
return;
|
||||||
if(rectclip(&r, scr->gscreen->r) == 0)
|
if(rectclip(&r, scr->gscreen->clipr) == 0)
|
||||||
return;
|
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){
|
if(scr->dev && scr->dev->flush){
|
||||||
scr->dev->flush(scr, r);
|
scr->dev->flush(scr, r);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
disp = scr->vaddr;
|
disp = scr->vaddr;
|
||||||
incs = scr->gscreen->width*sizeof(ulong);
|
incs = scr->pitch;
|
||||||
off = (r.min.x*scr->gscreen->depth) / 8;
|
off = (r.min.x*scr->gscreen->depth) / 8;
|
||||||
len = (r.max.x*scr->gscreen->depth + 7) / 8;
|
len = (r.max.x*scr->gscreen->depth + 7) / 8;
|
||||||
len -= off;
|
len -= off;
|
||||||
|
@ -299,16 +419,48 @@ setcolor(ulong p, ulong r, ulong g, ulong b)
|
||||||
return setpalette(p, r, g, 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
|
void
|
||||||
cursoron(void)
|
cursoron(void)
|
||||||
{
|
{
|
||||||
VGAscr *scr;
|
VGAscr *scr;
|
||||||
VGAcur *cur;
|
VGAcur *cur;
|
||||||
|
Point p;
|
||||||
|
|
||||||
scr = &vgascreen[0];
|
scr = &vgascreen[0];
|
||||||
cur = scr->cur;
|
cur = scr->cur;
|
||||||
if(cur && cur->move)
|
if(cur && cur->move){
|
||||||
cur->move(scr, mousexy());
|
p = mousexy();
|
||||||
|
if(scr->tilt && cur != &vgasoftcur)
|
||||||
|
p = tiltpt(-scr->tilt, scr->gscreen->clipr.max, p);
|
||||||
|
cur->move(scr, p);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -324,13 +476,18 @@ setcursor(Cursor* curs)
|
||||||
|
|
||||||
scr = &vgascreen[0];
|
scr = &vgascreen[0];
|
||||||
cur = scr->cur;
|
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);
|
cur->load(scr, curs);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int hwaccel = 0;
|
int hwaccel = 0;
|
||||||
int hwblank = 0;
|
int hwblank = 0;
|
||||||
int panning = 0;
|
|
||||||
|
|
||||||
int
|
int
|
||||||
hwdraw(Memdrawparam *par)
|
hwdraw(Memdrawparam *par)
|
||||||
|
@ -358,7 +515,7 @@ hwdraw(Memdrawparam *par)
|
||||||
if(mask && mask->data->bdata == scrd->bdata)
|
if(mask && mask->data->bdata == scrd->bdata)
|
||||||
swcursoravoid(par->mr);
|
swcursoravoid(par->mr);
|
||||||
}
|
}
|
||||||
if(!hwaccel || scr->softscreen)
|
if(!hwaccel || scr->softscreen || scr->tilt)
|
||||||
return 0;
|
return 0;
|
||||||
if(dst->data->bdata != scrd->bdata || src == nil || mask == nil)
|
if(dst->data->bdata != scrd->bdata || src == nil || mask == nil)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -396,14 +553,14 @@ blankscreen(int blank)
|
||||||
{
|
{
|
||||||
VGAscr *scr;
|
VGAscr *scr;
|
||||||
|
|
||||||
|
if(!hwblank)
|
||||||
|
return;
|
||||||
scr = &vgascreen[0];
|
scr = &vgascreen[0];
|
||||||
if(hwblank){
|
|
||||||
if(scr->blank)
|
if(scr->blank)
|
||||||
scr->blank(scr, blank);
|
scr->blank(scr, blank);
|
||||||
else
|
else
|
||||||
vgablank(scr, blank);
|
vgablank(scr, blank);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static char*
|
static char*
|
||||||
vgalinearaddr0(VGAscr *scr, uvlong paddr, int size)
|
vgalinearaddr0(VGAscr *scr, uvlong paddr, int size)
|
||||||
|
@ -461,6 +618,8 @@ vgalinearpci0(VGAscr *scr)
|
||||||
Pcidev *p;
|
Pcidev *p;
|
||||||
|
|
||||||
p = scr->pci;
|
p = scr->pci;
|
||||||
|
if(p == nil)
|
||||||
|
return "no pci card";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Scan for largest memory region on card.
|
* Scan for largest memory region on card.
|
||||||
|
@ -575,7 +734,7 @@ void
|
||||||
bootscreeninit(void)
|
bootscreeninit(void)
|
||||||
{
|
{
|
||||||
VGAscr *scr;
|
VGAscr *scr;
|
||||||
int x, y, z;
|
int x, y, z, tilt;
|
||||||
uvlong pa;
|
uvlong pa;
|
||||||
ulong chan, sz;
|
ulong chan, sz;
|
||||||
char *s, *p, *err;
|
char *s, *p, *err;
|
||||||
|
@ -608,34 +767,36 @@ bootscreeninit(void)
|
||||||
pa = strtoull(p+1, &s, 0);
|
pa = strtoull(p+1, &s, 0);
|
||||||
if(pa == 0)
|
if(pa == 0)
|
||||||
return;
|
return;
|
||||||
if(*s++ == ' ')
|
if(*s == ' ')
|
||||||
sz = strtoul(s, nil, 0);
|
sz = strtoul(s+1, nil, 0);
|
||||||
if(sz < x * y * (z+7)/8)
|
if(sz < x * y * (z+7)/8)
|
||||||
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 = &vgascreen[0];
|
||||||
|
scr->dev = nil;
|
||||||
|
scr->softscreen = 1;
|
||||||
|
|
||||||
if((err = bootmapfb(scr, pa, sz)) != nil){
|
if((err = bootmapfb(scr, pa, sz)) != nil){
|
||||||
print("bootmapfb: %s\n", err);
|
print("bootmapfb: %s\n", err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(memimageinit() < 0)
|
if(memimageinit() < 0){
|
||||||
|
print("memimageinit failed\n");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
gscreen = allocmemimage(Rect(0,0,x,y), chan);
|
if((err = setscreensize0(scr, x, y, z, chan, tilt)) != nil){
|
||||||
if(gscreen == nil)
|
print("setscreensize0: %s\n", err);
|
||||||
return;
|
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);
|
vgaimageinit(chan);
|
||||||
vgascreenwin(scr);
|
vgascreenwin(scr);
|
||||||
|
@ -659,10 +820,11 @@ bootscreenconf(VGAscr *scr)
|
||||||
char conf[100], chan[30];
|
char conf[100], chan[30];
|
||||||
|
|
||||||
conf[0] = '\0';
|
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",
|
snprint(conf, sizeof(conf), "%dx%dx%d %s 0x%.8llux %d\n",
|
||||||
scr->gscreen->r.max.x, scr->gscreen->r.max.y,
|
scr->width, scr->height, scr->gscreen->depth, chantostr(chan, scr->gscreen->chan),
|
||||||
scr->gscreen->depth, chantostr(chan, scr->gscreen->chan),
|
|
||||||
scr->paddr, scr->apsize);
|
scr->paddr, scr->apsize);
|
||||||
|
ksetenv("tiltscreen", tiltstr[scr->tilt], 1);
|
||||||
|
}
|
||||||
ksetenv("*bootscreen", conf, 1);
|
ksetenv("*bootscreen", conf, 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,8 +75,6 @@ struct VGAcur {
|
||||||
void (*disable)(VGAscr*);
|
void (*disable)(VGAscr*);
|
||||||
void (*load)(VGAscr*, Cursor*);
|
void (*load)(VGAscr*, Cursor*);
|
||||||
int (*move)(VGAscr*, Point);
|
int (*move)(VGAscr*, Point);
|
||||||
|
|
||||||
int doespanning;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -96,6 +94,12 @@ struct VGAscr {
|
||||||
void* vaddr;
|
void* vaddr;
|
||||||
int apsize;
|
int apsize;
|
||||||
|
|
||||||
|
int bpp;
|
||||||
|
int pitch;
|
||||||
|
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
|
||||||
ulong io; /* device specific registers */
|
ulong io; /* device specific registers */
|
||||||
ulong *mmio;
|
ulong *mmio;
|
||||||
|
|
||||||
|
@ -110,8 +114,8 @@ struct VGAscr {
|
||||||
int (*scroll)(VGAscr*, Rectangle, Rectangle);
|
int (*scroll)(VGAscr*, Rectangle, Rectangle);
|
||||||
void (*blank)(VGAscr*, int);
|
void (*blank)(VGAscr*, int);
|
||||||
ulong id; /* internal identifier for driver use */
|
ulong id; /* internal identifier for driver use */
|
||||||
int overlayinit;
|
|
||||||
int softscreen;
|
int softscreen;
|
||||||
|
int tilt;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern VGAscr vgascreen[];
|
extern VGAscr vgascreen[];
|
||||||
|
@ -128,16 +132,17 @@ extern void mouseredraw(void);
|
||||||
/* screen.c */
|
/* screen.c */
|
||||||
extern int hwaccel; /* use hw acceleration */
|
extern int hwaccel; /* use hw acceleration */
|
||||||
extern int hwblank; /* use hw blanking */
|
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 void addvgaseg(char*, uvlong, ulong);
|
||||||
extern Memdata* attachscreen(Rectangle*, ulong*, int*, int*, int*);
|
extern Memdata* attachscreen(Rectangle*, ulong*, int*, int*, int*);
|
||||||
extern void flushmemscreen(Rectangle);
|
extern void flushmemscreen(Rectangle);
|
||||||
extern void cursoron(void);
|
extern void cursoron(void);
|
||||||
extern void cursoroff(void);
|
extern void cursoroff(void);
|
||||||
extern void setcursor(Cursor*);
|
extern void setcursor(Cursor*);
|
||||||
extern int screensize(int, int, int, ulong);
|
extern int screenaperture(VGAscr*, int, int);
|
||||||
extern int screenaperture(int, int);
|
|
||||||
extern Rectangle physgscreenr; /* actual monitor size */
|
|
||||||
extern void blankscreen(int);
|
extern void blankscreen(int);
|
||||||
extern char* rgbmask2chan(char *buf, int depth, u32int rm, u32int gm, u32int bm);
|
extern char* rgbmask2chan(char *buf, int depth, u32int rm, u32int gm, u32int bm);
|
||||||
extern void bootscreeninit(void);
|
extern void bootscreeninit(void);
|
||||||
|
|
|
@ -34,7 +34,7 @@ ct65545enable(VGAscr* scr)
|
||||||
* Find a place for the cursor data in display memory.
|
* Find a place for the cursor data in display memory.
|
||||||
* Must be on a 1024-byte boundary.
|
* 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);
|
outl(0xB3D0, storage);
|
||||||
scr->storage = storage;
|
scr->storage = storage;
|
||||||
|
|
||||||
|
|
|
@ -170,7 +170,7 @@ cyber938xcurenable(VGAscr* scr)
|
||||||
/*
|
/*
|
||||||
* Find a place for the cursor data in display memory.
|
* 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, 0x44, storage & 0xFF);
|
||||||
vgaxo(Crtx, 0x45, (storage>>8) & 0xFF);
|
vgaxo(Crtx, 0x45, (storage>>8) & 0xFF);
|
||||||
storage *= 1024;
|
storage *= 1024;
|
||||||
|
|
|
@ -79,7 +79,7 @@ et4000enable(VGAscr *scr)
|
||||||
* 1024-byte boundary so that there's no danger of it
|
* 1024-byte boundary so that there's no danger of it
|
||||||
* crossing a page.
|
* 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;
|
scr->storage *= 1024/4;
|
||||||
outb(0x217A, 0xE8);
|
outb(0x217A, 0xE8);
|
||||||
outb(0x217B, scr->storage & 0xFF);
|
outb(0x217B, scr->storage & 0xFF);
|
||||||
|
|
|
@ -80,12 +80,6 @@ char Enotconfigured[] = "device not configured";
|
||||||
#define HOST_MEM_MODE_V 0xC0000000
|
#define HOST_MEM_MODE_V 0xC0000000
|
||||||
#define HOST_MEM_MODE_NORMAL HOST_YUV_APERTURE_UPPER
|
#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 {
|
enum {
|
||||||
VTGTB1S1 = 0x01, /* Asic description for VTB1S1 and GTB1S1. */
|
VTGTB1S1 = 0x01, /* Asic description for VTB1S1 and GTB1S1. */
|
||||||
VT4GTIIC = 0x3A, /* asic descr for VT4 and RAGE IIC */
|
VT4GTIIC = 0x3A, /* asic descr for VT4 and RAGE IIC */
|
||||||
|
@ -117,7 +111,6 @@ struct Mach64types {
|
||||||
static ulong mach64refclock;
|
static ulong mach64refclock;
|
||||||
static Mach64types *mach64type;
|
static Mach64types *mach64type;
|
||||||
static int mach64revb; /* Revision B or greater? */
|
static int mach64revb; /* Revision B or greater? */
|
||||||
static ulong mach64overlay; /* Overlay buffer */
|
|
||||||
|
|
||||||
static Mach64types mach64s[] = {
|
static Mach64types mach64s[] = {
|
||||||
('C'<<8)|'T', 0, 1350000, /*?*/ 0, /* 4354: CT */
|
('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;
|
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
|
static int
|
||||||
mach64xxcurmove(VGAscr* scr, Point p)
|
mach64xxcurmove(VGAscr* scr, Point p)
|
||||||
{
|
{
|
||||||
int x, xo, y, yo;
|
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,
|
* 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.
|
* Find a place for the cursor data in display memory.
|
||||||
* Must be 64-bit aligned.
|
* 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);
|
iow32(scr, CurOffset, storage);
|
||||||
scr->storage = storage*8;
|
scr->storage = storage*8;
|
||||||
|
|
||||||
|
@ -643,64 +577,23 @@ resetengine(VGAscr *scr)
|
||||||
iow32(scr, BusCntl, ior32(scr, BusCntl)|0x00A00000);
|
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
|
static void
|
||||||
initengine(VGAscr *scr)
|
initengine(VGAscr *scr)
|
||||||
{
|
{
|
||||||
ulong pitch;
|
|
||||||
uchar *bios;
|
uchar *bios;
|
||||||
ushort table;
|
ushort table;
|
||||||
|
|
||||||
pitch = Dx(scr->gscreen->r)/8;
|
|
||||||
if(scr->gscreen->depth == 24)
|
|
||||||
pitch *= 3;
|
|
||||||
|
|
||||||
resetengine(scr);
|
resetengine(scr);
|
||||||
waitforfifo(scr, 14);
|
waitforfifo(scr, 14);
|
||||||
iow32(scr, ContextMask, ~0);
|
iow32(scr, ContextMask, ~0);
|
||||||
iow32(scr, DstOffPitch, pitch<<22);
|
iow32(scr, DstOffPitch, scr->pitch<<22);
|
||||||
iow32(scr, DstYX, 0);
|
iow32(scr, DstYX, 0);
|
||||||
iow32(scr, DstHeight, 0);
|
iow32(scr, DstHeight, 0);
|
||||||
iow32(scr, DstBresErr, 0);
|
iow32(scr, DstBresErr, 0);
|
||||||
iow32(scr, DstBresInc, 0);
|
iow32(scr, DstBresInc, 0);
|
||||||
iow32(scr, DstBresDec, 0);
|
iow32(scr, DstBresDec, 0);
|
||||||
iow32(scr, DstCntl, 0x23);
|
iow32(scr, DstCntl, 0x23);
|
||||||
iow32(scr, SrcOffPitch, pitch<<22);
|
iow32(scr, SrcOffPitch, scr->pitch<<22);
|
||||||
iow32(scr, SrcYX, 0);
|
iow32(scr, SrcYX, 0);
|
||||||
iow32(scr, SrcHeight1Width1, 1);
|
iow32(scr, SrcHeight1Width1, 1);
|
||||||
iow32(scr, SrcYXstart, 0);
|
iow32(scr, SrcYXstart, 0);
|
||||||
|
@ -793,19 +686,16 @@ initengine(VGAscr *scr)
|
||||||
static int
|
static int
|
||||||
mach64hwfill(VGAscr *scr, Rectangle r, ulong sval)
|
mach64hwfill(VGAscr *scr, Rectangle r, ulong sval)
|
||||||
{
|
{
|
||||||
ulong pitch;
|
|
||||||
ulong ctl;
|
ulong ctl;
|
||||||
|
|
||||||
/* shouldn't happen */
|
/* shouldn't happen */
|
||||||
if(scr->io == 0x2EC || scr->io == 0x1C8 || scr->io == 0)
|
if(scr->io == 0x2EC || scr->io == 0x1C8 || scr->io == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
pitch = Dx(scr->gscreen->r)/8;
|
|
||||||
ctl = 1|2; /* left-to-right, top-to-bottom */
|
ctl = 1|2; /* left-to-right, top-to-bottom */
|
||||||
if(scr->gscreen->depth == 24){
|
if(scr->gscreen->depth == 24){
|
||||||
r.min.x *= 3;
|
r.min.x *= 3;
|
||||||
r.max.x *= 3;
|
r.max.x *= 3;
|
||||||
pitch *= 3;
|
|
||||||
ctl |= (1<<7)|(((r.min.x/4)%6)<<8);
|
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, ClrCmpCntl, 0x00000000);
|
||||||
iow32(scr, ScLeftRight, 0x1FFF0000);
|
iow32(scr, ScLeftRight, 0x1FFF0000);
|
||||||
iow32(scr, ScTopBottom, 0x1FFF0000);
|
iow32(scr, ScTopBottom, 0x1FFF0000);
|
||||||
iow32(scr, DstOffPitch, pitch<<22);
|
iow32(scr, DstOffPitch, scr->pitch<<22);
|
||||||
iow32(scr, DstCntl, ctl);
|
iow32(scr, DstCntl, ctl);
|
||||||
iow32(scr, DstYX, (r.min.x<<16)|r.min.y);
|
iow32(scr, DstYX, (r.min.x<<16)|r.min.y);
|
||||||
iow32(scr, DstHeightWidth, (Dx(r)<<16)|Dy(r));
|
iow32(scr, DstHeightWidth, (Dx(r)<<16)|Dy(r));
|
||||||
|
@ -829,17 +719,14 @@ mach64hwfill(VGAscr *scr, Rectangle r, ulong sval)
|
||||||
static int
|
static int
|
||||||
mach64hwscroll(VGAscr *scr, Rectangle r, Rectangle sr)
|
mach64hwscroll(VGAscr *scr, Rectangle r, Rectangle sr)
|
||||||
{
|
{
|
||||||
ulong pitch;
|
|
||||||
Point dp, sp;
|
Point dp, sp;
|
||||||
ulong ctl;
|
ulong ctl;
|
||||||
int dx, dy;
|
int dx, dy;
|
||||||
|
|
||||||
dx = Dx(r);
|
dx = Dx(r);
|
||||||
dy = Dy(r);
|
dy = Dy(r);
|
||||||
pitch = Dx(scr->gscreen->r)/8;
|
|
||||||
if(scr->gscreen->depth == 24){
|
if(scr->gscreen->depth == 24){
|
||||||
dx *= 3;
|
dx *= 3;
|
||||||
pitch *= 3;
|
|
||||||
r.min.x *= 3;
|
r.min.x *= 3;
|
||||||
sr.min.x *= 3;
|
sr.min.x *= 3;
|
||||||
}
|
}
|
||||||
|
@ -875,11 +762,11 @@ mach64hwscroll(VGAscr *scr, Rectangle r, Rectangle sr)
|
||||||
iow32(scr, ClrCmpCntl, 0x00000000);
|
iow32(scr, ClrCmpCntl, 0x00000000);
|
||||||
|
|
||||||
waitforfifo(scr, 8);
|
waitforfifo(scr, 8);
|
||||||
iow32(scr, SrcOffPitch, pitch<<22);
|
iow32(scr, SrcOffPitch, scr->pitch<<22);
|
||||||
iow32(scr, SrcCntl, 0x00000000);
|
iow32(scr, SrcCntl, 0x00000000);
|
||||||
iow32(scr, SrcYX, (sp.x<<16)|sp.y);
|
iow32(scr, SrcYX, (sp.x<<16)|sp.y);
|
||||||
iow32(scr, SrcWidth1, dx);
|
iow32(scr, SrcWidth1, dx);
|
||||||
iow32(scr, DstOffPitch, pitch<<22);
|
iow32(scr, DstOffPitch, scr->pitch<<22);
|
||||||
iow32(scr, DstCntl, ctl);
|
iow32(scr, DstCntl, ctl);
|
||||||
|
|
||||||
iow32(scr, DstYX, (dp.x<<16)|dp.y);
|
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 = {
|
VGAdev vgamach64xxdev = {
|
||||||
"mach64xx",
|
"mach64xx",
|
||||||
|
|
||||||
|
@ -1181,9 +852,6 @@ VGAdev vgamach64xxdev = {
|
||||||
0, /* page */
|
0, /* page */
|
||||||
mach64xxlinear, /* linear */
|
mach64xxlinear, /* linear */
|
||||||
mach64xxdrawinit, /* drawinit */
|
mach64xxdrawinit, /* drawinit */
|
||||||
0,
|
|
||||||
mach64xxovlctl, /* overlay control */
|
|
||||||
mach64xxovlwrite, /* write the overlay */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
VGAcur vgamach64xxcur = {
|
VGAcur vgamach64xxcur = {
|
||||||
|
@ -1193,7 +861,5 @@ VGAcur vgamach64xxcur = {
|
||||||
mach64xxcurdisable, /* disable */
|
mach64xxcurdisable, /* disable */
|
||||||
mach64xxcurload, /* load */
|
mach64xxcurload, /* load */
|
||||||
mach64xxcurmove, /* move */
|
mach64xxcurmove, /* move */
|
||||||
|
|
||||||
1 /* doespanning */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -405,7 +405,6 @@ static int
|
||||||
mga4xxscroll(VGAscr *scr, Rectangle dr, Rectangle sr)
|
mga4xxscroll(VGAscr *scr, Rectangle dr, Rectangle sr)
|
||||||
{
|
{
|
||||||
uchar * mga;
|
uchar * mga;
|
||||||
int pitch;
|
|
||||||
int width, height;
|
int width, height;
|
||||||
ulong start, end, sgn;
|
ulong start, end, sgn;
|
||||||
Point sp, dp;
|
Point sp, dp;
|
||||||
|
@ -421,7 +420,6 @@ mga4xxscroll(VGAscr *scr, Rectangle dr, Rectangle sr)
|
||||||
if(eqpt(sp, dp))
|
if(eqpt(sp, dp))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
pitch = Dx(scr->gscreen->r);
|
|
||||||
width = Dx(sr);
|
width = Dx(sr);
|
||||||
height = Dy(sr);
|
height = Dy(sr);
|
||||||
sgn = 0;
|
sgn = 0;
|
||||||
|
@ -433,7 +431,7 @@ mga4xxscroll(VGAscr *scr, Rectangle dr, Rectangle sr)
|
||||||
}
|
}
|
||||||
|
|
||||||
width--;
|
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){
|
if(dp.x > sp.x && dp.x < sp.x + width){
|
||||||
start += width;
|
start += width;
|
||||||
|
@ -445,7 +443,7 @@ mga4xxscroll(VGAscr *scr, Rectangle dr, Rectangle sr)
|
||||||
mga_fifo(mga, 8);
|
mga_fifo(mga, 8);
|
||||||
mgawrite32(mga, DWGCTL, 0);
|
mgawrite32(mga, DWGCTL, 0);
|
||||||
mgawrite32(mga, SGN, sgn);
|
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, AR0, end);
|
||||||
mgawrite32(mga, AR3, start);
|
mgawrite32(mga, AR3, start);
|
||||||
mgawrite32(mga, FXBNDRY, ((dp.x + width) << 16) | dp.x);
|
mgawrite32(mga, FXBNDRY, ((dp.x + width) << 16) | dp.x);
|
||||||
|
|
|
@ -376,8 +376,8 @@ neomagichwfill(VGAscr *scr, Rectangle r, ulong sval)
|
||||||
| NEO_BC3_SKIP_MAPPING
|
| NEO_BC3_SKIP_MAPPING
|
||||||
| GXcopy;
|
| GXcopy;
|
||||||
mmio[DstStartOff] = scr->paddr
|
mmio[DstStartOff] = scr->paddr
|
||||||
+ r.min.y*scr->gscreen->width*sizeof(ulong)
|
+ r.min.y*scr->pitch
|
||||||
+ r.min.x*scr->gscreen->depth/BI2BY;
|
+ r.min.x*scr->bpp;
|
||||||
mmio[XYExt] = (Dy(r) << 16) | (Dx(r) & 0xffff);
|
mmio[XYExt] = (Dy(r) << 16) | (Dx(r) & 0xffff);
|
||||||
waitforidle(scr);
|
waitforidle(scr);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -387,13 +387,9 @@ static int
|
||||||
neomagichwscroll(VGAscr *scr, Rectangle r, Rectangle sr)
|
neomagichwscroll(VGAscr *scr, Rectangle r, Rectangle sr)
|
||||||
{
|
{
|
||||||
ulong *mmio;
|
ulong *mmio;
|
||||||
int pitch, pixel;
|
|
||||||
|
|
||||||
mmio = scr->mmio;
|
mmio = scr->mmio;
|
||||||
|
|
||||||
pitch = scr->gscreen->width*sizeof(ulong);
|
|
||||||
pixel = scr->gscreen->depth/BI2BY;
|
|
||||||
|
|
||||||
waitforfifo(scr, 4);
|
waitforfifo(scr, 4);
|
||||||
if (r.min.y < sr.min.y || (r.min.y == sr.min.y && r.min.x < sr.min.x)) {
|
if (r.min.y < sr.min.y || (r.min.y == sr.min.y && r.min.x < sr.min.x)) {
|
||||||
/* start from upper-left */
|
/* start from upper-left */
|
||||||
|
@ -402,9 +398,9 @@ neomagichwscroll(VGAscr *scr, Rectangle r, Rectangle sr)
|
||||||
| NEO_BC3_SKIP_MAPPING
|
| NEO_BC3_SKIP_MAPPING
|
||||||
| GXcopy;
|
| GXcopy;
|
||||||
mmio[SrcStartOff] = scr->paddr
|
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
|
mmio[DstStartOff] = scr->paddr
|
||||||
+ r.min.y*pitch + r.min.x*pixel;
|
+ r.min.y*scr->pitch + r.min.x*scr->bpp;
|
||||||
} else {
|
} else {
|
||||||
/* start from lower-right */
|
/* start from lower-right */
|
||||||
mmio[BltCntl] = neomagicbltflags
|
mmio[BltCntl] = neomagicbltflags
|
||||||
|
@ -415,9 +411,9 @@ neomagichwscroll(VGAscr *scr, Rectangle r, Rectangle sr)
|
||||||
| NEO_BC3_SKIP_MAPPING
|
| NEO_BC3_SKIP_MAPPING
|
||||||
| GXcopy;
|
| GXcopy;
|
||||||
mmio[SrcStartOff] = scr->paddr
|
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
|
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);
|
mmio[XYExt] = (Dy(r) << 16) | (Dx(r) & 0xffff);
|
||||||
waitforidle(scr);
|
waitforidle(scr);
|
||||||
|
@ -428,12 +424,10 @@ static void
|
||||||
neomagicdrawinit(VGAscr *scr)
|
neomagicdrawinit(VGAscr *scr)
|
||||||
{
|
{
|
||||||
ulong *mmio;
|
ulong *mmio;
|
||||||
uint bltmode, pitch;
|
uint bltmode;
|
||||||
|
|
||||||
mmio = scr->mmio;
|
mmio = scr->mmio;
|
||||||
|
|
||||||
pitch = scr->gscreen->width*sizeof(ulong);
|
|
||||||
|
|
||||||
neomagicbltflags = bltmode = 0;
|
neomagicbltflags = bltmode = 0;
|
||||||
|
|
||||||
switch(scr->gscreen->depth) {
|
switch(scr->gscreen->depth) {
|
||||||
|
@ -450,7 +444,7 @@ neomagicdrawinit(VGAscr *scr)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(Dx(scr->gscreen->r)) {
|
switch(scr->width) {
|
||||||
case 320:
|
case 320:
|
||||||
bltmode |= NEO_MODE1_X_320;
|
bltmode |= NEO_MODE1_X_320;
|
||||||
neomagicbltflags |= NEO_BC1_X_320;
|
neomagicbltflags |= NEO_BC1_X_320;
|
||||||
|
@ -486,7 +480,7 @@ neomagicdrawinit(VGAscr *scr)
|
||||||
|
|
||||||
waitforidle(scr);
|
waitforidle(scr);
|
||||||
mmio[BltStat] = bltmode << 16;
|
mmio[BltStat] = bltmode << 16;
|
||||||
mmio[Pitch] = (pitch << 16) | (pitch & 0xffff);
|
mmio[Pitch] = (scr->pitch << 16) | (scr->pitch & 0xffff);
|
||||||
|
|
||||||
scr->fill = neomagichwfill;
|
scr->fill = neomagichwfill;
|
||||||
scr->scroll = neomagichwscroll;
|
scr->scroll = neomagichwscroll;
|
||||||
|
|
|
@ -343,13 +343,11 @@ static int
|
||||||
nvresetgraphics(VGAscr *scr)
|
nvresetgraphics(VGAscr *scr)
|
||||||
{
|
{
|
||||||
ulong surfaceFormat, patternFormat, rectFormat, lineFormat;
|
ulong surfaceFormat, patternFormat, rectFormat, lineFormat;
|
||||||
int pitch, i;
|
int i;
|
||||||
|
|
||||||
if(scr->paddr == 0)
|
if(scr->paddr == 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
pitch = scr->gscreen->width*sizeof(ulong);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* DMA is at the end of the virtual window,
|
* DMA is at the end of the virtual window,
|
||||||
* but we might have cut it short when mapping it.
|
* but we might have cut it short when mapping it.
|
||||||
|
@ -416,7 +414,7 @@ nvresetgraphics(VGAscr *scr)
|
||||||
|
|
||||||
nvdmastart(scr, SURFACE_FORMAT, 4);
|
nvdmastart(scr, SURFACE_FORMAT, 4);
|
||||||
nvdmanext(surfaceFormat);
|
nvdmanext(surfaceFormat);
|
||||||
nvdmanext(pitch | (pitch << 16));
|
nvdmanext(scr->pitch | (scr->pitch << 16));
|
||||||
nvdmanext(0);
|
nvdmanext(0);
|
||||||
nvdmanext(0);
|
nvdmanext(0);
|
||||||
|
|
||||||
|
|
|
@ -350,7 +350,7 @@ radeonscroll(VGAscr*scr, Rectangle dst, Rectangle src)
|
||||||
static void
|
static void
|
||||||
radeondrawinit(VGAscr*scr)
|
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)
|
if (scr->mmio == 0)
|
||||||
return;
|
return;
|
||||||
|
@ -359,19 +359,15 @@ radeondrawinit(VGAscr*scr)
|
||||||
case 6:
|
case 6:
|
||||||
case 8:
|
case 8:
|
||||||
dtype = 2;
|
dtype = 2;
|
||||||
bpp = 1;
|
|
||||||
break;
|
break;
|
||||||
case 15:
|
case 15:
|
||||||
dtype = 3;
|
dtype = 3;
|
||||||
bpp = 2;
|
|
||||||
break;
|
break;
|
||||||
case 16:
|
case 16:
|
||||||
dtype = 4;
|
dtype = 4;
|
||||||
bpp = 2;
|
|
||||||
break;
|
break;
|
||||||
case 32:
|
case 32:
|
||||||
dtype = 6;
|
dtype = 6;
|
||||||
bpp = 4;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
|
@ -413,11 +409,10 @@ radeondrawinit(VGAscr*scr)
|
||||||
radeonwaitfifo(scr, 1);
|
radeonwaitfifo(scr, 1);
|
||||||
OUTREG(scr->mmio, RB2D_DSTCACHE_MODE, 0);
|
OUTREG(scr->mmio, RB2D_DSTCACHE_MODE, 0);
|
||||||
|
|
||||||
pitch = Dx(scr->gscreen->r) * bpp;
|
|
||||||
radeonwaitfifo(scr, 4);
|
radeonwaitfifo(scr, 4);
|
||||||
OUTREG(scr->mmio, DEFAULT_PITCH, pitch);
|
OUTREG(scr->mmio, DEFAULT_PITCH, scr->pitch);
|
||||||
OUTREG(scr->mmio, DST_PITCH, pitch);
|
OUTREG(scr->mmio, DST_PITCH, scr->pitch);
|
||||||
OUTREG(scr->mmio, SRC_PITCH, pitch);
|
OUTREG(scr->mmio, SRC_PITCH, scr->pitch);
|
||||||
OUTREG(scr->mmio, DST_PITCH_OFFSET_C, 0);
|
OUTREG(scr->mmio, DST_PITCH_OFFSET_C, 0);
|
||||||
|
|
||||||
radeonwaitfifo(scr, 3);
|
radeonwaitfifo(scr, 3);
|
||||||
|
@ -501,5 +496,4 @@ VGAcur vgaradeoncur = {
|
||||||
radeoncurdisable,
|
radeoncurdisable,
|
||||||
radeoncurload,
|
radeoncurload,
|
||||||
radeoncurmove,
|
radeoncurmove,
|
||||||
0 /* doespanning */
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -309,7 +309,7 @@ s3enable(VGAscr* scr)
|
||||||
* Find a place for the cursor data in display memory.
|
* Find a place for the cursor data in display memory.
|
||||||
* Must be on a 1024-byte boundary.
|
* 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, 0x4C, storage>>8);
|
||||||
vgaxo(Crtx, 0x4D, storage & 0xFF);
|
vgaxo(Crtx, 0x4D, storage & 0xFF);
|
||||||
storage *= 1024;
|
storage *= 1024;
|
||||||
|
@ -420,14 +420,12 @@ hwscroll(VGAscr *scr, Rectangle r, Rectangle sr)
|
||||||
{
|
{
|
||||||
enum { Bitbltop = 0xCC }; /* copy source */
|
enum { Bitbltop = 0xCC }; /* copy source */
|
||||||
ulong *mmio;
|
ulong *mmio;
|
||||||
ulong cmd, stride;
|
ulong cmd;
|
||||||
Point dp, sp;
|
Point dp, sp;
|
||||||
int did, d;
|
int did;
|
||||||
|
|
||||||
d = scr->gscreen->depth;
|
did = (scr->gscreen->depth-8)/8;
|
||||||
did = (d-8)/8;
|
|
||||||
cmd = 0x00000020|(Bitbltop<<17)|(did<<2);
|
cmd = 0x00000020|(Bitbltop<<17)|(did<<2);
|
||||||
stride = Dx(scr->gscreen->r)*d/8;
|
|
||||||
|
|
||||||
if(r.min.x <= sr.min.x){
|
if(r.min.x <= sr.min.x){
|
||||||
cmd |= 1<<25;
|
cmd |= 1<<25;
|
||||||
|
@ -452,7 +450,7 @@ hwscroll(VGAscr *scr, Rectangle r, Rectangle sr)
|
||||||
waitforfifo(scr, 7);
|
waitforfifo(scr, 7);
|
||||||
mmio[SrcBase] = scr->paddr;
|
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[WidthHeight] = ((Dx(r)-1)<<16)|Dy(r);
|
mmio[WidthHeight] = ((Dx(r)-1)<<16)|Dy(r);
|
||||||
mmio[SrcXY] = (sp.x<<16)|sp.y;
|
mmio[SrcXY] = (sp.x<<16)|sp.y;
|
||||||
mmio[DestXY] = (dp.x<<16)|dp.y;
|
mmio[DestXY] = (dp.x<<16)|dp.y;
|
||||||
|
@ -466,20 +464,18 @@ hwfill(VGAscr *scr, Rectangle r, ulong sval)
|
||||||
{
|
{
|
||||||
enum { Bitbltop = 0xCC }; /* copy source */
|
enum { Bitbltop = 0xCC }; /* copy source */
|
||||||
ulong *mmio;
|
ulong *mmio;
|
||||||
ulong cmd, stride;
|
ulong cmd;
|
||||||
int did, d;
|
int did;
|
||||||
|
|
||||||
d = scr->gscreen->depth;
|
did = (scr->gscreen->depth-8)/8;
|
||||||
did = (d-8)/8;
|
|
||||||
cmd = 0x16000120|(Bitbltop<<17)|(did<<2);
|
cmd = 0x16000120|(Bitbltop<<17)|(did<<2);
|
||||||
stride = Dx(scr->gscreen->r)*d/8;
|
|
||||||
mmio = scr->mmio;
|
mmio = scr->mmio;
|
||||||
waitforlinearfifo(scr);
|
waitforlinearfifo(scr);
|
||||||
waitforfifo(scr, 8);
|
waitforfifo(scr, 8);
|
||||||
mmio[SrcBase] = scr->paddr;
|
mmio[SrcBase] = scr->paddr;
|
||||||
mmio[DstBase] = scr->paddr;
|
mmio[DstBase] = 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[FgrdData] = sval;
|
||||||
mmio[WidthHeight] = ((Dx(r)-1)<<16)|Dy(r);
|
mmio[WidthHeight] = ((Dx(r)-1)<<16)|Dy(r);
|
||||||
mmio[DestXY] = (r.min.x<<16)|r.min.y;
|
mmio[DestXY] = (r.min.x<<16)|r.min.y;
|
||||||
|
|
|
@ -540,7 +540,7 @@ savageinit(VGAscr *scr)
|
||||||
|
|
||||||
/* set bitmap descriptors */
|
/* set bitmap descriptors */
|
||||||
bd = (scr->gscreen->depth<<DepthShift) |
|
bd = (scr->gscreen->depth<<DepthShift) |
|
||||||
(Dx(scr->gscreen->r)<<StrideShift) | BlockWriteDis
|
(scr->width<<StrideShift) | BlockWriteDis
|
||||||
| BDS64;
|
| BDS64;
|
||||||
|
|
||||||
*(ulong*)(mmio+GBD1) = 0;
|
*(ulong*)(mmio+GBD1) = 0;
|
||||||
|
|
|
@ -459,14 +459,9 @@ t2r4blank(VGAscr *scr, int blank)
|
||||||
static void
|
static void
|
||||||
t2r4drawinit(VGAscr *scr)
|
t2r4drawinit(VGAscr *scr)
|
||||||
{
|
{
|
||||||
ulong pitch;
|
|
||||||
int depth;
|
|
||||||
int fmt;
|
int fmt;
|
||||||
ulong *d;
|
ulong *d;
|
||||||
|
|
||||||
pitch = Dx(scr->gscreen->r);
|
|
||||||
depth = scr->gscreen->depth;
|
|
||||||
|
|
||||||
switch(scr->gscreen->chan){
|
switch(scr->gscreen->chan){
|
||||||
case RGB16:
|
case RGB16:
|
||||||
fmt = 3;
|
fmt = 3;
|
||||||
|
@ -488,8 +483,8 @@ t2r4drawinit(VGAscr *scr)
|
||||||
d[BufCtl] = fmt<<24;
|
d[BufCtl] = fmt<<24;
|
||||||
d[DeSorg] = 0;
|
d[DeSorg] = 0;
|
||||||
d[DeDorg] = 0;
|
d[DeDorg] = 0;
|
||||||
d[DeSptch] = (pitch*depth)/8;
|
d[DeSptch] = scr->pitch;
|
||||||
d[DeDptch] = (pitch*depth)/8;
|
d[DeDptch] = scr->pitch;
|
||||||
d[CmdClp] = 0; /* 2 = inside rectangle */
|
d[CmdClp] = 0; /* 2 = inside rectangle */
|
||||||
d[Mask] = ~0;
|
d[Mask] = ~0;
|
||||||
d[DeKey] = 0;
|
d[DeKey] = 0;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue