implement vesa screenblanking (issue #36)
This commit is contained in:
parent
1af6c6df32
commit
e54222fb0d
2 changed files with 100 additions and 19 deletions
|
@ -277,8 +277,13 @@ vgactl(Cmdbuf *cb)
|
||||||
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))
|
||||||
continue;
|
continue;
|
||||||
if(scr->dev && scr->dev->disable)
|
if(scr->dev){
|
||||||
scr->dev->disable(scr);
|
if(scr->dev->disable)
|
||||||
|
scr->dev->disable(scr);
|
||||||
|
scr->fill = nil;
|
||||||
|
scr->scroll = nil;
|
||||||
|
scr->blank = nil;
|
||||||
|
}
|
||||||
scr->dev = vgadev[i];
|
scr->dev = vgadev[i];
|
||||||
if(scr->dev->enable)
|
if(scr->dev->enable)
|
||||||
scr->dev->enable(scr);
|
scr->dev->enable(scr);
|
||||||
|
@ -352,6 +357,8 @@ vgactl(Cmdbuf *cb)
|
||||||
error("drawinit: no gscreen");
|
error("drawinit: no gscreen");
|
||||||
if(scr->dev && scr->dev->drawinit)
|
if(scr->dev && scr->dev->drawinit)
|
||||||
scr->dev->drawinit(scr);
|
scr->dev->drawinit(scr);
|
||||||
|
hwblank = scr->blank != nil;
|
||||||
|
hwaccel = scr->scroll || scr->fill;
|
||||||
vgascreenwin(scr);
|
vgascreenwin(scr);
|
||||||
resetscreenimage();
|
resetscreenimage();
|
||||||
cursoron(1);
|
cursoron(1);
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* vga driver using just vesa bios to set up.
|
* vga driver using just vesa bios to set up.
|
||||||
*
|
|
||||||
* note that setting hwaccel to zero will cause cursor ghosts to be
|
|
||||||
* left behind. hwaccel set non-zero repairs this.
|
|
||||||
*/
|
*/
|
||||||
#include "u.h"
|
#include "u.h"
|
||||||
#include "../port/lib.h"
|
#include "../port/lib.h"
|
||||||
|
@ -21,10 +18,18 @@
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
Usesoftscreen = 1,
|
Usesoftscreen = 1,
|
||||||
|
|
||||||
|
Cdisable = 0,
|
||||||
|
Cenable,
|
||||||
|
Cblank,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void *hardscreen;
|
static void *hardscreen;
|
||||||
static uchar modebuf[0x1000];
|
static uchar modebuf[0x1000];
|
||||||
|
static Chan *creg, *cmem;
|
||||||
|
static QLock vesaq;
|
||||||
|
static Rendez vesar;
|
||||||
|
static int vesactl;
|
||||||
|
|
||||||
#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))
|
||||||
|
@ -48,19 +53,15 @@ vbesetup(Ureg *u, int ax)
|
||||||
static void
|
static void
|
||||||
vbecall(Ureg *u)
|
vbecall(Ureg *u)
|
||||||
{
|
{
|
||||||
Chan *creg, *cmem;
|
static QLock callq;
|
||||||
ulong pa;
|
ulong pa;
|
||||||
|
|
||||||
cmem = namec("/dev/realmodemem", Aopen, ORDWR, 0);
|
eqlock(&callq);
|
||||||
if(waserror()){
|
if(waserror()){
|
||||||
cclose(cmem);
|
qunlock(&callq);
|
||||||
nexterror();
|
|
||||||
}
|
|
||||||
creg = namec("/dev/realmode", Aopen, ORDWR, 0);
|
|
||||||
if(waserror()){
|
|
||||||
cclose(creg);
|
|
||||||
nexterror();
|
nexterror();
|
||||||
}
|
}
|
||||||
|
|
||||||
pa = PADDR(RMBUF);
|
pa = PADDR(RMBUF);
|
||||||
if(devtab[cmem->type]->write(cmem, modebuf, sizeof(modebuf), pa) != sizeof(modebuf))
|
if(devtab[cmem->type]->write(cmem, modebuf, sizeof(modebuf), pa) != sizeof(modebuf))
|
||||||
error("write modebuf");
|
error("write modebuf");
|
||||||
|
@ -77,9 +78,7 @@ vbecall(Ureg *u)
|
||||||
error("read modebuf");
|
error("read modebuf");
|
||||||
|
|
||||||
poperror();
|
poperror();
|
||||||
cclose(creg);
|
qunlock(&callq);
|
||||||
poperror();
|
|
||||||
cclose(cmem);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -216,13 +215,88 @@ vesaflush(VGAscr *scr, Rectangle r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
vesadisabled(void *)
|
||||||
|
{
|
||||||
|
return vesactl == Cdisable;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vesaproc(void*)
|
||||||
|
{
|
||||||
|
Ureg u;
|
||||||
|
|
||||||
|
while(vesactl != Cdisable){
|
||||||
|
if(!waserror()){
|
||||||
|
sleep(&vesar, vesadisabled, nil);
|
||||||
|
vbesetup(&u, 0x4f10);
|
||||||
|
if(vesactl == Cblank)
|
||||||
|
u.bx = 0x0101;
|
||||||
|
else
|
||||||
|
u.bx = 0x0001;
|
||||||
|
vbecall(&u);
|
||||||
|
poperror();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cclose(cmem);
|
||||||
|
cclose(creg);
|
||||||
|
cmem = creg = nil;
|
||||||
|
qunlock(&vesaq);
|
||||||
|
|
||||||
|
pexit("", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vesaenable(VGAscr *)
|
||||||
|
{
|
||||||
|
eqlock(&vesaq);
|
||||||
|
if(waserror()){
|
||||||
|
qunlock(&vesaq);
|
||||||
|
nexterror();
|
||||||
|
}
|
||||||
|
cmem = namec("/dev/realmodemem", Aopen, ORDWR, 0);
|
||||||
|
if(waserror()){
|
||||||
|
cclose(cmem);
|
||||||
|
cmem = nil;
|
||||||
|
nexterror();
|
||||||
|
}
|
||||||
|
creg = namec("/dev/realmode", Aopen, ORDWR, 0);
|
||||||
|
poperror();
|
||||||
|
poperror();
|
||||||
|
|
||||||
|
vesactl = Cenable;
|
||||||
|
kproc("vesa", vesaproc, nil);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vesadisable(VGAscr *)
|
||||||
|
{
|
||||||
|
vesactl = Cdisable;
|
||||||
|
wakeup(&vesar);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vesablank(VGAscr *, int blank)
|
||||||
|
{
|
||||||
|
if(vesactl != Cdisable){
|
||||||
|
vesactl = blank ? Cblank : Cenable;
|
||||||
|
wakeup(&vesar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vesadrawinit(VGAscr *scr)
|
||||||
|
{
|
||||||
|
scr->blank = vesablank;
|
||||||
|
}
|
||||||
|
|
||||||
VGAdev vgavesadev = {
|
VGAdev vgavesadev = {
|
||||||
"vesa",
|
"vesa",
|
||||||
0,
|
vesaenable,
|
||||||
0,
|
vesadisable,
|
||||||
0,
|
0,
|
||||||
vesalinear,
|
vesalinear,
|
||||||
0,
|
vesadrawinit,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
|
|
Loading…
Reference in a new issue