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