makemodes.awk revision 1.6 1 # $NetBSD: makemodes.awk,v 1.6 2006/08/19 11:01:56 bjh21 Exp $
2
3 #
4 # Copyright (c) 1998 The NetBSD Foundation, Inc.
5 # All rights reserved.
6 #
7 # This code is derived from software contributed to The NetBSD Foundation
8 # by Mark Brinicombe
9 #
10 # Redistribution and use in source and binary forms, with or without
11 # modification, are permitted provided that the following conditions
12 # are met:
13 # 1. Redistributions of source code must retain the above copyright
14 # notice, this list of conditions and the following disclaimer.
15 # 2. Redistributions in binary form must reproduce the above copyright
16 # notice, this list of conditions and the following disclaimer in the
17 # documentation and/or other materials provided with the distribution.
18 # 3. All advertising materials mentioning features or use of this software
19 # must display the following acknowledgement:
20 # This product includes software developed by the NetBSD
21 # Foundation, Inc. and its contributors.
22 # 4. Neither the name of The NetBSD Foundation nor the names of its
23 # contributors may be used to endorse or promote products derived
24 # from this software without specific prior written permission.
25 #
26 # THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 # POSSIBILITY OF SUCH DAMAGE.
37 #
38
39 # This parses a Acorn monitor definition file and constructs an array of
40 # parameters for each mode.
41 # Once the file has been parsed the list of modes is examined to find modes
42 # that match the mode specifications specified on the command line.
43 # The matching mode definitions are written to stdout in the form of a C file.
44 # Parsing information is written to stderr.
45 #
46 #
47 # Syntax for using this program
48 #
49 # awk -f makemodes.awk <MDF file> <mode spec> [<mode spec> ...]
50 #
51 # where <mode spec> is
52 # <x>,<y>
53 # <x>,<y>,<f>
54 # <x>,<y>,<c>,<f>
55 #
56 # Note: Spaces are NOT allowed in a mode specifier
57 #
58 # where x = x resolution
59 # y = y resolution
60 # f = frame rate
61 # c = colour depth (16, 256, 32768, 65536)
62 #
63
64 BEGIN {
65 # Number of modes parsed and valid in the modes array.
66 mode = 0;
67
68 # MDF file globals
69 monitor = "";
70 dpms = 0;
71
72 # Non zero if we are translating a mode
73 translate = 0;
74
75 # ':' character is used to separate the tokens.
76 FS=":";
77
78 # Note the real number of arguments and truncate ARGC so that only the first
79 # argument is used as a filename.
80 realargc = ARGC;
81 ARGC=2;
82
83 # Translation of sync_pol to videomode.flags
84 pol[0] = "HP|VP";
85 pol[1] = "HN|VP";
86 pol[2] = "HP|VN";
87 pol[3] = "HN|VN";
88 }
89
90 # MDF File format
91 /^file_format/ {
92 # Currently we only understand format 1 MDF files
93 if ($2 != 1) {
94 printf("Unrecognised MDF format (%d)\n", $2);
95 exit;
96 }
97 }
98
99 # Monitor name
100 /^monitor_title/ {
101 monitor = $2;
102 }
103
104 # Monitor DPMS state
105 /^DPMS_state/ {
106 dpms = $2;
107 }
108
109 # Start of mode definition
110 /^startmode/ {
111 translate = 1;
112 }
113
114 # End of mode definition
115 /^endmode/ {
116 translate = 0;
117 mode = mode + 1;
118 }
119
120 # The mode definition name (only valid within startmode/endmode section)
121 /^mode_name:/ {
122 if (!translate)
123 next;
124 modes[mode, 0] = $2;
125 next;
126 }
127
128 # The horizontal resolution (only valid within startmode/endmode section)
129 /^x_res:/ {
130 if (!translate)
131 next;
132 modes[mode, 1] = $2;
133 next;
134 }
135
136 # The vertical resolution (only valid within startmode/endmode section)
137 /^y_res:/ {
138 if (!translate)
139 next;
140 modes[mode, 2] = $2;
141 next;
142 }
143
144 # The pixel rate (only valid within startmode/endmode section)
145 /^pixel_rate:/ {
146 if (!translate)
147 next;
148 modes[mode, 3] = $2;
149 next;
150 }
151
152 # The horizontal timings (only valid within startmode/endmode section)
153 /^h_timings:/ {
154 if (!translate)
155 next;
156 modes[mode, 4] = $2;
157 next;
158 }
159
160 # The vertical timings (only valid within startmode/endmode section)
161 /^v_timings:/ {
162 if (!translate)
163 next;
164 modes[mode, 5] = $2;
165 next;
166 }
167
168 # The sync polarity (only valid within startmode/endmode section)
169 /^sync_pol:/ {
170 if (!translate)
171 next;
172 modes[mode, 6] = $2;
173 next;
174 }
175
176 END {
177 #
178 # Now generate the C file
179 #
180
181 # Create the file header
182 printf("/*\n");
183 printf(" * MACHINE GENERATED: DO NOT EDIT\n");
184 printf(" *\n");
185 printf(" * Created from %s\n", FILENAME);
186 printf(" */\n\n");
187 printf("#include <sys/types.h>\n");
188 printf("#include <arm/iomd/vidc.h>\n\n");
189 printf("const char * const monitor = \"%s\";\n", monitor);
190 printf("const int dpms = %d;\n", dpms);
191 printf("#define HP VID_PHSYNC\n");
192 printf("#define HN VID_NHSYNC\n");
193 printf("#define VP VID_PVSYNC\n");
194 printf("#define VN VID_NVSYNC\n");
195 printf("\n");
196
197 # Now define the modes array
198 printf("const struct videomode vidc_videomode_list[] = {\n");
199 nmodes = 0
200
201 # Loop round all the modespecs on the command line
202 for (res = 2; res < realargc; res = res + 1) {
203 pos = -1;
204 found = -1;
205 closest = 200;
206
207 # Report the mode specifier being processed
208 printf("%s ==> ", ARGV[res]) | "cat 1>&2";
209
210 # Pull apart the modespec
211 args = split(ARGV[res], modespec, ",");
212
213 # We need at least 2 arguments
214 if (args < 2) {
215 printf("Invalid mode specifier\n") | "cat 1>&2";
216 continue;
217 }
218
219 # If we only have x,y default c and f
220 if (args == 2) {
221 modespec[3] = 256;
222 modespec[4] = -1;
223 }
224 # If we have x,y,f default c and re-arrange.
225 if (args == 3) {
226 modespec[4] = modespec[3];
227 modespec[3] = 256;
228 }
229
230 # Report the full mode specifier
231 printf("%d x %d x %d x %d : ", modespec[1], modespec[2],
232 modespec[3], modespec[4]) | "cat 1>&2";
233
234 # Now loop round all the modes we parsed and find the matches
235 for (loop = 0; loop < mode; loop = loop + 1) {
236 # Match X & Y
237 if (modespec[1] != modes[loop, 1]) continue;
238 if (modespec[2] != modes[loop, 2]) continue;
239
240 # Split the horizontal and vertical timings
241 # This is needed for the frame rate calculation
242 ht = split(modes[loop, 4], htimings, ",");
243 if (ht != 6) continue;
244 vt = split(modes[loop, 5], vtimings, ",");
245 if (vt != 6) continue;
246
247 # Calculate the frame rate
248 fr = modes[loop, 3] / (htimings[1] + htimings[2] + \
249 htimings[3] + htimings[4] + htimings[5] + \
250 htimings[6]) / ( vtimings[1] + vtimings[2] + \
251 vtimings[3] + vtimings[4] + vtimings[5] + \
252 vtimings[6]);
253 fr = fr * 1000;
254
255 # Remember the frame rate
256 modes[loop, 7] = int(fr + 0.5);
257
258 # Create the internal version of the timings
259 modes[loop, "timings"] = \
260 sprintf( \
261 "{ %d, %d,%d,%d,%d, %d,%d,%d,%d, %s, \"%s\" }",\
262 modes[loop, 3], htimings[4], \
263 htimings[4] + htimings[5] + htimings[6], \
264 htimings[4] + htimings[5] + htimings[6] + \
265 htimings[1], \
266 htimings[4] + htimings[5] + htimings[6] + \
267 htimings[1] + htimings[2] + htimings[3], \
268 vtimings[4], \
269 vtimings[4] + vtimings[5] + vtimings[6], \
270 vtimings[4] + vtimings[5] + vtimings[6] + \
271 vtimings[1], \
272 vtimings[4] + vtimings[5] + vtimings[6] + \
273 vtimings[1] + vtimings[2] + vtimings[3], \
274 pol[modes[loop, 6]], modes[loop, 0]);
275
276 # Report the frame rate
277 printf("%d ", modes[loop, 7]) | "cat 1>&2";
278
279 # Is this the closest
280 if (closest > mod(modes[loop, 7] - modespec[4])) {
281 closest = mod(modes[loop, 7] - modespec[4]);
282 pos = loop;
283 }
284
285 # Do we have an exact match ?
286 if (modes[loop, 7] == modespec[4])
287 found = pos;
288 }
289
290 # If no exact match use the nearest
291 if (found == -1)
292 found = pos;
293
294 # Did we find any sort of match ?
295 if (found == -1) {
296 printf("Cannot find mode") | "cat 1>&2";
297 continue;
298 }
299
300 # Report the frame rate matched
301 printf("- %d", modes[found, 7]) | "cat 1>&2";
302
303 # Output the mode as part of the mode definition array
304 printf("\t%s,\n", modes[found, "timings"]);
305
306 printf("\n") | "cat 1>&2";
307 nmodes++;
308 }
309
310 # Close the array.
311 printf("};\n\n");
312 printf("const int vidc_videomode_count = %d;\n", nmodes);
313 }
314
315 #
316 # Simple mod() function
317 #
318 function mod(a) {
319 if (a < 0)
320 return -a;
321 return a;
322 }
323