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