Home | History | Annotate | Line # | Download | only in iomd
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