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