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 64BEGIN { 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 170END { 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# 292function 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# 307function mod(a) { 308 if (a < 0) 309 return -a; 310 return a; 311} 312