Home | History | Annotate | Line # | Download | only in iomd
makemodes.awk revision 1.4
      1 #	$NetBSD: makemodes.awk,v 1.4 2006/08/17 22:33:59 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 *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("struct vidc_mode vidcmodes[] = {\n");
    199 
    200 	# Loop round all the modespecs on the command line
    201 	for (res = 2; res < realargc; res = res + 1) {
    202 		pos = -1;
    203 		found = -1;
    204 		closest = 200;
    205 
    206 		# Report the mode specifier being processed
    207 		printf("%s ==> ", ARGV[res]) | "cat 1>&2";
    208 
    209 		# Pull apart the modespec
    210 		args = split(ARGV[res], modespec, ",");
    211 
    212 		# We need at least 2 arguments
    213 		if (args < 2) {
    214 			printf("Invalid mode specifier\n") | "cat 1>&2";
    215 			continue;
    216 		}
    217 
    218 		# If we only have x,y default c and f
    219 		if (args == 2) {
    220 			modespec[3] = 256;
    221 			modespec[4] = -1;
    222 		}
    223 		# If we have x,y,f default c and re-arrange.
    224 		if (args == 3) {
    225 			modespec[4] = modespec[3];
    226 			modespec[3] = 256;
    227 		}
    228 
    229 		# Report the full mode specifier
    230 		printf("%d x %d x %d x %d : ", modespec[1], modespec[2],
    231 		    modespec[3], modespec[4]) | "cat 1>&2";
    232 
    233 		# Now loop round all the modes we parsed and find the matches
    234 		for (loop = 0; loop < mode; loop = loop + 1) {
    235 			# Match X & Y
    236 			if (modespec[1] != modes[loop, 1]) continue;
    237 			if (modespec[2] != modes[loop, 2]) continue;
    238 
    239 			# Split the horizontal and vertical timings
    240 			# This is needed for the frame rate calculation
    241 			ht = split(modes[loop, 4], htimings, ",");
    242 			if (ht != 6) continue;
    243 			vt = split(modes[loop, 5], vtimings, ",");
    244 			if (vt != 6) continue;
    245 
    246 			# Calculate the frame rate
    247 			fr = modes[loop, 3] / (htimings[1] + htimings[2] + \
    248 			    htimings[3] + htimings[4] + htimings[5] + \
    249 			    htimings[6]) / ( vtimings[1] + vtimings[2] + \
    250 			    vtimings[3] + vtimings[4] + vtimings[5] + \
    251 			    vtimings[6]);
    252 			fr = fr * 1000;
    253 
    254 			# Remember the frame rate
    255 			modes[loop, 7] = int(fr + 0.5);
    256 
    257 			# Create the internal version of the timings
    258 			modes[loop, "timings"] = \
    259 			    sprintf( \
    260 			    "{ %d, %d,%d,%d,%d, %d,%d,%d,%d, %s, \"%s\" }",\
    261 			    modes[loop, 3], htimings[4], \
    262 			    htimings[4] + htimings[5] + htimings[6], \
    263 			    htimings[4] + htimings[5] + htimings[6] + \
    264 			    htimings[1], \
    265 			    htimings[4] + htimings[5] + htimings[6] + \
    266 			    htimings[1] + htimings[2] + htimings[3], \
    267 			    vtimings[4], \
    268 			    vtimings[4] + vtimings[5] + vtimings[6], \
    269 			    vtimings[4] + vtimings[5] + vtimings[6] + \
    270 			    vtimings[1], \
    271 			    vtimings[4] + vtimings[5] + vtimings[6] + \
    272 			    vtimings[1] + vtimings[2] + vtimings[3], \
    273 			    pol[modes[loop, 6]], modes[loop, 0]);
    274 
    275 			# Report the frame rate
    276 			printf("%d ", modes[loop, 7]) | "cat 1>&2";
    277 
    278 			# Is this the closest
    279 			if (closest > mod(modes[loop, 7] - modespec[4])) {
    280 				closest = mod(modes[loop, 7] - modespec[4]);
    281 				pos = loop;
    282 			}
    283 
    284 			# Do we have an exact match ?
    285 			if (modes[loop, 7] == modespec[4])
    286 				found = pos;
    287 		}
    288 
    289 		# If no exact match use the nearest
    290 		if (found == -1)
    291 			found = pos;
    292 
    293 		# Did we find any sort of match ?
    294 		if (found == -1) {
    295 			printf("Cannot find mode") | "cat 1>&2";
    296 			continue;
    297 		}
    298 
    299 		# Report the frame rate matched
    300 		printf("- %d", modes[found, 7]) | "cat 1>&2";
    301 
    302 		# Output the mode as part of the mode definition array
    303 		printf("\t{ %s,\n\t  %d, %d },\n",
    304 		    modes[found, "timings"], cdepth(modespec[3]),
    305 		    modes[found, 7]);
    306 
    307 		printf("\n") | "cat 1>&2";
    308 	}
    309 
    310 	# Add a terminating entry and close the array.
    311 	printf("\t{ { 0 } }\n");
    312 	printf("};\n");
    313 }
    314 
    315 #
    316 # cdepth() function
    317 #
    318 # This returns the colour depth as a power of 2 + 1
    319 #
    320 function cdepth(depth) {
    321 	if (depth == 16)
    322 		return 5;
    323 	if (depth == 256)
    324 		return 9;
    325 	if (depth == 32768)
    326 		return 16;
    327 	if (depth == 65536)
    328 		return 17;
    329 	return 9;
    330 }
    331 
    332 #
    333 # Simple mod() function
    334 #
    335 function mod(a) {
    336 	if (a < 0)
    337 		return -a;
    338 	return a;
    339 }
    340