Home | History | Annotate | Line # | Download | only in iomd
makemodes.awk revision 1.1
      1  1.1  reinoud #	$NetBSD: makemodes.awk,v 1.1 2001/10/05 22:27:41 reinoud Exp $
      2  1.1  reinoud 
      3  1.1  reinoud #
      4  1.1  reinoud # Copyright (c) 1998 The NetBSD Foundation, Inc.
      5  1.1  reinoud # All rights reserved.
      6  1.1  reinoud #
      7  1.1  reinoud # This code is derived from software contributed to The NetBSD Foundation
      8  1.1  reinoud # by Mark Brinicombe
      9  1.1  reinoud #
     10  1.1  reinoud # Redistribution and use in source and binary forms, with or without
     11  1.1  reinoud # modification, are permitted provided that the following conditions
     12  1.1  reinoud # are met:
     13  1.1  reinoud # 1. Redistributions of source code must retain the above copyright
     14  1.1  reinoud #    notice, this list of conditions and the following disclaimer.
     15  1.1  reinoud # 2. Redistributions in binary form must reproduce the above copyright
     16  1.1  reinoud #    notice, this list of conditions and the following disclaimer in the
     17  1.1  reinoud #    documentation and/or other materials provided with the distribution.
     18  1.1  reinoud # 3. All advertising materials mentioning features or use of this software
     19  1.1  reinoud #    must display the following acknowledgement:
     20  1.1  reinoud #        This product includes software developed by the NetBSD
     21  1.1  reinoud #        Foundation, Inc. and its contributors.
     22  1.1  reinoud # 4. Neither the name of The NetBSD Foundation nor the names of its
     23  1.1  reinoud #    contributors may be used to endorse or promote products derived
     24  1.1  reinoud #    from this software without specific prior written permission.
     25  1.1  reinoud #
     26  1.1  reinoud # THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     27  1.1  reinoud # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     28  1.1  reinoud # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     29  1.1  reinoud # PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     30  1.1  reinoud # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     31  1.1  reinoud # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     32  1.1  reinoud # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     33  1.1  reinoud # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     34  1.1  reinoud # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     35  1.1  reinoud # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     36  1.1  reinoud # POSSIBILITY OF SUCH DAMAGE.
     37  1.1  reinoud #
     38  1.1  reinoud 
     39  1.1  reinoud # This parses a Acorn monitor definition file and constructs an array of
     40  1.1  reinoud # parameters for each mode.
     41  1.1  reinoud # Once the file has been parsed the list of modes is examined to find modes
     42  1.1  reinoud # that match the mode specifications specified on the command line.
     43  1.1  reinoud # The matching mode definitions are written to stdout in the form of a C file.
     44  1.1  reinoud # Parsing information is written to stderr.
     45  1.1  reinoud #
     46  1.1  reinoud #
     47  1.1  reinoud # Syntax for using this program
     48  1.1  reinoud #
     49  1.1  reinoud # awk -f makemodes.awk <MDF file> <mode spec> [<mode spec> ...]
     50  1.1  reinoud #
     51  1.1  reinoud # where <mode spec> is
     52  1.1  reinoud #	<x>,<y>
     53  1.1  reinoud #	<x>,<y>,<f>
     54  1.1  reinoud #	<x>,<y>,<c>,<f>
     55  1.1  reinoud #
     56  1.1  reinoud # Note: Spaces are NOT allowed in a mode specifier
     57  1.1  reinoud #
     58  1.1  reinoud # where	x = x resolution
     59  1.1  reinoud #	y = y resolution
     60  1.1  reinoud #	f = frame rate
     61  1.1  reinoud #	c = colour depth (16, 256, 32768, 65536)
     62  1.1  reinoud #
     63  1.1  reinoud 
     64  1.1  reinoud BEGIN {
     65  1.1  reinoud 	# Number of modes parsed and valid in the modes array.
     66  1.1  reinoud 	mode = 0;
     67  1.1  reinoud 
     68  1.1  reinoud 	# MDF file globals
     69  1.1  reinoud 	monitor = "";
     70  1.1  reinoud 	dpms = 0;
     71  1.1  reinoud 
     72  1.1  reinoud 	# Non zero if we are translating a mode
     73  1.1  reinoud 	translate = 0;
     74  1.1  reinoud 
     75  1.1  reinoud 	# ':'  character is used to separate the tokens.
     76  1.1  reinoud 	FS=":";
     77  1.1  reinoud 
     78  1.1  reinoud 	# Note the real number of arguments and truncate ARGC so that only the first
     79  1.1  reinoud 	# argument is used as a filename.
     80  1.1  reinoud 	realargc = ARGC;
     81  1.1  reinoud 	ARGC=2;
     82  1.1  reinoud }
     83  1.1  reinoud 
     84  1.1  reinoud # MDF File format
     85  1.1  reinoud /^file_format/ {
     86  1.1  reinoud 	# Currently we only understand format 1 MDF files
     87  1.1  reinoud 	if ($2 != 1) {
     88  1.1  reinoud 		printf("Unrecognised MDF format (%d)\n", $2);
     89  1.1  reinoud 		exit;
     90  1.1  reinoud 	}
     91  1.1  reinoud }
     92  1.1  reinoud 
     93  1.1  reinoud # Monitor name
     94  1.1  reinoud /^monitor_title/ {
     95  1.1  reinoud 	monitor = $2;
     96  1.1  reinoud }
     97  1.1  reinoud 
     98  1.1  reinoud # Monitor DPMS state
     99  1.1  reinoud /^DPMS_state/ {
    100  1.1  reinoud 	dpms = $2;
    101  1.1  reinoud }
    102  1.1  reinoud 
    103  1.1  reinoud # Start of mode definition
    104  1.1  reinoud /^startmode/ {
    105  1.1  reinoud 	translate = 1;
    106  1.1  reinoud }
    107  1.1  reinoud 
    108  1.1  reinoud # End of mode definition
    109  1.1  reinoud /^endmode/ {
    110  1.1  reinoud 	translate = 0;
    111  1.1  reinoud 	mode = mode + 1;
    112  1.1  reinoud }
    113  1.1  reinoud 
    114  1.1  reinoud # The mode definition name (only valid within startmode/endmode section)
    115  1.1  reinoud /^mode_name:/ {
    116  1.1  reinoud 	if (!translate)
    117  1.1  reinoud 		next;
    118  1.1  reinoud 	modes[mode, 0] = $2;
    119  1.1  reinoud 	next;
    120  1.1  reinoud }
    121  1.1  reinoud 
    122  1.1  reinoud # The horizontal resolution (only valid within startmode/endmode section)
    123  1.1  reinoud /^x_res:/ {
    124  1.1  reinoud 	if (!translate)
    125  1.1  reinoud 		next;
    126  1.1  reinoud 	modes[mode, 1] = $2;
    127  1.1  reinoud 	next;
    128  1.1  reinoud }
    129  1.1  reinoud 
    130  1.1  reinoud # The vertical resolution (only valid within startmode/endmode section)
    131  1.1  reinoud /^y_res:/ {
    132  1.1  reinoud 	if (!translate)
    133  1.1  reinoud 		next;
    134  1.1  reinoud 	modes[mode, 2] = $2;
    135  1.1  reinoud 	next;
    136  1.1  reinoud }
    137  1.1  reinoud 
    138  1.1  reinoud # The pixel rate (only valid within startmode/endmode section)
    139  1.1  reinoud /^pixel_rate:/ {
    140  1.1  reinoud 	if (!translate)
    141  1.1  reinoud 		next;
    142  1.1  reinoud 	modes[mode, 3] = $2;
    143  1.1  reinoud 	next;
    144  1.1  reinoud }
    145  1.1  reinoud 
    146  1.1  reinoud # The horizontal timings (only valid within startmode/endmode section)
    147  1.1  reinoud /^h_timings:/ {
    148  1.1  reinoud 	if (!translate)
    149  1.1  reinoud 		next;
    150  1.1  reinoud 	modes[mode, 4] = $2;
    151  1.1  reinoud 	next;
    152  1.1  reinoud }
    153  1.1  reinoud 
    154  1.1  reinoud # The vertical timings (only valid within startmode/endmode section)
    155  1.1  reinoud /^v_timings:/ {
    156  1.1  reinoud 	if (!translate)
    157  1.1  reinoud 		next;
    158  1.1  reinoud 	modes[mode, 5] = $2;
    159  1.1  reinoud 	next;
    160  1.1  reinoud }
    161  1.1  reinoud 
    162  1.1  reinoud # The sync polarity (only valid within startmode/endmode section)
    163  1.1  reinoud /^sync_pol:/ {
    164  1.1  reinoud 	if (!translate)
    165  1.1  reinoud 		next;
    166  1.1  reinoud 	modes[mode, 6] = $2;
    167  1.1  reinoud 	next;
    168  1.1  reinoud }
    169  1.1  reinoud 
    170  1.1  reinoud END {
    171  1.1  reinoud 	#
    172  1.1  reinoud 	# Now generate the C file
    173  1.1  reinoud 	#
    174  1.1  reinoud 
    175  1.1  reinoud 	# Create the file header
    176  1.1  reinoud 	printf("/*\n");
    177  1.1  reinoud 	printf(" * MACHINE GENERATED: DO NOT EDIT\n");
    178  1.1  reinoud 	printf(" *\n");
    179  1.1  reinoud 	printf(" * Created from %s\n", FILENAME);
    180  1.1  reinoud 	printf(" */\n\n");
    181  1.1  reinoud 	printf("#include <sys/types.h>\n");
    182  1.1  reinoud 	printf("#include <arm/iomd/vidc.h>\n\n");
    183  1.1  reinoud 	printf("const char *monitor = \"%s\";\n", monitor);
    184  1.1  reinoud 	printf("const int dpms = %d;\n", dpms);
    185  1.1  reinoud 	printf("\n");
    186  1.1  reinoud 
    187  1.1  reinoud 	# Now define the modes array
    188  1.1  reinoud 	printf("struct vidc_mode vidcmodes[] = {\n");
    189  1.1  reinoud 
    190  1.1  reinoud 	# Loop round all the modespecs on the command line
    191  1.1  reinoud 	for (res = 2; res < realargc; res = res + 1) {
    192  1.1  reinoud 		pos = -1;
    193  1.1  reinoud 		found = -1;
    194  1.1  reinoud 		closest = 200;
    195  1.1  reinoud 
    196  1.1  reinoud 		# Report the mode specifier being processed
    197  1.1  reinoud 		printf("%s ==> ", ARGV[res]) > "/dev/stderr";
    198  1.1  reinoud 
    199  1.1  reinoud 		# Pull apart the modespec
    200  1.1  reinoud 		args = split(ARGV[res], modespec, ",");
    201  1.1  reinoud 
    202  1.1  reinoud 		# We need at least 2 arguments
    203  1.1  reinoud 		if (args < 2) {
    204  1.1  reinoud 			printf("Invalid mode specifier\n") > "/dev/stderr";
    205  1.1  reinoud 			continue;
    206  1.1  reinoud 		}
    207  1.1  reinoud 
    208  1.1  reinoud 		# If we only have x,y default c and f
    209  1.1  reinoud 		if (args == 2) {
    210  1.1  reinoud 			modespec[3] = 256;
    211  1.1  reinoud 			modespec[4] = -1;
    212  1.1  reinoud 		}
    213  1.1  reinoud 		# If we have x,y,f default c and re-arrange.
    214  1.1  reinoud 		if (args == 3) {
    215  1.1  reinoud 			modespec[4] = modespec[3];
    216  1.1  reinoud 			modespec[3] = 256;
    217  1.1  reinoud 		}
    218  1.1  reinoud 
    219  1.1  reinoud 		# Report the full mode specifier
    220  1.1  reinoud 		printf("%d x %d x %d x %d : ", modespec[1], modespec[2],
    221  1.1  reinoud 		    modespec[3], modespec[4]) > "/dev/stderr";
    222  1.1  reinoud 
    223  1.1  reinoud 		# Now loop round all the modes we parsed and find the matches
    224  1.1  reinoud 		for (loop = 0; loop < mode; loop = loop + 1) {
    225  1.1  reinoud 			# Match X & Y
    226  1.1  reinoud 			if (modespec[1] != modes[loop, 1]) continue;
    227  1.1  reinoud 			if (modespec[2] != modes[loop, 2]) continue;
    228  1.1  reinoud 
    229  1.1  reinoud 			# Split the horizontal and vertical timings
    230  1.1  reinoud 			# This is needed for the frame rate calculation
    231  1.1  reinoud 			ht = split(modes[loop, 4], htimings, ",");
    232  1.1  reinoud 			if (ht != 6) continue;
    233  1.1  reinoud 			vt = split(modes[loop, 5], vtimings, ",");
    234  1.1  reinoud 			if (vt != 6) continue;
    235  1.1  reinoud 
    236  1.1  reinoud 			# Calculate the frame rate
    237  1.1  reinoud 			fr = modes[loop, 3] / (htimings[1] + htimings[2] + \
    238  1.1  reinoud 			    htimings[3] + htimings[4] + htimings[5] + \
    239  1.1  reinoud 			    htimings[6]) / ( vtimings[1] + vtimings[2] + \
    240  1.1  reinoud 			    vtimings[3] + vtimings[4] + vtimings[5] + \
    241  1.1  reinoud 			    vtimgings[6]);
    242  1.1  reinoud 			fr = fr * 1000;
    243  1.1  reinoud 
    244  1.1  reinoud 			# Remember the frame rate
    245  1.1  reinoud 			modes[loop, 7] = int(fr + 0.5);
    246  1.1  reinoud 
    247  1.1  reinoud 			# Report the frame rate
    248  1.1  reinoud 			printf("%d ", modes[loop, 7]) > "/dev/stderr";
    249  1.1  reinoud 
    250  1.1  reinoud 			# Is this the closest
    251  1.1  reinoud 			if (closest > mod(modes[loop, 7] - modespec[4])) {
    252  1.1  reinoud 				closest = mod(modes[loop, 7] - modespec[4]);
    253  1.1  reinoud 				pos = loop;
    254  1.1  reinoud 			}
    255  1.1  reinoud 
    256  1.1  reinoud 			# Do we have an exact match ?
    257  1.1  reinoud 			if (modes[loop, 7] == modespec[4])
    258  1.1  reinoud 				found = pos;
    259  1.1  reinoud 		}
    260  1.1  reinoud 
    261  1.1  reinoud 		# If no exact match use the nearest
    262  1.1  reinoud 		if (found == -1)
    263  1.1  reinoud 			found = pos;
    264  1.1  reinoud 
    265  1.1  reinoud 		# Did we find any sort of match ?
    266  1.1  reinoud 		if (found == -1) {
    267  1.1  reinoud 			printf("Cannot find mode") > "/dev/stderr";
    268  1.1  reinoud 			continue;
    269  1.1  reinoud 		}
    270  1.1  reinoud 
    271  1.1  reinoud 		# Report the frame rate matched
    272  1.1  reinoud 		printf("- %d", modes[found, 7]) > "/dev/stderr";
    273  1.1  reinoud 
    274  1.1  reinoud 		# Output the mode as part of the mode definition array
    275  1.1  reinoud 		printf("\t{ %6d, %22s, %22s, %d, %d, %d },\n",
    276  1.1  reinoud 		    modes[found, 3], modes[found, 4], modes[found, 5],
    277  1.1  reinoud 		    cdepth(modespec[3]), modes[found, 6], modes[found, 7]);
    278  1.1  reinoud 
    279  1.1  reinoud 		printf("\n") > "/dev/stderr";
    280  1.1  reinoud 	}
    281  1.1  reinoud 
    282  1.1  reinoud 	# Add a terminating entry and close the array.
    283  1.1  reinoud 	printf("\t{ 0 }\n");
    284  1.1  reinoud 	printf("};\n");
    285  1.1  reinoud }
    286  1.1  reinoud 
    287  1.1  reinoud #
    288  1.1  reinoud # cdepth() function
    289  1.1  reinoud #
    290  1.1  reinoud # This returns the colour depth as a power of 2 + 1
    291  1.1  reinoud #
    292  1.1  reinoud function cdepth(depth) {
    293  1.1  reinoud 	if (depth == 16)
    294  1.1  reinoud 		return 5;
    295  1.1  reinoud 	if (depth == 256)
    296  1.1  reinoud 		return 9;
    297  1.1  reinoud 	if (depth == 32768)
    298  1.1  reinoud 		return 16;
    299  1.1  reinoud 	if (depth == 65536)
    300  1.1  reinoud 		return 17;
    301  1.1  reinoud 	return 9;
    302  1.1  reinoud }
    303  1.1  reinoud 
    304  1.1  reinoud #
    305  1.1  reinoud # Simple mod() function
    306  1.1  reinoud #
    307  1.1  reinoud function mod(a) {
    308  1.1  reinoud 	if (a < 0)
    309  1.1  reinoud 		return -a;
    310  1.1  reinoud 	return a;
    311  1.1  reinoud }
    312