5 #include "../port/lib.h"
10 #include "../port/error.h"
18 extern uchar *vgabios;
26 static Dirtab vgadir[] = {
27 ".", { Qdir, 0, QTDIR }, 0, 0550,
28 "vgactl", { Qvgactl, 0 }, 0, 0660,
29 "vgabios", { Qvgabios, 0 }, 0x10000, 0440,
35 /* reserve the 'standard' vga registers */
36 if(ioalloc(0x2b0, 0x2df-0x2b0+1, 0, "vga") < 0)
37 panic("vga ports already allocated");
38 if(ioalloc(0x3c0, 0x3da-0x3c0+1, 0, "vga") < 0)
39 panic("vga ports already allocated");
46 if(*spec && strcmp(spec, "0"))
48 return devattach('v', spec);
52 vgawalk(Chan* c, Chan *nc, char** name, int nname)
54 return devwalk(c, nc, name, nname, vgadir, nelem(vgadir), devgen);
58 vgastat(Chan* c, uchar* dp, int n)
60 return devstat(c, dp, n, vgadir, nelem(vgadir), devgen);
64 vgaopen(Chan* c, int omode)
66 return devopen(c, omode, vgadir, nelem(vgadir), devgen);
75 checkport(int start, int end)
77 /* standard vga regs are OK */
78 if(start >= 0x2b0 && end <= 0x2df+1)
80 if(start >= 0x3c0 && end <= 0x3da+1)
83 if(iounused(start, end))
89 vgaread(Chan* c, void* a, long n, vlong off)
97 switch((ulong)c->qid.path){
100 return devdirread(c, a, n, vgadir, nelem(vgadir), devgen);
117 len += snprint(p+len, READSTR-len, "type %s\n", s);
120 len += snprint(p+len, READSTR-len, "size %dx%dx%d %s\n",
121 scr->gscreen->r.max.x, scr->gscreen->r.max.y,
122 scr->gscreen->depth, chantostr(chbuf, scr->gscreen->chan));
124 if(Dx(scr->gscreen->r) != Dx(physgscreenr)
125 || Dy(scr->gscreen->r) != Dy(physgscreenr))
126 len += snprint(p+len, READSTR-len, "actualsize %dx%d\n",
127 physgscreenr.max.x, physgscreenr.max.y);
130 len += snprint(p+len, READSTR-len, "blanktime %lud\n", blanktime);
131 len += snprint(p+len, READSTR-len, "hwaccel %s\n", hwaccel ? "on" : "off");
132 len += snprint(p+len, READSTR-len, "hwblank %s\n", hwblank ? "on" : "off");
133 snprint(p+len, READSTR-len, "addr 0x%lux\n", scr->paddr);
134 n = readstr(offset, a, n, p);
143 if(offset&0x80000000)
144 offset &= ~0x800E0000;
145 if(offset+n > 0x10000)
149 memmove(a, vgabios+offset, n);
160 static char Ebusy[] = "vga already configured";
165 int align, i, n, size, x, y, z;
166 char *chanstr, *field[6], *p;
169 extern VGAdev *vgadev[];
170 extern VGAcur *vgacur[];
173 n = tokenize(a, field, nelem(field));
178 if(strcmp(field[0], "hwgc") == 0){
182 if(strcmp(field[1], "off") == 0){
185 if(scr->cur->disable)
186 scr->cur->disable(scr);
193 for(i = 0; vgacur[i]; i++){
194 if(strcmp(field[1], vgacur[i]->name))
197 if(scr->cur && scr->cur->disable)
198 scr->cur->disable(scr);
199 scr->cur = vgacur[i];
201 scr->cur->enable(scr);
206 else if(strcmp(field[0], "type") == 0){
210 for(i = 0; vgadev[i]; i++){
211 if(strcmp(field[1], vgadev[i]->name))
213 if(scr->dev && scr->dev->disable)
214 scr->dev->disable(scr);
215 scr->dev = vgadev[i];
217 scr->dev->enable(scr);
221 else if(strcmp(field[0], "size") == 0){
227 x = strtoul(field[1], &p, 0);
228 if(x == 0 || x > 2048)
233 y = strtoul(p, &p, 0);
234 if(y == 0 || y > 2048)
239 z = strtoul(p, &p, 0);
242 if((chan = strtochan(chanstr)) == 0)
243 error("bad channel");
245 if(chantodepth(chan) != z)
246 error("depth, channel do not match");
250 if(screensize(x, y, z, chan))
256 else if(strcmp(field[0], "actualsize") == 0){
257 if(scr->gscreen == nil)
258 error("set the screen size first");
262 x = strtoul(field[1], &p, 0);
263 if(x == 0 || x > 2048)
268 y = strtoul(p, nil, 0);
269 if(y == 0 || y > 2048)
272 if(x > scr->gscreen->r.max.x || y > scr->gscreen->r.max.y)
273 error("physical screen bigger than virtual");
276 if(!eqrect(r, scr->gscreen->r)){
277 if(scr->cur == nil || scr->cur->doespanning == 0)
278 error("virtual screen not supported");
284 else if(strcmp(field[0], "palettedepth") == 0){
288 x = strtoul(field[1], &p, 0);
292 scr->palettedepth = x;
295 else if(strcmp(field[0], "drawinit") == 0){
296 if(scr && scr->dev && scr->dev->drawinit)
297 scr->dev->drawinit(scr);
300 else if(strcmp(field[0], "linear") == 0){
304 size = strtoul(field[1], 0, 0);
308 align = strtoul(field[2], 0, 0);
309 if(screenaperture(size, align))
310 error("not enough free address space");
313 /* else if(strcmp(field[0], "memset") == 0){
316 memset((void*)strtoul(field[1], 0, 0), atoi(field[2]), atoi(field[3]));
320 else if(strcmp(field[0], "blank") == 0){
326 else if(strcmp(field[0], "blanktime") == 0){
329 blanktime = strtoul(field[1], 0, 0);
332 else if(strcmp(field[0], "hwaccel") == 0){
335 if(strcmp(field[1], "on") == 0)
337 else if(strcmp(field[1], "off") == 0)
341 else if(strcmp(field[0], "hwblank") == 0){
344 if(strcmp(field[1], "on") == 0)
346 else if(strcmp(field[1], "off") == 0)
355 vgawrite(Chan* c, void* a, long n, vlong off)
360 switch((ulong)c->qid.path){
366 if(offset || n >= READSTR)