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 57BEGIN { 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 169END { 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# 311function mod(a) { 312 if (a < 0) 313 return -a; 314 return a; 315} 316