xref: /netbsd-src/sys/arch/arm/iomd/makemodes.awk (revision ce099b40997c43048fb78bd578195f81d2456523)
1*ce099b40Smartin#	$NetBSD: makemodes.awk,v 1.7 2008/04/28 20:23:14 martin Exp $
27d4a1addSreinoud
37d4a1addSreinoud#
47d4a1addSreinoud# Copyright (c) 1998 The NetBSD Foundation, Inc.
57d4a1addSreinoud# All rights reserved.
67d4a1addSreinoud#
77d4a1addSreinoud# This code is derived from software contributed to The NetBSD Foundation
87d4a1addSreinoud# by Mark Brinicombe
97d4a1addSreinoud#
107d4a1addSreinoud# Redistribution and use in source and binary forms, with or without
117d4a1addSreinoud# modification, are permitted provided that the following conditions
127d4a1addSreinoud# are met:
137d4a1addSreinoud# 1. Redistributions of source code must retain the above copyright
147d4a1addSreinoud#    notice, this list of conditions and the following disclaimer.
157d4a1addSreinoud# 2. Redistributions in binary form must reproduce the above copyright
167d4a1addSreinoud#    notice, this list of conditions and the following disclaimer in the
177d4a1addSreinoud#    documentation and/or other materials provided with the distribution.
187d4a1addSreinoud#
197d4a1addSreinoud# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
207d4a1addSreinoud# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
217d4a1addSreinoud# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
227d4a1addSreinoud# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
237d4a1addSreinoud# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
247d4a1addSreinoud# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
257d4a1addSreinoud# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
267d4a1addSreinoud# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
277d4a1addSreinoud# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
287d4a1addSreinoud# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
297d4a1addSreinoud# POSSIBILITY OF SUCH DAMAGE.
307d4a1addSreinoud#
317d4a1addSreinoud
327d4a1addSreinoud# This parses a Acorn monitor definition file and constructs an array of
337d4a1addSreinoud# parameters for each mode.
347d4a1addSreinoud# Once the file has been parsed the list of modes is examined to find modes
357d4a1addSreinoud# that match the mode specifications specified on the command line.
367d4a1addSreinoud# The matching mode definitions are written to stdout in the form of a C file.
377d4a1addSreinoud# Parsing information is written to stderr.
387d4a1addSreinoud#
397d4a1addSreinoud#
407d4a1addSreinoud# Syntax for using this program
417d4a1addSreinoud#
427d4a1addSreinoud# awk -f makemodes.awk <MDF file> <mode spec> [<mode spec> ...]
437d4a1addSreinoud#
447d4a1addSreinoud# where <mode spec> is
457d4a1addSreinoud#	<x>,<y>
467d4a1addSreinoud#	<x>,<y>,<f>
477d4a1addSreinoud#	<x>,<y>,<c>,<f>
487d4a1addSreinoud#
497d4a1addSreinoud# Note: Spaces are NOT allowed in a mode specifier
507d4a1addSreinoud#
517d4a1addSreinoud# where	x = x resolution
527d4a1addSreinoud#	y = y resolution
537d4a1addSreinoud#	f = frame rate
547d4a1addSreinoud#	c = colour depth (16, 256, 32768, 65536)
557d4a1addSreinoud#
567d4a1addSreinoud
577d4a1addSreinoudBEGIN {
587d4a1addSreinoud	# Number of modes parsed and valid in the modes array.
597d4a1addSreinoud	mode = 0;
607d4a1addSreinoud
617d4a1addSreinoud	# MDF file globals
627d4a1addSreinoud	monitor = "";
637d4a1addSreinoud	dpms = 0;
647d4a1addSreinoud
657d4a1addSreinoud	# Non zero if we are translating a mode
667d4a1addSreinoud	translate = 0;
677d4a1addSreinoud
687d4a1addSreinoud	# ':'  character is used to separate the tokens.
697d4a1addSreinoud	FS=":";
707d4a1addSreinoud
717d4a1addSreinoud	# Note the real number of arguments and truncate ARGC so that only the first
727d4a1addSreinoud	# argument is used as a filename.
737d4a1addSreinoud	realargc = ARGC;
747d4a1addSreinoud	ARGC=2;
7528d9a9e3Sbjh21
7628d9a9e3Sbjh21	# Translation of sync_pol to videomode.flags
7728d9a9e3Sbjh21	pol[0] = "HP|VP";
7828d9a9e3Sbjh21	pol[1] = "HN|VP";
7928d9a9e3Sbjh21	pol[2] = "HP|VN";
8028d9a9e3Sbjh21	pol[3] = "HN|VN";
817d4a1addSreinoud}
827d4a1addSreinoud
837d4a1addSreinoud# MDF File format
847d4a1addSreinoud/^file_format/ {
857d4a1addSreinoud	# Currently we only understand format 1 MDF files
867d4a1addSreinoud	if ($2 != 1) {
877d4a1addSreinoud		printf("Unrecognised MDF format (%d)\n", $2);
887d4a1addSreinoud		exit;
897d4a1addSreinoud	}
907d4a1addSreinoud}
917d4a1addSreinoud
927d4a1addSreinoud# Monitor name
937d4a1addSreinoud/^monitor_title/ {
947d4a1addSreinoud	monitor = $2;
957d4a1addSreinoud}
967d4a1addSreinoud
977d4a1addSreinoud# Monitor DPMS state
987d4a1addSreinoud/^DPMS_state/ {
997d4a1addSreinoud	dpms = $2;
1007d4a1addSreinoud}
1017d4a1addSreinoud
1027d4a1addSreinoud# Start of mode definition
1037d4a1addSreinoud/^startmode/ {
1047d4a1addSreinoud	translate = 1;
1057d4a1addSreinoud}
1067d4a1addSreinoud
1077d4a1addSreinoud# End of mode definition
1087d4a1addSreinoud/^endmode/ {
1097d4a1addSreinoud	translate = 0;
1107d4a1addSreinoud	mode = mode + 1;
1117d4a1addSreinoud}
1127d4a1addSreinoud
1137d4a1addSreinoud# The mode definition name (only valid within startmode/endmode section)
1147d4a1addSreinoud/^mode_name:/ {
1157d4a1addSreinoud	if (!translate)
1167d4a1addSreinoud		next;
1177d4a1addSreinoud	modes[mode, 0] = $2;
1187d4a1addSreinoud	next;
1197d4a1addSreinoud}
1207d4a1addSreinoud
1217d4a1addSreinoud# The horizontal resolution (only valid within startmode/endmode section)
1227d4a1addSreinoud/^x_res:/ {
1237d4a1addSreinoud	if (!translate)
1247d4a1addSreinoud		next;
1257d4a1addSreinoud	modes[mode, 1] = $2;
1267d4a1addSreinoud	next;
1277d4a1addSreinoud}
1287d4a1addSreinoud
1297d4a1addSreinoud# The vertical resolution (only valid within startmode/endmode section)
1307d4a1addSreinoud/^y_res:/ {
1317d4a1addSreinoud	if (!translate)
1327d4a1addSreinoud		next;
1337d4a1addSreinoud	modes[mode, 2] = $2;
1347d4a1addSreinoud	next;
1357d4a1addSreinoud}
1367d4a1addSreinoud
1377d4a1addSreinoud# The pixel rate (only valid within startmode/endmode section)
1387d4a1addSreinoud/^pixel_rate:/ {
1397d4a1addSreinoud	if (!translate)
1407d4a1addSreinoud		next;
1417d4a1addSreinoud	modes[mode, 3] = $2;
1427d4a1addSreinoud	next;
1437d4a1addSreinoud}
1447d4a1addSreinoud
1457d4a1addSreinoud# The horizontal timings (only valid within startmode/endmode section)
1467d4a1addSreinoud/^h_timings:/ {
1477d4a1addSreinoud	if (!translate)
1487d4a1addSreinoud		next;
1497d4a1addSreinoud	modes[mode, 4] = $2;
1507d4a1addSreinoud	next;
1517d4a1addSreinoud}
1527d4a1addSreinoud
1537d4a1addSreinoud# The vertical timings (only valid within startmode/endmode section)
1547d4a1addSreinoud/^v_timings:/ {
1557d4a1addSreinoud	if (!translate)
1567d4a1addSreinoud		next;
1577d4a1addSreinoud	modes[mode, 5] = $2;
1587d4a1addSreinoud	next;
1597d4a1addSreinoud}
1607d4a1addSreinoud
1617d4a1addSreinoud# The sync polarity (only valid within startmode/endmode section)
1627d4a1addSreinoud/^sync_pol:/ {
1637d4a1addSreinoud	if (!translate)
1647d4a1addSreinoud		next;
1657d4a1addSreinoud	modes[mode, 6] = $2;
1667d4a1addSreinoud	next;
1677d4a1addSreinoud}
1687d4a1addSreinoud
1697d4a1addSreinoudEND {
1707d4a1addSreinoud	#
1717d4a1addSreinoud	# Now generate the C file
1727d4a1addSreinoud	#
1737d4a1addSreinoud
1747d4a1addSreinoud	# Create the file header
1757d4a1addSreinoud	printf("/*\n");
1767d4a1addSreinoud	printf(" * MACHINE GENERATED: DO NOT EDIT\n");
1777d4a1addSreinoud	printf(" *\n");
1787d4a1addSreinoud	printf(" * Created from %s\n", FILENAME);
1797d4a1addSreinoud	printf(" */\n\n");
1807d4a1addSreinoud	printf("#include <sys/types.h>\n");
1817d4a1addSreinoud	printf("#include <arm/iomd/vidc.h>\n\n");
18272cec937Sbjh21	printf("const char * const monitor = \"%s\";\n", monitor);
1837d4a1addSreinoud	printf("const int dpms = %d;\n", dpms);
18428d9a9e3Sbjh21	printf("#define HP VID_PHSYNC\n");
18528d9a9e3Sbjh21	printf("#define HN VID_NHSYNC\n");
18628d9a9e3Sbjh21	printf("#define VP VID_PVSYNC\n");
18728d9a9e3Sbjh21	printf("#define VN VID_NVSYNC\n");
1887d4a1addSreinoud	printf("\n");
1897d4a1addSreinoud
1907d4a1addSreinoud	# Now define the modes array
19172cec937Sbjh21	printf("const struct videomode vidc_videomode_list[] = {\n");
19272cec937Sbjh21	nmodes = 0
1937d4a1addSreinoud
1947d4a1addSreinoud	# Loop round all the modespecs on the command line
1957d4a1addSreinoud	for (res = 2; res < realargc; res = res + 1) {
1967d4a1addSreinoud		pos = -1;
1977d4a1addSreinoud		found = -1;
1987d4a1addSreinoud		closest = 200;
1997d4a1addSreinoud
2007d4a1addSreinoud		# Report the mode specifier being processed
2011c8dd205Sgdamore		printf("%s ==> ", ARGV[res]) | "cat 1>&2";
2027d4a1addSreinoud
2037d4a1addSreinoud		# Pull apart the modespec
2047d4a1addSreinoud		args = split(ARGV[res], modespec, ",");
2057d4a1addSreinoud
2067d4a1addSreinoud		# We need at least 2 arguments
2077d4a1addSreinoud		if (args < 2) {
2081c8dd205Sgdamore			printf("Invalid mode specifier\n") | "cat 1>&2";
2097d4a1addSreinoud			continue;
2107d4a1addSreinoud		}
2117d4a1addSreinoud
2127d4a1addSreinoud		# If we only have x,y default c and f
2137d4a1addSreinoud		if (args == 2) {
2147d4a1addSreinoud			modespec[3] = 256;
2157d4a1addSreinoud			modespec[4] = -1;
2167d4a1addSreinoud		}
2177d4a1addSreinoud		# If we have x,y,f default c and re-arrange.
2187d4a1addSreinoud		if (args == 3) {
2197d4a1addSreinoud			modespec[4] = modespec[3];
2207d4a1addSreinoud			modespec[3] = 256;
2217d4a1addSreinoud		}
2227d4a1addSreinoud
2237d4a1addSreinoud		# Report the full mode specifier
2247d4a1addSreinoud		printf("%d x %d x %d x %d : ", modespec[1], modespec[2],
2251c8dd205Sgdamore		    modespec[3], modespec[4]) | "cat 1>&2";
2267d4a1addSreinoud
2277d4a1addSreinoud		# Now loop round all the modes we parsed and find the matches
2287d4a1addSreinoud		for (loop = 0; loop < mode; loop = loop + 1) {
2297d4a1addSreinoud			# Match X & Y
2307d4a1addSreinoud			if (modespec[1] != modes[loop, 1]) continue;
2317d4a1addSreinoud			if (modespec[2] != modes[loop, 2]) continue;
2327d4a1addSreinoud
2337d4a1addSreinoud			# Split the horizontal and vertical timings
2347d4a1addSreinoud			# This is needed for the frame rate calculation
2357d4a1addSreinoud			ht = split(modes[loop, 4], htimings, ",");
2367d4a1addSreinoud			if (ht != 6) continue;
2377d4a1addSreinoud			vt = split(modes[loop, 5], vtimings, ",");
2387d4a1addSreinoud			if (vt != 6) continue;
2397d4a1addSreinoud
2407d4a1addSreinoud			# Calculate the frame rate
2417d4a1addSreinoud			fr = modes[loop, 3] / (htimings[1] + htimings[2] + \
2427d4a1addSreinoud			    htimings[3] + htimings[4] + htimings[5] + \
2437d4a1addSreinoud			    htimings[6]) / ( vtimings[1] + vtimings[2] + \
2447d4a1addSreinoud			    vtimings[3] + vtimings[4] + vtimings[5] + \
24564e85b48Sbjh21			    vtimings[6]);
2467d4a1addSreinoud			fr = fr * 1000;
2477d4a1addSreinoud
2487d4a1addSreinoud			# Remember the frame rate
2497d4a1addSreinoud			modes[loop, 7] = int(fr + 0.5);
2507d4a1addSreinoud
25128d9a9e3Sbjh21			# Create the internal version of the timings
25228d9a9e3Sbjh21			modes[loop, "timings"] = \
25328d9a9e3Sbjh21			    sprintf( \
25428d9a9e3Sbjh21			    "{ %d, %d,%d,%d,%d, %d,%d,%d,%d, %s, \"%s\" }",\
25528d9a9e3Sbjh21			    modes[loop, 3], htimings[4], \
25628d9a9e3Sbjh21			    htimings[4] + htimings[5] + htimings[6], \
25728d9a9e3Sbjh21			    htimings[4] + htimings[5] + htimings[6] + \
25828d9a9e3Sbjh21			    htimings[1], \
25928d9a9e3Sbjh21			    htimings[4] + htimings[5] + htimings[6] + \
26028d9a9e3Sbjh21			    htimings[1] + htimings[2] + htimings[3], \
26128d9a9e3Sbjh21			    vtimings[4], \
26228d9a9e3Sbjh21			    vtimings[4] + vtimings[5] + vtimings[6], \
26328d9a9e3Sbjh21			    vtimings[4] + vtimings[5] + vtimings[6] + \
26428d9a9e3Sbjh21			    vtimings[1], \
26528d9a9e3Sbjh21			    vtimings[4] + vtimings[5] + vtimings[6] + \
26628d9a9e3Sbjh21			    vtimings[1] + vtimings[2] + vtimings[3], \
26728d9a9e3Sbjh21			    pol[modes[loop, 6]], modes[loop, 0]);
26828d9a9e3Sbjh21
2697d4a1addSreinoud			# Report the frame rate
2701c8dd205Sgdamore			printf("%d ", modes[loop, 7]) | "cat 1>&2";
2717d4a1addSreinoud
2727d4a1addSreinoud			# Is this the closest
2737d4a1addSreinoud			if (closest > mod(modes[loop, 7] - modespec[4])) {
2747d4a1addSreinoud				closest = mod(modes[loop, 7] - modespec[4]);
2757d4a1addSreinoud				pos = loop;
2767d4a1addSreinoud			}
2777d4a1addSreinoud
2787d4a1addSreinoud			# Do we have an exact match ?
2797d4a1addSreinoud			if (modes[loop, 7] == modespec[4])
2807d4a1addSreinoud				found = pos;
2817d4a1addSreinoud		}
2827d4a1addSreinoud
2837d4a1addSreinoud		# If no exact match use the nearest
2847d4a1addSreinoud		if (found == -1)
2857d4a1addSreinoud			found = pos;
2867d4a1addSreinoud
2877d4a1addSreinoud		# Did we find any sort of match ?
2887d4a1addSreinoud		if (found == -1) {
2891c8dd205Sgdamore			printf("Cannot find mode") | "cat 1>&2";
2907d4a1addSreinoud			continue;
2917d4a1addSreinoud		}
2927d4a1addSreinoud
2937d4a1addSreinoud		# Report the frame rate matched
2941c8dd205Sgdamore		printf("- %d", modes[found, 7]) | "cat 1>&2";
2957d4a1addSreinoud
2967d4a1addSreinoud		# Output the mode as part of the mode definition array
29772cec937Sbjh21		printf("\t%s,\n", modes[found, "timings"]);
2987d4a1addSreinoud
2991c8dd205Sgdamore		printf("\n") | "cat 1>&2";
30072cec937Sbjh21		nmodes++;
3017d4a1addSreinoud	}
3027d4a1addSreinoud
30372cec937Sbjh21	# Close the array.
30472cec937Sbjh21	printf("};\n\n");
30572cec937Sbjh21	printf("const int vidc_videomode_count = %d;\n", nmodes);
3067d4a1addSreinoud}
3077d4a1addSreinoud
3087d4a1addSreinoud#
3097d4a1addSreinoud# Simple mod() function
3107d4a1addSreinoud#
3117d4a1addSreinoudfunction mod(a) {
3127d4a1addSreinoud	if (a < 0)
3137d4a1addSreinoud		return -a;
3147d4a1addSreinoud	return a;
3157d4a1addSreinoud}
316