1*45e6af3bSDavid du Colombier /*
2*45e6af3bSDavid du Colombier * VGA controller
3*45e6af3bSDavid du Colombier */
4*45e6af3bSDavid du Colombier #include "u.h"
5*45e6af3bSDavid du Colombier #include "../port/lib.h"
6*45e6af3bSDavid du Colombier #include "mem.h"
7*45e6af3bSDavid du Colombier #include "dat.h"
8*45e6af3bSDavid du Colombier #include "fns.h"
9*45e6af3bSDavid du Colombier #include "io.h"
10*45e6af3bSDavid du Colombier #include "../port/error.h"
11*45e6af3bSDavid du Colombier
12*45e6af3bSDavid du Colombier #define Image IMAGE
13*45e6af3bSDavid du Colombier #include <draw.h>
14*45e6af3bSDavid du Colombier #include <memdraw.h>
15*45e6af3bSDavid du Colombier #include <cursor.h>
16*45e6af3bSDavid du Colombier #include "screen.h"
17*45e6af3bSDavid du Colombier
18*45e6af3bSDavid du Colombier enum {
19*45e6af3bSDavid du Colombier Qdir,
20*45e6af3bSDavid du Colombier Qvgabios,
21*45e6af3bSDavid du Colombier Qvgactl,
22*45e6af3bSDavid du Colombier Qvgaovl,
23*45e6af3bSDavid du Colombier Qvgaovlctl,
24*45e6af3bSDavid du Colombier };
25*45e6af3bSDavid du Colombier
26*45e6af3bSDavid du Colombier static Dirtab vgadir[] = {
27*45e6af3bSDavid du Colombier ".", { Qdir, 0, QTDIR }, 0, 0550,
28*45e6af3bSDavid du Colombier "vgabios", { Qvgabios, 0 }, 0x100000, 0440,
29*45e6af3bSDavid du Colombier "vgactl", { Qvgactl, 0 }, 0, 0660,
30*45e6af3bSDavid du Colombier "vgaovl", { Qvgaovl, 0 }, 0, 0660,
31*45e6af3bSDavid du Colombier "vgaovlctl", { Qvgaovlctl, 0 }, 0, 0660,
32*45e6af3bSDavid du Colombier };
33*45e6af3bSDavid du Colombier
34*45e6af3bSDavid du Colombier enum {
35*45e6af3bSDavid du Colombier CMactualsize,
36*45e6af3bSDavid du Colombier CMblank,
37*45e6af3bSDavid du Colombier CMblanktime,
38*45e6af3bSDavid du Colombier CMdrawinit,
39*45e6af3bSDavid du Colombier CMhwaccel,
40*45e6af3bSDavid du Colombier CMhwblank,
41*45e6af3bSDavid du Colombier CMhwgc,
42*45e6af3bSDavid du Colombier CMlinear,
43*45e6af3bSDavid du Colombier CMpalettedepth,
44*45e6af3bSDavid du Colombier CMpanning,
45*45e6af3bSDavid du Colombier CMsize,
46*45e6af3bSDavid du Colombier CMtextmode,
47*45e6af3bSDavid du Colombier CMtype,
48*45e6af3bSDavid du Colombier CMunblank,
49*45e6af3bSDavid du Colombier };
50*45e6af3bSDavid du Colombier
51*45e6af3bSDavid du Colombier static Cmdtab vgactlmsg[] = {
52*45e6af3bSDavid du Colombier CMactualsize, "actualsize", 2,
53*45e6af3bSDavid du Colombier CMblank, "blank", 1,
54*45e6af3bSDavid du Colombier CMblanktime, "blanktime", 2,
55*45e6af3bSDavid du Colombier CMdrawinit, "drawinit", 1,
56*45e6af3bSDavid du Colombier CMhwaccel, "hwaccel", 2,
57*45e6af3bSDavid du Colombier CMhwblank, "hwblank", 2,
58*45e6af3bSDavid du Colombier CMhwgc, "hwgc", 2,
59*45e6af3bSDavid du Colombier CMlinear, "linear", 0,
60*45e6af3bSDavid du Colombier CMpalettedepth, "palettedepth", 2,
61*45e6af3bSDavid du Colombier CMpanning, "panning", 2,
62*45e6af3bSDavid du Colombier CMsize, "size", 3,
63*45e6af3bSDavid du Colombier CMtextmode, "textmode", 1,
64*45e6af3bSDavid du Colombier CMtype, "type", 2,
65*45e6af3bSDavid du Colombier CMunblank, "unblank", 1,
66*45e6af3bSDavid du Colombier };
67*45e6af3bSDavid du Colombier
68*45e6af3bSDavid du Colombier static void
vgareset(void)69*45e6af3bSDavid du Colombier vgareset(void)
70*45e6af3bSDavid du Colombier {
71*45e6af3bSDavid du Colombier /* reserve the 'standard' vga registers */
72*45e6af3bSDavid du Colombier if(ioalloc(0x2b0, 0x2df-0x2b0+1, 0, "vga") < 0)
73*45e6af3bSDavid du Colombier panic("vga ports already allocated");
74*45e6af3bSDavid du Colombier if(ioalloc(0x3c0, 0x3da-0x3c0+1, 0, "vga") < 0)
75*45e6af3bSDavid du Colombier panic("vga ports already allocated");
76*45e6af3bSDavid du Colombier }
77*45e6af3bSDavid du Colombier
78*45e6af3bSDavid du Colombier static Chan*
vgaattach(char * spec)79*45e6af3bSDavid du Colombier vgaattach(char* spec)
80*45e6af3bSDavid du Colombier {
81*45e6af3bSDavid du Colombier if(*spec && strcmp(spec, "0"))
82*45e6af3bSDavid du Colombier error(Eio);
83*45e6af3bSDavid du Colombier return devattach('v', spec);
84*45e6af3bSDavid du Colombier }
85*45e6af3bSDavid du Colombier
86*45e6af3bSDavid du Colombier Walkqid*
vgawalk(Chan * c,Chan * nc,char ** name,int nname)87*45e6af3bSDavid du Colombier vgawalk(Chan* c, Chan *nc, char** name, int nname)
88*45e6af3bSDavid du Colombier {
89*45e6af3bSDavid du Colombier return devwalk(c, nc, name, nname, vgadir, nelem(vgadir), devgen);
90*45e6af3bSDavid du Colombier }
91*45e6af3bSDavid du Colombier
92*45e6af3bSDavid du Colombier static long
vgastat(Chan * c,uchar * dp,long n)93*45e6af3bSDavid du Colombier vgastat(Chan* c, uchar* dp, long n)
94*45e6af3bSDavid du Colombier {
95*45e6af3bSDavid du Colombier return devstat(c, dp, n, vgadir, nelem(vgadir), devgen);
96*45e6af3bSDavid du Colombier }
97*45e6af3bSDavid du Colombier
98*45e6af3bSDavid du Colombier static Chan*
vgaopen(Chan * c,int omode)99*45e6af3bSDavid du Colombier vgaopen(Chan* c, int omode)
100*45e6af3bSDavid du Colombier {
101*45e6af3bSDavid du Colombier VGAscr *scr;
102*45e6af3bSDavid du Colombier static char *openctl = "openctl\n";
103*45e6af3bSDavid du Colombier
104*45e6af3bSDavid du Colombier scr = &vgascreen[0];
105*45e6af3bSDavid du Colombier if ((ulong)c->qid.path == Qvgaovlctl) {
106*45e6af3bSDavid du Colombier if (scr->dev && scr->dev->ovlctl)
107*45e6af3bSDavid du Colombier scr->dev->ovlctl(scr, c, openctl, strlen(openctl));
108*45e6af3bSDavid du Colombier else
109*45e6af3bSDavid du Colombier error(Enonexist);
110*45e6af3bSDavid du Colombier }
111*45e6af3bSDavid du Colombier return devopen(c, omode, vgadir, nelem(vgadir), devgen);
112*45e6af3bSDavid du Colombier }
113*45e6af3bSDavid du Colombier
114*45e6af3bSDavid du Colombier static void
vgaclose(Chan * c)115*45e6af3bSDavid du Colombier vgaclose(Chan* c)
116*45e6af3bSDavid du Colombier {
117*45e6af3bSDavid du Colombier VGAscr *scr;
118*45e6af3bSDavid du Colombier static char *closectl = "closectl\n";
119*45e6af3bSDavid du Colombier
120*45e6af3bSDavid du Colombier scr = &vgascreen[0];
121*45e6af3bSDavid du Colombier if((ulong)c->qid.path == Qvgaovlctl)
122*45e6af3bSDavid du Colombier if(scr->dev && scr->dev->ovlctl){
123*45e6af3bSDavid du Colombier if(waserror()){
124*45e6af3bSDavid du Colombier print("ovlctl error: %s\n", up->errstr);
125*45e6af3bSDavid du Colombier return;
126*45e6af3bSDavid du Colombier }
127*45e6af3bSDavid du Colombier scr->dev->ovlctl(scr, c, closectl, strlen(closectl));
128*45e6af3bSDavid du Colombier poperror();
129*45e6af3bSDavid du Colombier }
130*45e6af3bSDavid du Colombier }
131*45e6af3bSDavid du Colombier
132*45e6af3bSDavid du Colombier static long
vgaread(Chan * c,void * a,long n,vlong off)133*45e6af3bSDavid du Colombier vgaread(Chan* c, void* a, long n, vlong off)
134*45e6af3bSDavid du Colombier {
135*45e6af3bSDavid du Colombier int len;
136*45e6af3bSDavid du Colombier char *p, *s;
137*45e6af3bSDavid du Colombier VGAscr *scr;
138*45e6af3bSDavid du Colombier ulong offset = off;
139*45e6af3bSDavid du Colombier char chbuf[30];
140*45e6af3bSDavid du Colombier
141*45e6af3bSDavid du Colombier switch((ulong)c->qid.path){
142*45e6af3bSDavid du Colombier
143*45e6af3bSDavid du Colombier case Qdir:
144*45e6af3bSDavid du Colombier return devdirread(c, a, n, vgadir, nelem(vgadir), devgen);
145*45e6af3bSDavid du Colombier
146*45e6af3bSDavid du Colombier case Qvgabios:
147*45e6af3bSDavid du Colombier if(offset >= 0x100000)
148*45e6af3bSDavid du Colombier return 0;
149*45e6af3bSDavid du Colombier if(offset+n >= 0x100000)
150*45e6af3bSDavid du Colombier n = 0x100000 - offset;
151*45e6af3bSDavid du Colombier memmove(a, (uchar*)KADDR(0)+offset, n);
152*45e6af3bSDavid du Colombier return n;
153*45e6af3bSDavid du Colombier
154*45e6af3bSDavid du Colombier case Qvgactl:
155*45e6af3bSDavid du Colombier scr = &vgascreen[0];
156*45e6af3bSDavid du Colombier
157*45e6af3bSDavid du Colombier p = malloc(READSTR);
158*45e6af3bSDavid du Colombier if(p == nil)
159*45e6af3bSDavid du Colombier error(Enomem);
160*45e6af3bSDavid du Colombier if(waserror()){
161*45e6af3bSDavid du Colombier free(p);
162*45e6af3bSDavid du Colombier nexterror();
163*45e6af3bSDavid du Colombier }
164*45e6af3bSDavid du Colombier
165*45e6af3bSDavid du Colombier len = 0;
166*45e6af3bSDavid du Colombier
167*45e6af3bSDavid du Colombier if(scr->dev)
168*45e6af3bSDavid du Colombier s = scr->dev->name;
169*45e6af3bSDavid du Colombier else
170*45e6af3bSDavid du Colombier s = "cga";
171*45e6af3bSDavid du Colombier len += snprint(p+len, READSTR-len, "type %s\n", s);
172*45e6af3bSDavid du Colombier
173*45e6af3bSDavid du Colombier if(scr->gscreen) {
174*45e6af3bSDavid du Colombier len += snprint(p+len, READSTR-len, "size %dx%dx%d %s\n",
175*45e6af3bSDavid du Colombier scr->gscreen->r.max.x, scr->gscreen->r.max.y,
176*45e6af3bSDavid du Colombier scr->gscreen->depth, chantostr(chbuf, scr->gscreen->chan));
177*45e6af3bSDavid du Colombier
178*45e6af3bSDavid du Colombier if(Dx(scr->gscreen->r) != Dx(physgscreenr)
179*45e6af3bSDavid du Colombier || Dy(scr->gscreen->r) != Dy(physgscreenr))
180*45e6af3bSDavid du Colombier len += snprint(p+len, READSTR-len, "actualsize %dx%d\n",
181*45e6af3bSDavid du Colombier physgscreenr.max.x, physgscreenr.max.y);
182*45e6af3bSDavid du Colombier }
183*45e6af3bSDavid du Colombier
184*45e6af3bSDavid du Colombier len += snprint(p+len, READSTR-len, "blank time %lud idle %d state %s\n",
185*45e6af3bSDavid du Colombier blanktime, drawidletime(), scr->isblank ? "off" : "on");
186*45e6af3bSDavid du Colombier len += snprint(p+len, READSTR-len, "hwaccel %s\n", hwaccel ? "on" : "off");
187*45e6af3bSDavid du Colombier len += snprint(p+len, READSTR-len, "hwblank %s\n", hwblank ? "on" : "off");
188*45e6af3bSDavid du Colombier len += snprint(p+len, READSTR-len, "panning %s\n", panning ? "on" : "off");
189*45e6af3bSDavid du Colombier len += snprint(p+len, READSTR-len, "addr p 0x%lux v 0x%p size 0x%ux\n", scr->paddr, scr->vaddr, scr->apsize);
190*45e6af3bSDavid du Colombier USED(len);
191*45e6af3bSDavid du Colombier
192*45e6af3bSDavid du Colombier n = readstr(offset, a, n, p);
193*45e6af3bSDavid du Colombier poperror();
194*45e6af3bSDavid du Colombier free(p);
195*45e6af3bSDavid du Colombier
196*45e6af3bSDavid du Colombier return n;
197*45e6af3bSDavid du Colombier
198*45e6af3bSDavid du Colombier case Qvgaovl:
199*45e6af3bSDavid du Colombier case Qvgaovlctl:
200*45e6af3bSDavid du Colombier error(Ebadusefd);
201*45e6af3bSDavid du Colombier break;
202*45e6af3bSDavid du Colombier
203*45e6af3bSDavid du Colombier default:
204*45e6af3bSDavid du Colombier error(Egreg);
205*45e6af3bSDavid du Colombier break;
206*45e6af3bSDavid du Colombier }
207*45e6af3bSDavid du Colombier
208*45e6af3bSDavid du Colombier return 0;
209*45e6af3bSDavid du Colombier }
210*45e6af3bSDavid du Colombier
211*45e6af3bSDavid du Colombier static void
vgactl(Cmdbuf * cb)212*45e6af3bSDavid du Colombier vgactl(Cmdbuf *cb)
213*45e6af3bSDavid du Colombier {
214*45e6af3bSDavid du Colombier int align, i, size, x, y, z;
215*45e6af3bSDavid du Colombier char *chanstr, *p;
216*45e6af3bSDavid du Colombier ulong chan;
217*45e6af3bSDavid du Colombier Cmdtab *ct;
218*45e6af3bSDavid du Colombier VGAscr *scr;
219*45e6af3bSDavid du Colombier extern VGAdev *vgadev[];
220*45e6af3bSDavid du Colombier extern VGAcur *vgacur[];
221*45e6af3bSDavid du Colombier
222*45e6af3bSDavid du Colombier scr = &vgascreen[0];
223*45e6af3bSDavid du Colombier ct = lookupcmd(cb, vgactlmsg, nelem(vgactlmsg));
224*45e6af3bSDavid du Colombier switch(ct->index){
225*45e6af3bSDavid du Colombier case CMhwgc:
226*45e6af3bSDavid du Colombier if(strcmp(cb->f[1], "off") == 0){
227*45e6af3bSDavid du Colombier lock(&cursor);
228*45e6af3bSDavid du Colombier if(scr->cur){
229*45e6af3bSDavid du Colombier if(scr->cur->disable)
230*45e6af3bSDavid du Colombier scr->cur->disable(scr);
231*45e6af3bSDavid du Colombier scr->cur = nil;
232*45e6af3bSDavid du Colombier }
233*45e6af3bSDavid du Colombier unlock(&cursor);
234*45e6af3bSDavid du Colombier return;
235*45e6af3bSDavid du Colombier }
236*45e6af3bSDavid du Colombier if(strcmp(cb->f[1], "soft") == 0){
237*45e6af3bSDavid du Colombier lock(&cursor);
238*45e6af3bSDavid du Colombier swcursorinit();
239*45e6af3bSDavid du Colombier if(scr->cur && scr->cur->disable)
240*45e6af3bSDavid du Colombier scr->cur->disable(scr);
241*45e6af3bSDavid du Colombier scr->cur = &swcursor;
242*45e6af3bSDavid du Colombier if(scr->cur->enable)
243*45e6af3bSDavid du Colombier scr->cur->enable(scr);
244*45e6af3bSDavid du Colombier unlock(&cursor);
245*45e6af3bSDavid du Colombier return;
246*45e6af3bSDavid du Colombier }
247*45e6af3bSDavid du Colombier for(i = 0; vgacur[i]; i++){
248*45e6af3bSDavid du Colombier if(strcmp(cb->f[1], vgacur[i]->name))
249*45e6af3bSDavid du Colombier continue;
250*45e6af3bSDavid du Colombier lock(&cursor);
251*45e6af3bSDavid du Colombier if(scr->cur && scr->cur->disable)
252*45e6af3bSDavid du Colombier scr->cur->disable(scr);
253*45e6af3bSDavid du Colombier scr->cur = vgacur[i];
254*45e6af3bSDavid du Colombier if(scr->cur->enable)
255*45e6af3bSDavid du Colombier scr->cur->enable(scr);
256*45e6af3bSDavid du Colombier unlock(&cursor);
257*45e6af3bSDavid du Colombier return;
258*45e6af3bSDavid du Colombier }
259*45e6af3bSDavid du Colombier break;
260*45e6af3bSDavid du Colombier
261*45e6af3bSDavid du Colombier case CMtype:
262*45e6af3bSDavid du Colombier for(i = 0; vgadev[i]; i++){
263*45e6af3bSDavid du Colombier if(strcmp(cb->f[1], vgadev[i]->name))
264*45e6af3bSDavid du Colombier continue;
265*45e6af3bSDavid du Colombier if(scr->dev && scr->dev->disable)
266*45e6af3bSDavid du Colombier scr->dev->disable(scr);
267*45e6af3bSDavid du Colombier scr->dev = vgadev[i];
268*45e6af3bSDavid du Colombier if(scr->dev->enable)
269*45e6af3bSDavid du Colombier scr->dev->enable(scr);
270*45e6af3bSDavid du Colombier return;
271*45e6af3bSDavid du Colombier }
272*45e6af3bSDavid du Colombier break;
273*45e6af3bSDavid du Colombier
274*45e6af3bSDavid du Colombier case CMtextmode:
275*45e6af3bSDavid du Colombier cgainit();
276*45e6af3bSDavid du Colombier return;
277*45e6af3bSDavid du Colombier
278*45e6af3bSDavid du Colombier case CMsize:
279*45e6af3bSDavid du Colombier x = strtoul(cb->f[1], &p, 0);
280*45e6af3bSDavid du Colombier if(x == 0 || x > 10240)
281*45e6af3bSDavid du Colombier error(Ebadarg);
282*45e6af3bSDavid du Colombier if(*p)
283*45e6af3bSDavid du Colombier p++;
284*45e6af3bSDavid du Colombier
285*45e6af3bSDavid du Colombier y = strtoul(p, &p, 0);
286*45e6af3bSDavid du Colombier if(y == 0 || y > 10240)
287*45e6af3bSDavid du Colombier error(Ebadarg);
288*45e6af3bSDavid du Colombier if(*p)
289*45e6af3bSDavid du Colombier p++;
290*45e6af3bSDavid du Colombier
291*45e6af3bSDavid du Colombier z = strtoul(p, &p, 0);
292*45e6af3bSDavid du Colombier
293*45e6af3bSDavid du Colombier chanstr = cb->f[2];
294*45e6af3bSDavid du Colombier if((chan = strtochan(chanstr)) == 0)
295*45e6af3bSDavid du Colombier error("bad channel");
296*45e6af3bSDavid du Colombier
297*45e6af3bSDavid du Colombier if(chantodepth(chan) != z)
298*45e6af3bSDavid du Colombier error("depth, channel do not match");
299*45e6af3bSDavid du Colombier
300*45e6af3bSDavid du Colombier cursoroff(1);
301*45e6af3bSDavid du Colombier deletescreenimage();
302*45e6af3bSDavid du Colombier if(screensize(x, y, z, chan))
303*45e6af3bSDavid du Colombier error(Egreg);
304*45e6af3bSDavid du Colombier vgascreenwin(scr);
305*45e6af3bSDavid du Colombier resetscreenimage();
306*45e6af3bSDavid du Colombier cursoron(1);
307*45e6af3bSDavid du Colombier return;
308*45e6af3bSDavid du Colombier
309*45e6af3bSDavid du Colombier case CMactualsize:
310*45e6af3bSDavid du Colombier if(scr->gscreen == nil)
311*45e6af3bSDavid du Colombier error("set the screen size first");
312*45e6af3bSDavid du Colombier
313*45e6af3bSDavid du Colombier x = strtoul(cb->f[1], &p, 0);
314*45e6af3bSDavid du Colombier if(x == 0 || x > 2048)
315*45e6af3bSDavid du Colombier error(Ebadarg);
316*45e6af3bSDavid du Colombier if(*p)
317*45e6af3bSDavid du Colombier p++;
318*45e6af3bSDavid du Colombier
319*45e6af3bSDavid du Colombier y = strtoul(p, nil, 0);
320*45e6af3bSDavid du Colombier if(y == 0 || y > 2048)
321*45e6af3bSDavid du Colombier error(Ebadarg);
322*45e6af3bSDavid du Colombier
323*45e6af3bSDavid du Colombier if(x > scr->gscreen->r.max.x || y > scr->gscreen->r.max.y)
324*45e6af3bSDavid du Colombier error("physical screen bigger than virtual");
325*45e6af3bSDavid du Colombier
326*45e6af3bSDavid du Colombier physgscreenr = Rect(0,0,x,y);
327*45e6af3bSDavid du Colombier scr->gscreen->clipr = physgscreenr;
328*45e6af3bSDavid du Colombier return;
329*45e6af3bSDavid du Colombier
330*45e6af3bSDavid du Colombier case CMpalettedepth:
331*45e6af3bSDavid du Colombier x = strtoul(cb->f[1], &p, 0);
332*45e6af3bSDavid du Colombier if(x != 8 && x != 6)
333*45e6af3bSDavid du Colombier error(Ebadarg);
334*45e6af3bSDavid du Colombier
335*45e6af3bSDavid du Colombier scr->palettedepth = x;
336*45e6af3bSDavid du Colombier return;
337*45e6af3bSDavid du Colombier
338*45e6af3bSDavid du Colombier case CMdrawinit:
339*45e6af3bSDavid du Colombier if(scr->gscreen == nil)
340*45e6af3bSDavid du Colombier error("drawinit: no gscreen");
341*45e6af3bSDavid du Colombier if(scr->dev && scr->dev->drawinit)
342*45e6af3bSDavid du Colombier scr->dev->drawinit(scr);
343*45e6af3bSDavid du Colombier return;
344*45e6af3bSDavid du Colombier
345*45e6af3bSDavid du Colombier case CMlinear:
346*45e6af3bSDavid du Colombier if(cb->nf!=2 && cb->nf!=3)
347*45e6af3bSDavid du Colombier error(Ebadarg);
348*45e6af3bSDavid du Colombier size = strtoul(cb->f[1], 0, 0);
349*45e6af3bSDavid du Colombier if(cb->nf == 2)
350*45e6af3bSDavid du Colombier align = 0;
351*45e6af3bSDavid du Colombier else
352*45e6af3bSDavid du Colombier align = strtoul(cb->f[2], 0, 0);
353*45e6af3bSDavid du Colombier if(screenaperture(size, align) < 0)
354*45e6af3bSDavid du Colombier error("not enough free address space");
355*45e6af3bSDavid du Colombier return;
356*45e6af3bSDavid du Colombier /*
357*45e6af3bSDavid du Colombier case CMmemset:
358*45e6af3bSDavid du Colombier memset((void*)strtoul(cb->f[1], 0, 0), atoi(cb->f[2]), atoi(cb->f[3]));
359*45e6af3bSDavid du Colombier return;
360*45e6af3bSDavid du Colombier */
361*45e6af3bSDavid du Colombier
362*45e6af3bSDavid du Colombier case CMblank:
363*45e6af3bSDavid du Colombier drawblankscreen(1);
364*45e6af3bSDavid du Colombier return;
365*45e6af3bSDavid du Colombier
366*45e6af3bSDavid du Colombier case CMunblank:
367*45e6af3bSDavid du Colombier drawblankscreen(0);
368*45e6af3bSDavid du Colombier return;
369*45e6af3bSDavid du Colombier
370*45e6af3bSDavid du Colombier case CMblanktime:
371*45e6af3bSDavid du Colombier blanktime = strtoul(cb->f[1], 0, 0);
372*45e6af3bSDavid du Colombier return;
373*45e6af3bSDavid du Colombier
374*45e6af3bSDavid du Colombier case CMpanning:
375*45e6af3bSDavid du Colombier if(strcmp(cb->f[1], "on") == 0){
376*45e6af3bSDavid du Colombier if(scr == nil || scr->cur == nil)
377*45e6af3bSDavid du Colombier error("set screen first");
378*45e6af3bSDavid du Colombier if(!scr->cur->doespanning)
379*45e6af3bSDavid du Colombier error("panning not supported");
380*45e6af3bSDavid du Colombier scr->gscreen->clipr = scr->gscreen->r;
381*45e6af3bSDavid du Colombier panning = 1;
382*45e6af3bSDavid du Colombier }
383*45e6af3bSDavid du Colombier else if(strcmp(cb->f[1], "off") == 0){
384*45e6af3bSDavid du Colombier scr->gscreen->clipr = physgscreenr;
385*45e6af3bSDavid du Colombier panning = 0;
386*45e6af3bSDavid du Colombier }else
387*45e6af3bSDavid du Colombier break;
388*45e6af3bSDavid du Colombier return;
389*45e6af3bSDavid du Colombier
390*45e6af3bSDavid du Colombier case CMhwaccel:
391*45e6af3bSDavid du Colombier if(strcmp(cb->f[1], "on") == 0)
392*45e6af3bSDavid du Colombier hwaccel = 1;
393*45e6af3bSDavid du Colombier else if(strcmp(cb->f[1], "off") == 0)
394*45e6af3bSDavid du Colombier hwaccel = 0;
395*45e6af3bSDavid du Colombier else
396*45e6af3bSDavid du Colombier break;
397*45e6af3bSDavid du Colombier return;
398*45e6af3bSDavid du Colombier
399*45e6af3bSDavid du Colombier case CMhwblank:
400*45e6af3bSDavid du Colombier if(strcmp(cb->f[1], "on") == 0)
401*45e6af3bSDavid du Colombier hwblank = 1;
402*45e6af3bSDavid du Colombier else if(strcmp(cb->f[1], "off") == 0)
403*45e6af3bSDavid du Colombier hwblank = 0;
404*45e6af3bSDavid du Colombier else
405*45e6af3bSDavid du Colombier break;
406*45e6af3bSDavid du Colombier return;
407*45e6af3bSDavid du Colombier }
408*45e6af3bSDavid du Colombier
409*45e6af3bSDavid du Colombier cmderror(cb, "bad VGA control message");
410*45e6af3bSDavid du Colombier }
411*45e6af3bSDavid du Colombier
412*45e6af3bSDavid du Colombier char Enooverlay[] = "No overlay support";
413*45e6af3bSDavid du Colombier
414*45e6af3bSDavid du Colombier static long
vgawrite(Chan * c,void * a,long n,vlong off)415*45e6af3bSDavid du Colombier vgawrite(Chan* c, void* a, long n, vlong off)
416*45e6af3bSDavid du Colombier {
417*45e6af3bSDavid du Colombier ulong offset = off;
418*45e6af3bSDavid du Colombier Cmdbuf *cb;
419*45e6af3bSDavid du Colombier VGAscr *scr;
420*45e6af3bSDavid du Colombier
421*45e6af3bSDavid du Colombier switch((ulong)c->qid.path){
422*45e6af3bSDavid du Colombier
423*45e6af3bSDavid du Colombier case Qdir:
424*45e6af3bSDavid du Colombier error(Eperm);
425*45e6af3bSDavid du Colombier
426*45e6af3bSDavid du Colombier case Qvgactl:
427*45e6af3bSDavid du Colombier if(offset || n >= READSTR)
428*45e6af3bSDavid du Colombier error(Ebadarg);
429*45e6af3bSDavid du Colombier cb = parsecmd(a, n);
430*45e6af3bSDavid du Colombier if(waserror()){
431*45e6af3bSDavid du Colombier free(cb);
432*45e6af3bSDavid du Colombier nexterror();
433*45e6af3bSDavid du Colombier }
434*45e6af3bSDavid du Colombier vgactl(cb);
435*45e6af3bSDavid du Colombier poperror();
436*45e6af3bSDavid du Colombier free(cb);
437*45e6af3bSDavid du Colombier return n;
438*45e6af3bSDavid du Colombier
439*45e6af3bSDavid du Colombier case Qvgaovl:
440*45e6af3bSDavid du Colombier scr = &vgascreen[0];
441*45e6af3bSDavid du Colombier if (scr->dev == nil || scr->dev->ovlwrite == nil) {
442*45e6af3bSDavid du Colombier error(Enooverlay);
443*45e6af3bSDavid du Colombier break;
444*45e6af3bSDavid du Colombier }
445*45e6af3bSDavid du Colombier return scr->dev->ovlwrite(scr, a, n, off);
446*45e6af3bSDavid du Colombier
447*45e6af3bSDavid du Colombier case Qvgaovlctl:
448*45e6af3bSDavid du Colombier scr = &vgascreen[0];
449*45e6af3bSDavid du Colombier if (scr->dev == nil || scr->dev->ovlctl == nil) {
450*45e6af3bSDavid du Colombier error(Enooverlay);
451*45e6af3bSDavid du Colombier break;
452*45e6af3bSDavid du Colombier }
453*45e6af3bSDavid du Colombier scr->dev->ovlctl(scr, c, a, n);
454*45e6af3bSDavid du Colombier return n;
455*45e6af3bSDavid du Colombier
456*45e6af3bSDavid du Colombier default:
457*45e6af3bSDavid du Colombier error(Egreg);
458*45e6af3bSDavid du Colombier break;
459*45e6af3bSDavid du Colombier }
460*45e6af3bSDavid du Colombier
461*45e6af3bSDavid du Colombier return 0;
462*45e6af3bSDavid du Colombier }
463*45e6af3bSDavid du Colombier
464*45e6af3bSDavid du Colombier Dev vgadevtab = {
465*45e6af3bSDavid du Colombier 'v',
466*45e6af3bSDavid du Colombier "vga",
467*45e6af3bSDavid du Colombier
468*45e6af3bSDavid du Colombier vgareset,
469*45e6af3bSDavid du Colombier devinit,
470*45e6af3bSDavid du Colombier devshutdown,
471*45e6af3bSDavid du Colombier vgaattach,
472*45e6af3bSDavid du Colombier vgawalk,
473*45e6af3bSDavid du Colombier vgastat,
474*45e6af3bSDavid du Colombier vgaopen,
475*45e6af3bSDavid du Colombier devcreate,
476*45e6af3bSDavid du Colombier vgaclose,
477*45e6af3bSDavid du Colombier vgaread,
478*45e6af3bSDavid du Colombier devbread,
479*45e6af3bSDavid du Colombier vgawrite,
480*45e6af3bSDavid du Colombier devbwrite,
481*45e6af3bSDavid du Colombier devremove,
482*45e6af3bSDavid du Colombier devwstat,
483*45e6af3bSDavid du Colombier };
484