xref: /plan9/sys/src/cmd/aux/vga/main.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1*219b2ee8SDavid du Colombier #include <u.h>
2*219b2ee8SDavid du Colombier #include <libc.h>
3*219b2ee8SDavid du Colombier 
4*219b2ee8SDavid du Colombier #include "vga.h"
5*219b2ee8SDavid du Colombier 
6*219b2ee8SDavid du Colombier static int iflag, lflag, pflag;
7*219b2ee8SDavid du Colombier static char *usage = "usage: %s [ -cdfilmpv ] [ mode ]\n";
8*219b2ee8SDavid du Colombier 
9*219b2ee8SDavid du Colombier static char *dbname = "/lib/vgadb";
10*219b2ee8SDavid du Colombier static char monitordb[128];
11*219b2ee8SDavid du Colombier 
12*219b2ee8SDavid du Colombier static void
13*219b2ee8SDavid du Colombier dump(Vga *vga)
14*219b2ee8SDavid du Colombier {
15*219b2ee8SDavid du Colombier 	Ctlr *ctlr;
16*219b2ee8SDavid du Colombier 
17*219b2ee8SDavid du Colombier 	if(vga->mode)
18*219b2ee8SDavid du Colombier 		dbdumpmode(vga->mode);
19*219b2ee8SDavid du Colombier 
20*219b2ee8SDavid du Colombier 	for(ctlr = vga->link; ctlr; ctlr = ctlr->link){
21*219b2ee8SDavid du Colombier 		if(ctlr->dump == 0)
22*219b2ee8SDavid du Colombier 			continue;
23*219b2ee8SDavid du Colombier 
24*219b2ee8SDavid du Colombier 		verbose("%s->dump\n", ctlr->name);
25*219b2ee8SDavid du Colombier 		if(ctlr->flag && ctlr->flag != Fsnarf){
26*219b2ee8SDavid du Colombier 			printitem(ctlr->name, "flag");
27*219b2ee8SDavid du Colombier 			print("%9luX\n", ctlr->flag);
28*219b2ee8SDavid du Colombier 		}
29*219b2ee8SDavid du Colombier 		(*ctlr->dump)(vga, ctlr);
30*219b2ee8SDavid du Colombier 		ctlr->flag |= Fdump;
31*219b2ee8SDavid du Colombier 	}
32*219b2ee8SDavid du Colombier 	print("\n");
33*219b2ee8SDavid du Colombier }
34*219b2ee8SDavid du Colombier 
35*219b2ee8SDavid du Colombier void
36*219b2ee8SDavid du Colombier resyncinit(Vga *vga, Ctlr *ctlr, ulong on, ulong off)
37*219b2ee8SDavid du Colombier {
38*219b2ee8SDavid du Colombier 	Ctlr *link;
39*219b2ee8SDavid du Colombier 
40*219b2ee8SDavid du Colombier 	verbose("%s->resyncinit\n", ctlr->name);
41*219b2ee8SDavid du Colombier 
42*219b2ee8SDavid du Colombier 	for(link = vga->link; link; link = link->link){
43*219b2ee8SDavid du Colombier 		link->flag |= on;
44*219b2ee8SDavid du Colombier 		link->flag &= ~off;
45*219b2ee8SDavid du Colombier 		if(link == ctlr)
46*219b2ee8SDavid du Colombier 			continue;
47*219b2ee8SDavid du Colombier 
48*219b2ee8SDavid du Colombier 		if(link->init == 0 || (link->flag & Finit) == 0)
49*219b2ee8SDavid du Colombier 			continue;
50*219b2ee8SDavid du Colombier 		link->flag &= ~Finit;
51*219b2ee8SDavid du Colombier 		(*link->init)(vga, link);
52*219b2ee8SDavid du Colombier 	}
53*219b2ee8SDavid du Colombier }
54*219b2ee8SDavid du Colombier 
55*219b2ee8SDavid du Colombier void
56*219b2ee8SDavid du Colombier sequencer(Vga *vga, int on)
57*219b2ee8SDavid du Colombier {
58*219b2ee8SDavid du Colombier 	static uchar seq01;
59*219b2ee8SDavid du Colombier 
60*219b2ee8SDavid du Colombier 	verbose("+sequencer %d\n", on);
61*219b2ee8SDavid du Colombier 	if(on){
62*219b2ee8SDavid du Colombier 		if(vga)
63*219b2ee8SDavid du Colombier 			seq01 = vga->sequencer[0x01];
64*219b2ee8SDavid du Colombier 		seq01 |= 0x01;
65*219b2ee8SDavid du Colombier 		vgaxo(Seqx, 0x01, seq01);
66*219b2ee8SDavid du Colombier 		vgaxo(Seqx, 0x00, 0x03);
67*219b2ee8SDavid du Colombier 	}
68*219b2ee8SDavid du Colombier 	else{
69*219b2ee8SDavid du Colombier 		vgaxo(Seqx, 0x00, 0x01);
70*219b2ee8SDavid du Colombier 		seq01 = vgaxi(Seqx, 0x01);
71*219b2ee8SDavid du Colombier 		vgaxo(Seqx, 0x01, seq01|0x20);
72*219b2ee8SDavid du Colombier 	}
73*219b2ee8SDavid du Colombier 	verbose("-sequencer %d\n", on);
74*219b2ee8SDavid du Colombier }
75*219b2ee8SDavid du Colombier 
76*219b2ee8SDavid du Colombier void
77*219b2ee8SDavid du Colombier main(int argc, char *argv[])
78*219b2ee8SDavid du Colombier {
79*219b2ee8SDavid du Colombier 	char *size, *type, name[NAMELEN+1], *p;
80*219b2ee8SDavid du Colombier 	Ctlr *ctlr;
81*219b2ee8SDavid du Colombier 	Vga *vga;
82*219b2ee8SDavid du Colombier 
83*219b2ee8SDavid du Colombier 	if((type = getenv("monitor")) == 0)
84*219b2ee8SDavid du Colombier 		type = "vga";
85*219b2ee8SDavid du Colombier 	size = "640x480x1";
86*219b2ee8SDavid du Colombier 
87*219b2ee8SDavid du Colombier 	ARGBEGIN{
88*219b2ee8SDavid du Colombier 
89*219b2ee8SDavid du Colombier 	case 'c':
90*219b2ee8SDavid du Colombier 		cflag = 1;
91*219b2ee8SDavid du Colombier 		break;
92*219b2ee8SDavid du Colombier 
93*219b2ee8SDavid du Colombier 	case 'd':
94*219b2ee8SDavid du Colombier 		dflag = 1;
95*219b2ee8SDavid du Colombier 		break;
96*219b2ee8SDavid du Colombier 
97*219b2ee8SDavid du Colombier 	case 'i':
98*219b2ee8SDavid du Colombier 		iflag = 1;
99*219b2ee8SDavid du Colombier 		break;
100*219b2ee8SDavid du Colombier 
101*219b2ee8SDavid du Colombier 	case 'l':
102*219b2ee8SDavid du Colombier 		lflag = 1;
103*219b2ee8SDavid du Colombier 		break;
104*219b2ee8SDavid du Colombier 
105*219b2ee8SDavid du Colombier 	case 'm':
106*219b2ee8SDavid du Colombier 		type = ARGF();
107*219b2ee8SDavid du Colombier 		break;
108*219b2ee8SDavid du Colombier 
109*219b2ee8SDavid du Colombier 	case 'p':
110*219b2ee8SDavid du Colombier 		pflag = 1;
111*219b2ee8SDavid du Colombier 		break;
112*219b2ee8SDavid du Colombier 
113*219b2ee8SDavid du Colombier 	case 'v':
114*219b2ee8SDavid du Colombier 		vflag = 1;
115*219b2ee8SDavid du Colombier 		break;
116*219b2ee8SDavid du Colombier 
117*219b2ee8SDavid du Colombier 	default:
118*219b2ee8SDavid du Colombier 		error(usage, argv0);
119*219b2ee8SDavid du Colombier 
120*219b2ee8SDavid du Colombier 	}ARGEND
121*219b2ee8SDavid du Colombier 
122*219b2ee8SDavid du Colombier 	vga = alloc(sizeof(Vga));
123*219b2ee8SDavid du Colombier 
124*219b2ee8SDavid du Colombier 	/*
125*219b2ee8SDavid du Colombier 	 * Try to identify the VGA card and grab
126*219b2ee8SDavid du Colombier 	 * registers. Print them out if requested.
127*219b2ee8SDavid du Colombier 	 */
128*219b2ee8SDavid du Colombier 	if(dbctlr(dbname, vga) == 0){
129*219b2ee8SDavid du Colombier 		print("controller not in %s\n", dbname);
130*219b2ee8SDavid du Colombier 		dumpbios();
131*219b2ee8SDavid du Colombier 		type = "vga";
132*219b2ee8SDavid du Colombier 		size = "640x480x1";
133*219b2ee8SDavid du Colombier 		vga->ctlr = &generic;
134*219b2ee8SDavid du Colombier 		vga->link = &generic;
135*219b2ee8SDavid du Colombier 	}
136*219b2ee8SDavid du Colombier 
137*219b2ee8SDavid du Colombier 	for(ctlr = vga->link; ctlr; ctlr = ctlr->link){
138*219b2ee8SDavid du Colombier 		if(ctlr->snarf == 0)
139*219b2ee8SDavid du Colombier 			continue;
140*219b2ee8SDavid du Colombier 		(*ctlr->snarf)(vga, ctlr);
141*219b2ee8SDavid du Colombier 	}
142*219b2ee8SDavid du Colombier 
143*219b2ee8SDavid du Colombier 	if(pflag)
144*219b2ee8SDavid du Colombier 		dump(vga);
145*219b2ee8SDavid du Colombier 
146*219b2ee8SDavid du Colombier 	if(iflag || lflag){
147*219b2ee8SDavid du Colombier 		if(getenv(type))
148*219b2ee8SDavid du Colombier 			sprint(monitordb, "/env/%s", type);
149*219b2ee8SDavid du Colombier 		else
150*219b2ee8SDavid du Colombier 			strcpy(monitordb, dbname);
151*219b2ee8SDavid du Colombier 		if(argc)
152*219b2ee8SDavid du Colombier 			size = *argv;
153*219b2ee8SDavid du Colombier 
154*219b2ee8SDavid du Colombier 		if((vga->mode = dbmode(monitordb, type, size)) == 0)
155*219b2ee8SDavid du Colombier 			error("%s@%s not in %s\n", type, size, monitordb);
156*219b2ee8SDavid du Colombier 
157*219b2ee8SDavid du Colombier 		for(ctlr = vga->link; ctlr; ctlr = ctlr->link){
158*219b2ee8SDavid du Colombier 			if(ctlr->options == 0)
159*219b2ee8SDavid du Colombier 				continue;
160*219b2ee8SDavid du Colombier 			(*ctlr->options)(vga, ctlr);
161*219b2ee8SDavid du Colombier 		}
162*219b2ee8SDavid du Colombier 
163*219b2ee8SDavid du Colombier 		for(ctlr = vga->link; ctlr; ctlr = ctlr->link){
164*219b2ee8SDavid du Colombier 			if(ctlr->init == 0)
165*219b2ee8SDavid du Colombier 				continue;
166*219b2ee8SDavid du Colombier 			(*ctlr->init)(vga, ctlr);
167*219b2ee8SDavid du Colombier 		}
168*219b2ee8SDavid du Colombier 
169*219b2ee8SDavid du Colombier 		if(iflag || pflag)
170*219b2ee8SDavid du Colombier 			dump(vga);
171*219b2ee8SDavid du Colombier 
172*219b2ee8SDavid du Colombier 		if(lflag){
173*219b2ee8SDavid du Colombier 			verbose("load\n");
174*219b2ee8SDavid du Colombier 			if(vga->vmb && (vga->mode->x*vga->mode->y*vga->mode->z/8 > vga->vmb))
175*219b2ee8SDavid du Colombier 				error("%s: not enough video memory - %lud\n",
176*219b2ee8SDavid du Colombier 					ctlr->name, vga->vmb);
177*219b2ee8SDavid du Colombier 
178*219b2ee8SDavid du Colombier 			/*
179*219b2ee8SDavid du Colombier 			 * Turn off the display during the load.
180*219b2ee8SDavid du Colombier 			 */
181*219b2ee8SDavid du Colombier 			sequencer(vga, 0);
182*219b2ee8SDavid du Colombier 
183*219b2ee8SDavid du Colombier 			if(vga->ctlr->type)
184*219b2ee8SDavid du Colombier 				vgactlw("type", vga->ctlr->type);
185*219b2ee8SDavid du Colombier 			else if(p = strchr(vga->ctlr->name, '-')){
186*219b2ee8SDavid du Colombier 				strncpy(name, vga->ctlr->name, p - vga->ctlr->name);
187*219b2ee8SDavid du Colombier 				name[p - vga->ctlr->name] = 0;
188*219b2ee8SDavid du Colombier 				vgactlw("type", name);
189*219b2ee8SDavid du Colombier 			}
190*219b2ee8SDavid du Colombier 			else
191*219b2ee8SDavid du Colombier 				vgactlw("type", vga->ctlr->name);
192*219b2ee8SDavid du Colombier 
193*219b2ee8SDavid du Colombier 			vgactlw("size", vga->mode->size);
194*219b2ee8SDavid du Colombier 
195*219b2ee8SDavid du Colombier 			for(ctlr = vga->link; ctlr; ctlr = ctlr->link){
196*219b2ee8SDavid du Colombier 				if(ctlr->load == 0)
197*219b2ee8SDavid du Colombier 					continue;
198*219b2ee8SDavid du Colombier 				(*ctlr->load)(vga, ctlr);
199*219b2ee8SDavid du Colombier 			}
200*219b2ee8SDavid du Colombier 			sequencer(vga, 1);
201*219b2ee8SDavid du Colombier 
202*219b2ee8SDavid du Colombier 			if(vga->hwgc == 0 || cflag)
203*219b2ee8SDavid du Colombier 				vgactlw("hwgc", "off");
204*219b2ee8SDavid du Colombier 			else
205*219b2ee8SDavid du Colombier 				vgactlw("hwgc", vga->hwgc->name);
206*219b2ee8SDavid du Colombier 
207*219b2ee8SDavid du Colombier 			if(pflag)
208*219b2ee8SDavid du Colombier 				dump(vga);
209*219b2ee8SDavid du Colombier 		}
210*219b2ee8SDavid du Colombier 	}
211*219b2ee8SDavid du Colombier 
212*219b2ee8SDavid du Colombier 	verbose("exits\n");
213*219b2ee8SDavid du Colombier 	exits(0);
214*219b2ee8SDavid du Colombier }
215