vga, vesa: scaling modes

This commit is contained in:
ftrvxmtrx 2014-12-26 15:24:07 +01:00
parent 2ab042f11e
commit 604f00d9bc
4 changed files with 70 additions and 6 deletions

View file

@ -198,6 +198,17 @@ enable or disable the use of DPMS blanking
.B blank .B blank
above). above).
.TP .TP
.BI scaling " mode"
Set the GPU scaling
.I mode
to
.BR off ,
.B full
or
.B aspect
to either disable scaling, scale to full screen, or
to scale while preserving aspect ratio.
.TP
.BI linear " size align" .BI linear " size align"
Use a linear screen aperture of size Use a linear screen aperture of size
.I size .I size

View file

@ -48,6 +48,7 @@ enum {
CMunblank, CMunblank,
CMsoftscreen, CMsoftscreen,
CMpcidev, CMpcidev,
CMscaling,
}; };
static Cmdtab vgactlmsg[] = { static Cmdtab vgactlmsg[] = {
@ -67,6 +68,7 @@ static Cmdtab vgactlmsg[] = {
CMunblank, "unblank", 1, CMunblank, "unblank", 1,
CMsoftscreen, "softscreen", 2, CMsoftscreen, "softscreen", 2,
CMpcidev, "pcidev", 2, CMpcidev, "pcidev", 2,
CMscaling, "scaling", 2,
}; };
static void static void
@ -305,6 +307,19 @@ vgactl(Cmdbuf *cb)
error(Ebadarg); error(Ebadarg);
return; return;
case CMscaling:
if(scr != nil && scr->dev != nil){
if(scr->dev->scaling == nil)
error("scaling not supported");
else if(strcmp(cb->f[1], "aspect") == 0)
scr->dev->scaling(scr, Saspect);
else if(strcmp(cb->f[1], "full") == 0)
scr->dev->scaling(scr, Sfull);
else if(strcmp(cb->f[1], "off") == 0)
scr->dev->scaling(scr, Soff);
}
return;
case CMtype: case CMtype:
for(i = 0; vgadev[i]; i++){ for(i = 0; vgadev[i]; i++){
if(strcmp(cb->f[1], vgadev[i]->name)) if(strcmp(cb->f[1], vgadev[i]->name))

View file

@ -49,6 +49,15 @@ enum {
Pwhite = 0xFF, Pwhite = 0xFF,
}; };
/*
* Scaling modes.
*/
enum {
Soff,
Sfull,
Saspect,
};
#define VGAMEM() 0xA0000 #define VGAMEM() 0xA0000
#define vgai(port) inb(port) #define vgai(port) inb(port)
#define vgao(port, data) outb(port, data) #define vgao(port, data) outb(port, data)
@ -74,6 +83,7 @@ struct VGAdev {
void (*ovlctl)(VGAscr*, Chan*, void*, int); void (*ovlctl)(VGAscr*, Chan*, void*, int);
int (*ovlwrite)(VGAscr*, void*, int, vlong); int (*ovlwrite)(VGAscr*, void*, int, vlong);
void (*flush)(VGAscr*, Rectangle); void (*flush)(VGAscr*, Rectangle);
void (*scaling)(VGAscr*, int);
}; };
struct VGAcur { struct VGAcur {

View file

@ -23,6 +23,7 @@ enum {
Cdisable = 0, Cdisable = 0,
Cenable, Cenable,
Cblank, Cblank,
Cscaling,
RealModeBuf = 0x9000, RealModeBuf = 0x9000,
}; };
@ -32,6 +33,7 @@ static Chan *creg, *cmem;
static QLock vesaq; static QLock vesaq;
static Rendez vesar; static Rendez vesar;
static int vesactl; static int vesactl;
static int scaling;
#define WORD(p) ((p)[0] | ((p)[1]<<8)) #define WORD(p) ((p)[0] | ((p)[1]<<8))
#define LONG(p) ((p)[0] | ((p)[1]<<8) | ((p)[2]<<16) | ((p)[3]<<24)) #define LONG(p) ((p)[0] | ((p)[1]<<8) | ((p)[2]<<16) | ((p)[3]<<24))
@ -183,11 +185,17 @@ vesaproc(void*)
sleep(&vesar, gotctl, &ctl); sleep(&vesar, gotctl, &ctl);
ctl = vesactl; ctl = vesactl;
vbesetup(&u, 0x4f10); if(ctl == Cscaling){
if(ctl == Cblank) vbesetup(&u, 0x4f14);
u.bx = 0x0101; u.bx = 0x102;
else u.cx = scaling;
u.bx = 0x0001; }else{
vbesetup(&u, 0x4f10);
if(ctl == Cblank)
u.bx = 0x0101;
else
u.bx = 0x0001;
}
/* /*
* dont wait forever here. some BIOS get stuck * dont wait forever here. some BIOS get stuck
@ -252,6 +260,21 @@ vesablank(VGAscr *, int blank)
} }
} }
static void
vesascaling(VGAscr *, int mode)
{
if(vesactl != Cdisable){
vesactl = Cscaling;
if(mode == Soff)
scaling = 1;
else if(mode == Saspect)
scaling = 3;
else if(mode == Sfull)
scaling = 0;
wakeup(&vesar);
}
}
static void static void
vesadrawinit(VGAscr *scr) vesadrawinit(VGAscr *scr)
{ {
@ -262,7 +285,12 @@ VGAdev vgavesadev = {
"vesa", "vesa",
vesaenable, vesaenable,
vesadisable, vesadisable,
0, nil,
vesalinear, vesalinear,
vesadrawinit, vesadrawinit,
nil,
nil,
nil,
nil,
vesascaling,
}; };