makemodes.awk revision 1.1 1 # $NetBSD: makemodes.awk,v 1.1 2001/10/05 22:27:41 reinoud 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
84 # MDF File format
85 /^file_format/ {
86 # Currently we only understand format 1 MDF files
87 if ($2 != 1) {
88 printf("Unrecognised MDF format (%d)\n", $2);
89 exit;
90 }
91 }
92
93 # Monitor name
94 /^monitor_title/ {
95 monitor = $2;
96 }
97
98 # Monitor DPMS state
99 /^DPMS_state/ {
100 dpms = $2;
101 }
102
103 # Start of mode definition
104 /^startmode/ {
105 translate = 1;
106 }
107
108 # End of mode definition
109 /^endmode/ {
110 translate = 0;
111 mode = mode + 1;
112 }
113
114 # The mode definition name (only valid within startmode/endmode section)
115 /^mode_name:/ {
116 if (!translate)
117 next;
118 modes[mode, 0] = $2;
119 next;
120 }
121
122 # The horizontal resolution (only valid within startmode/endmode section)
123 /^x_res:/ {
124 if (!translate)
125 next;
126 modes[mode, 1] = $2;
127 next;
128 }
129
130 # The vertical resolution (only valid within startmode/endmode section)
131 /^y_res:/ {
132 if (!translate)
133 next;
134 modes[mode, 2] = $2;
135 next;
136 }
137
138 # The pixel rate (only valid within startmode/endmode section)
139 /^pixel_rate:/ {
140 if (!translate)
141 next;
142 modes[mode, 3] = $2;
143 next;
144 }
145
146 # The horizontal timings (only valid within startmode/endmode section)
147 /^h_timings:/ {
148 if (!translate)
149 next;
150 modes[mode, 4] = $2;
151 next;
152 }
153
154 # The vertical timings (only valid within startmode/endmode section)
155 /^v_timings:/ {
156 if (!translate)
157 next;
158 modes[mode, 5] = $2;
159 next;
160 }
161
162 # The sync polarity (only valid within startmode/endmode section)
163 /^sync_pol:/ {
164 if (!translate)
165 next;
166 modes[mode, 6] = $2;
167 next;
168 }
169
170 END {
171 #
172 # Now generate the C file
173 #
174
175 # Create the file header
176 printf("/*\n");
177 printf(" * MACHINE GENERATED: DO NOT EDIT\n");
178 printf(" *\n");
179 printf(" * Created from %s\n", FILENAME);
180 printf(" */\n\n");
181 printf("#include <sys/types.h>\n");
182 printf("#include <arm/iomd/vidc.h>\n\n");
183 printf("const char *monitor = \"%s\";\n", monitor);
184 printf("const int dpms = %d;\n", dpms);
185 printf("\n");
186
187 # Now define the modes array
188 printf("struct vidc_mode vidcmodes[] = {\n");
189
190 # Loop round all the modespecs on the command line
191 for (res = 2; res < realargc; res = res + 1) {
192 pos = -1;
193 found = -1;
194 closest = 200;
195
196 # Report the mode specifier being processed
197 printf("%s ==> ", ARGV[res]) > "/dev/stderr";
198
199 # Pull apart the modespec
200 args = split(ARGV[res], modespec, ",");
201
202 # We need at least 2 arguments
203 if (args < 2) {
204 printf("Invalid mode specifier\n") > "/dev/stderr";
205 continue;
206 }
207
208 # If we only have x,y default c and f
209 if (args == 2) {
210 modespec[3] = 256;
211 modespec[4] = -1;
212 }
213 # If we have x,y,f default c and re-arrange.
214 if (args == 3) {
215 modespec[4] = modespec[3];
216 modespec[3] = 256;
217 }
218
219 # Report the full mode specifier
220 printf("%d x %d x %d x %d : ", modespec[1], modespec[2],
221 modespec[3], modespec[4]) > "/dev/stderr";
222
223 # Now loop round all the modes we parsed and find the matches
224 for (loop = 0; loop < mode; loop = loop + 1) {
225 # Match X & Y
226 if (modespec[1] != modes[loop, 1]) continue;
227 if (modespec[2] != modes[loop, 2]) continue;
228
229 # Split the horizontal and vertical timings
230 # This is needed for the frame rate calculation
231 ht = split(modes[loop, 4], htimings, ",");
232 if (ht != 6) continue;
233 vt = split(modes[loop, 5], vtimings, ",");
234 if (vt != 6) continue;
235
236 # Calculate the frame rate
237 fr = modes[loop, 3] / (htimings[1] + htimings[2] + \
238 htimings[3] + htimings[4] + htimings[5] + \
239 htimings[6]) / ( vtimings[1] + vtimings[2] + \
240 vtimings[3] + vtimings[4] + vtimings[5] + \
241 vtimgings[6]);
242 fr = fr * 1000;
243
244 # Remember the frame rate
245 modes[loop, 7] = int(fr + 0.5);
246
247 # Report the frame rate
248 printf("%d ", modes[loop, 7]) > "/dev/stderr";
249
250 # Is this the closest
251 if (closest > mod(modes[loop, 7] - modespec[4])) {
252 closest = mod(modes[loop, 7] - modespec[4]);
253 pos = loop;
254 }
255
256 # Do we have an exact match ?
257 if (modes[loop, 7] == modespec[4])
258 found = pos;
259 }
260
261 # If no exact match use the nearest
262 if (found == -1)
263 found = pos;
264
265 # Did we find any sort of match ?
266 if (found == -1) {
267 printf("Cannot find mode") > "/dev/stderr";
268 continue;
269 }
270
271 # Report the frame rate matched
272 printf("- %d", modes[found, 7]) > "/dev/stderr";
273
274 # Output the mode as part of the mode definition array
275 printf("\t{ %6d, %22s, %22s, %d, %d, %d },\n",
276 modes[found, 3], modes[found, 4], modes[found, 5],
277 cdepth(modespec[3]), modes[found, 6], modes[found, 7]);
278
279 printf("\n") > "/dev/stderr";
280 }
281
282 # Add a terminating entry and close the array.
283 printf("\t{ 0 }\n");
284 printf("};\n");
285 }
286
287 #
288 # cdepth() function
289 #
290 # This returns the colour depth as a power of 2 + 1
291 #
292 function cdepth(depth) {
293 if (depth == 16)
294 return 5;
295 if (depth == 256)
296 return 9;
297 if (depth == 32768)
298 return 16;
299 if (depth == 65536)
300 return 17;
301 return 9;
302 }
303
304 #
305 # Simple mod() function
306 #
307 function mod(a) {
308 if (a < 0)
309 return -a;
310 return a;
311 }
312