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