aux/vga: scaling modes for VESA

This commit is contained in:
ftrvxmtrx 2014-12-26 17:01:58 +01:00
parent 04ec990b67
commit 0d5b33a9e8
4 changed files with 69 additions and 12 deletions

View file

@ -15,6 +15,10 @@ vga \- configure a VGA card
.I monitor .I monitor
] ]
[ [
.B -s
.I scaling
]
[
.B -x .B -x
.I file .I file
] ]
@ -81,6 +85,16 @@ is usually set by including it in the
.B plan9.ini .B plan9.ini
file read by the PC boot program. file read by the PC boot program.
.TP .TP
.B -s
set scaling mode to either
.I off
to disable completely (image will be centered),
.I full
to stretch to full screen
or
.I aspect
to stretch while preserving aspect ratio.
.TP
.B -p .B -p
print the current or expected register values at appropriate points depending on print the current or expected register values at appropriate points depending on
other options. other options.

View file

@ -149,7 +149,7 @@ chanstr[32+1] = {
static void static void
usage(void) usage(void)
{ {
fprint(2, "usage: aux/vga [ -BcdilpvV ] [ -b bios-id ] [ -m monitor ] [ -x db ] [ mode [ virtualsize ] ]\n"); fprint(2, "usage: aux/vga [ -BcdilpvV ] [ -b bios-id ] [ -m monitor ] [-s scaling] [ -x db ] [ mode [ virtualsize ] ]\n");
exits("usage"); exits("usage");
} }
@ -157,7 +157,7 @@ void
main(int argc, char** argv) main(int argc, char** argv)
{ {
char *bios, buf[256], sizeb[256], *p, *vsize, *psize; char *bios, buf[256], sizeb[256], *p, *vsize, *psize;
char *type, *vtype; char *type, *vtype, *scaling;
int virtual, len; int virtual, len;
Ctlr *ctlr; Ctlr *ctlr;
Vga *vga; Vga *vga;
@ -169,6 +169,7 @@ main(int argc, char** argv)
if((type = getenv("monitor")) == 0) if((type = getenv("monitor")) == 0)
type = "vga"; type = "vga";
psize = vsize = "640x480x8"; psize = vsize = "640x480x8";
scaling = nil;
ARGBEGIN{ ARGBEGIN{
default: default:
@ -204,6 +205,9 @@ main(int argc, char** argv)
*/ */
rflag++; rflag++;
break; break;
case 's':
scaling = EARGF(usage());
break;
case 'v': case 'v':
vflag = 1; vflag = 1;
break; break;
@ -467,6 +471,11 @@ main(int argc, char** argv)
} }
} }
if(scaling != nil){
if(vga->vesa)
vesa.scaling(vga, vga->vesa, scaling);
}
trace("main->exits\n"); trace("main->exits\n");
exits(0); exits(0);
} }

View file

@ -105,6 +105,8 @@ void vesaddc(void);
int vbeddcedid(Vbe *vbe, Edid *e); int vbeddcedid(Vbe *vbe, Edid *e);
void printedid(Edid*); void printedid(Edid*);
void fixbios(Vbe*); void fixbios(Vbe*);
uchar* vbesetup(Vbe*, Ureg*, int);
int vbecall(Vbe*, Ureg*);
int int
dbvesa(Vga* vga) dbvesa(Vga* vga)
@ -192,7 +194,7 @@ havemode:
*m = *vesamodes[i]; *m = *vesamodes[i];
break; break;
} }
if(edid){ if(edid != nil){
for(l = edid->modelist; l; l = l->next){ for(l = edid->modelist; l; l = l->next){
if(l->x != vm.dx || l->y != vm.dy) if(l->x != vm.dx || l->y != vm.dy)
continue; continue;
@ -272,7 +274,7 @@ dump(Vga*, Ctlr*)
char did[0x200]; char did[0x200];
uchar *p, *ep; uchar *p, *ep;
if(!vbe){ if(vbe == nil){
Bprint(&stdout, "no vesa bios\n"); Bprint(&stdout, "no vesa bios\n");
return; return;
} }
@ -280,7 +282,7 @@ dump(Vga*, Ctlr*)
memset(did, 0, sizeof did); memset(did, 0, sizeof did);
vbeprintinfo(vbe); vbeprintinfo(vbe);
p = vbemodes(vbe); p = vbemodes(vbe);
if(p){ if(p != nil){
for(ep=p+1024; (p[0]!=0xFF || p[1]!=0xFF) && p<ep; p+=2){ for(ep=p+1024; (p[0]!=0xFF || p[1]!=0xFF) && p<ep; p+=2){
vbeprintmodeinfo(vbe, WORD(p), ""); vbeprintmodeinfo(vbe, WORD(p), "");
if(WORD(p) < nelem(did)) if(WORD(p) < nelem(did))
@ -290,17 +292,48 @@ dump(Vga*, Ctlr*)
for(i=0x100; i<0x1FF; i++) for(i=0x100; i<0x1FF; i++)
if(!did[i]) if(!did[i])
vbeprintmodeinfo(vbe, i, " (unoffered)"); vbeprintmodeinfo(vbe, i, " (unoffered)");
if(edid) if(edid != nil)
printedid(edid); printedid(edid);
} }
static void
scaling(Vga*, Ctlr* ctlr, char* scaling)
{
Ureg u;
int mode;
if(vbe == nil)
error("no vesa bios\n");
if(strcmp(scaling, "off") == 0)
mode = 1;
else if(strcmp(scaling, "aspect") == 0)
mode = 3;
else if(strcmp(scaling, "full") == 0)
mode = 0;
else{
ctlr->flag |= Ferror;
fprint(2, "vbescaling: unknown mode %s\n", scaling);
return;
}
vbesetup(vbe, &u, 0x4F14);
u.bx = 0x102;
u.cx = mode;
if(vbecall(vbe, &u) < 0){
ctlr->flag |= Ferror;
fprint(2, "vbescaling: %r\n");
}
}
Ctlr vesa = { Ctlr vesa = {
"vesa", /* name */ "vesa",
snarf, /* snarf */ snarf,
options, /* options */ options,
0, /* init */ nil,
load, /* load */ load,
dump, /* dump */ dump,
scaling,
}; };
Ctlr softhwgc = { Ctlr softhwgc = {

View file

@ -49,6 +49,7 @@ typedef struct Ctlr {
void (*init)(Vga*, Ctlr*); void (*init)(Vga*, Ctlr*);
void (*load)(Vga*, Ctlr*); void (*load)(Vga*, Ctlr*);
void (*dump)(Vga*, Ctlr*); void (*dump)(Vga*, Ctlr*);
void (*scaling)(Vga*, Ctlr*, char*);
char* type; char* type;
ulong flag; ulong flag;