Home | History | Annotate | Line # | Download | only in iomd
      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 
     57 BEGIN {
     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 
    169 END {
    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 #
    311 function mod(a) {
    312 	if (a < 0)
    313 		return -a;
    314 	return a;
    315 }
    316