diff options
author | ftrvxmtrx <ftrvxmtrx@gmail.com> | 2014-12-26 15:40:06 +0100 |
---|---|---|
committer | ftrvxmtrx <ftrvxmtrx@gmail.com> | 2014-12-26 15:40:06 +0100 |
commit | 2cc7c72f8e1b2c0ea98f2184014988f9e2940f52 (patch) | |
tree | ebdb645867044c02301a945dbb829a399b14efda /sys/src | |
parent | 7f5f69ebb5c1fa361d44dc33465be79991dd0d94 (diff) |
vga, vesa: scaling modes
At least on some NVIDIA cards the default scaling mode makes
black borders visible on all sides, even on native resolution.
This patch adds a generic "scaling MODE" command to vgactl
and adds support for it on VESA through NVIDIA VBE OEM extension.
It hasn't been tested on any other video cards, but shouldn't
break anything as the scaling mode is only set on write to vgactl.
Diffstat (limited to 'sys/src')
-rw-r--r-- | sys/src/9/pc/devvga.c | 15 | ||||
-rw-r--r-- | sys/src/9/pc/screen.h | 10 | ||||
-rw-r--r-- | sys/src/9/pc/vgavesa.c | 40 |
3 files changed, 59 insertions, 6 deletions
diff --git a/sys/src/9/pc/devvga.c b/sys/src/9/pc/devvga.c index 3867d36dc..918da32b0 100644 --- a/sys/src/9/pc/devvga.c +++ b/sys/src/9/pc/devvga.c @@ -48,6 +48,7 @@ enum { CMunblank, CMsoftscreen, CMpcidev, + CMscaling, }; static Cmdtab vgactlmsg[] = { @@ -67,6 +68,7 @@ static Cmdtab vgactlmsg[] = { CMunblank, "unblank", 1, CMsoftscreen, "softscreen", 2, CMpcidev, "pcidev", 2, + CMscaling, "scaling", 2, }; static void @@ -305,6 +307,19 @@ vgactl(Cmdbuf *cb) error(Ebadarg); 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: for(i = 0; vgadev[i]; i++){ if(strcmp(cb->f[1], vgadev[i]->name)) diff --git a/sys/src/9/pc/screen.h b/sys/src/9/pc/screen.h index bbe6b2512..7928ca616 100644 --- a/sys/src/9/pc/screen.h +++ b/sys/src/9/pc/screen.h @@ -49,6 +49,15 @@ enum { Pwhite = 0xFF, }; +/* + * Scaling modes. + */ +enum { + Soff, + Sfull, + Saspect, +}; + #define VGAMEM() 0xA0000 #define vgai(port) inb(port) #define vgao(port, data) outb(port, data) @@ -74,6 +83,7 @@ struct VGAdev { void (*ovlctl)(VGAscr*, Chan*, void*, int); int (*ovlwrite)(VGAscr*, void*, int, vlong); void (*flush)(VGAscr*, Rectangle); + void (*scaling)(VGAscr*, int); }; struct VGAcur { diff --git a/sys/src/9/pc/vgavesa.c b/sys/src/9/pc/vgavesa.c index 794533a9d..4eeffbe85 100644 --- a/sys/src/9/pc/vgavesa.c +++ b/sys/src/9/pc/vgavesa.c @@ -23,6 +23,7 @@ enum { Cdisable = 0, Cenable, Cblank, + Cscaling, RealModeBuf = 0x9000, }; @@ -32,6 +33,7 @@ static Chan *creg, *cmem; static QLock vesaq; static Rendez vesar; static int vesactl; +static int scaling; #define WORD(p) ((p)[0] | ((p)[1]<<8)) #define LONG(p) ((p)[0] | ((p)[1]<<8) | ((p)[2]<<16) | ((p)[3]<<24)) @@ -183,11 +185,17 @@ vesaproc(void*) sleep(&vesar, gotctl, &ctl); ctl = vesactl; - vbesetup(&u, 0x4f10); - if(ctl == Cblank) - u.bx = 0x0101; - else - u.bx = 0x0001; + if(ctl == Cscaling){ + vbesetup(&u, 0x4f14); + u.bx = 0x102; + u.cx = scaling; + }else{ + vbesetup(&u, 0x4f10); + if(ctl == Cblank) + u.bx = 0x0101; + else + u.bx = 0x0001; + } /* * dont wait forever here. some BIOS get stuck @@ -253,6 +261,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 vesadrawinit(VGAscr *scr) { scr->blank = vesablank; @@ -262,7 +285,12 @@ VGAdev vgavesadev = { "vesa", vesaenable, vesadisable, - 0, + nil, vesalinear, vesadrawinit, + nil, + nil, + nil, + nil, + vesascaling, }; |