8b0bd1ca77
This is an awk script to parse an Acorn Monitor Definition File and generate a C file containing the selected mode timing parameters. Read the comments at the start of the file for details on use. This file replaces makemodes.c
312 lines
7.6 KiB
Awk
312 lines
7.6 KiB
Awk
# $NetBSD: makemodes.awk,v 1.1 1999/01/01 10:26:41 mark Exp $
|
|
|
|
#
|
|
# Copyright (c) 1998 The NetBSD Foundation, Inc.
|
|
# All rights reserved.
|
|
#
|
|
# This code is derived from software contributed to The NetBSD Foundation
|
|
# by Mark Brinicombe
|
|
#
|
|
# Redistribution and use in source and binary forms, with or without
|
|
# modification, are permitted provided that the following conditions
|
|
# are met:
|
|
# 1. Redistributions of source code must retain the above copyright
|
|
# notice, this list of conditions and the following disclaimer.
|
|
# 2. Redistributions in binary form must reproduce the above copyright
|
|
# notice, this list of conditions and the following disclaimer in the
|
|
# documentation and/or other materials provided with the distribution.
|
|
# 3. All advertising materials mentioning features or use of this software
|
|
# must display the following acknowledgement:
|
|
# This product includes software developed by the NetBSD
|
|
# Foundation, Inc. and its contributors.
|
|
# 4. Neither the name of The NetBSD Foundation nor the names of its
|
|
# contributors may be used to endorse or promote products derived
|
|
# from this software without specific prior written permission.
|
|
#
|
|
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
|
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
|
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
# POSSIBILITY OF SUCH DAMAGE.
|
|
#
|
|
|
|
# This parses a Acorn monitor definition file and constructs an array of
|
|
# parameters for each mode.
|
|
# Once the file has been parsed the list of modes is examined to find modes
|
|
# that match the mode specifications specified on the command line.
|
|
# The matching mode definitions are written to stdout in the form of a C file.
|
|
# Parsing information is written to stderr.
|
|
#
|
|
#
|
|
# Syntax for using this program
|
|
#
|
|
# awk -f makemodes.awk <MDF file> <mode spec> [<mode spec> ...]
|
|
#
|
|
# where <mode spec> is
|
|
# <x>,<y>
|
|
# <x>,<y>,<f>
|
|
# <x>,<y>,<c>,<f>
|
|
#
|
|
# Note: Spaces are NOT allowed in a mode specifier
|
|
#
|
|
# where x = x resolution
|
|
# y = y resolution
|
|
# f = frame rate
|
|
# c = colour depth (16, 256, 32768, 65536)
|
|
#
|
|
|
|
BEGIN {
|
|
# Number of modes parsed and valid in the modes array.
|
|
mode = 0;
|
|
|
|
# MDF file globals
|
|
monitor = "";
|
|
dpms = 0;
|
|
|
|
# Non zero if we are translating a mode
|
|
translate = 0;
|
|
|
|
# ':' character is used to separate the tokens.
|
|
FS=":";
|
|
|
|
# Note the real number of arguments and truncate ARGC so that only the first
|
|
# argument is used as a filename.
|
|
realargc = ARGC;
|
|
ARGC=2;
|
|
}
|
|
|
|
# MDF File format
|
|
/^file_format/ {
|
|
# Currently we only understand format 1 MDF files
|
|
if ($2 != 1) {
|
|
printf("Unrecognised MDF format (%d)\n", $2);
|
|
exit;
|
|
}
|
|
}
|
|
|
|
# Monitor name
|
|
/^monitor_title/ {
|
|
monitor = $2;
|
|
}
|
|
|
|
# Monitor DPMS state
|
|
/^DPMS_state/ {
|
|
dpms = $2;
|
|
}
|
|
|
|
# Start of mode definition
|
|
/^startmode/ {
|
|
translate = 1;
|
|
}
|
|
|
|
# End of mode definition
|
|
/^endmode/ {
|
|
translate = 0;
|
|
mode = mode + 1;
|
|
}
|
|
|
|
# The mode definition name (only valid within startmode/endmode section)
|
|
/^mode_name:/ {
|
|
if (!translate)
|
|
next;
|
|
modes[mode, 0] = $2;
|
|
next;
|
|
}
|
|
|
|
# The horizontal resolution (only valid within startmode/endmode section)
|
|
/^x_res:/ {
|
|
if (!translate)
|
|
next;
|
|
modes[mode, 1] = $2;
|
|
next;
|
|
}
|
|
|
|
# The vertical resolution (only valid within startmode/endmode section)
|
|
/^y_res:/ {
|
|
if (!translate)
|
|
next;
|
|
modes[mode, 2] = $2;
|
|
next;
|
|
}
|
|
|
|
# The pixel rate (only valid within startmode/endmode section)
|
|
/^pixel_rate:/ {
|
|
if (!translate)
|
|
next;
|
|
modes[mode, 3] = $2;
|
|
next;
|
|
}
|
|
|
|
# The horizontal timings (only valid within startmode/endmode section)
|
|
/^h_timings:/ {
|
|
if (!translate)
|
|
next;
|
|
modes[mode, 4] = $2;
|
|
next;
|
|
}
|
|
|
|
# The vertical timings (only valid within startmode/endmode section)
|
|
/^v_timings:/ {
|
|
if (!translate)
|
|
next;
|
|
modes[mode, 5] = $2;
|
|
next;
|
|
}
|
|
|
|
# The sync polarity (only valid within startmode/endmode section)
|
|
/^sync_pol:/ {
|
|
if (!translate)
|
|
next;
|
|
modes[mode, 6] = $2;
|
|
next;
|
|
}
|
|
|
|
END {
|
|
#
|
|
# Now generate the C file
|
|
#
|
|
|
|
# Create the file header
|
|
printf("/*\n");
|
|
printf(" * MACHINE GENERATED: DO NOT EDIT\n");
|
|
printf(" *\n");
|
|
printf(" * Created from %s\n", FILENAME);
|
|
printf(" */\n\n");
|
|
printf("#include <sys/types.h>\n");
|
|
printf("#include <machine/vidc.h>\n\n");
|
|
printf("const char *monitor = \"%s\";\n", monitor);
|
|
printf("const int dpms = %d;\n", dpms);
|
|
printf("\n");
|
|
|
|
# Now define the modes array
|
|
printf("struct vidc_mode vidcmodes[] = {\n");
|
|
|
|
# Loop round all the modespecs on the command line
|
|
for (res = 2; res < realargc; res = res + 1) {
|
|
pos = -1;
|
|
found = -1;
|
|
closest = 200;
|
|
|
|
# Report the mode specifier being processed
|
|
printf("%s ==> ", ARGV[res]) > "/dev/stderr";
|
|
|
|
# Pull apart the modespec
|
|
args = split(ARGV[res], modespec, ",");
|
|
|
|
# We need at least 2 arguments
|
|
if (args < 2) {
|
|
printf("Invalid mode specifier\n") > "/dev/stderr";
|
|
continue;
|
|
}
|
|
|
|
# If we only have x,y default c and f
|
|
if (args == 2) {
|
|
modespec[3] = 256;
|
|
modespec[4] = -1;
|
|
}
|
|
# If we have x,y,f default c and re-arrange.
|
|
if (args == 3) {
|
|
modespec[4] = modespec[3];
|
|
modespec[3] = 256;
|
|
}
|
|
|
|
# Report the full mode specifier
|
|
printf("%d x %d x %d x %d : ", modespec[1], modespec[2],
|
|
modespec[3], modespec[4]) > "/dev/stderr";
|
|
|
|
# Now loop round all the modes we parsed and find the matches
|
|
for (loop = 0; loop < mode; loop = loop + 1) {
|
|
# Match X & Y
|
|
if (modespec[1] != modes[loop, 1]) continue;
|
|
if (modespec[2] != modes[loop, 2]) continue;
|
|
|
|
# Split the horizontal and vertical timings
|
|
# This is needed for the frame rate calculation
|
|
ht = split(modes[loop, 4], htimings, ",");
|
|
if (ht != 6) continue;
|
|
vt = split(modes[loop, 5], vtimings, ",");
|
|
if (vt != 6) continue;
|
|
|
|
# Calculate the frame rate
|
|
fr = modes[loop, 3] / (htimings[1] + htimings[2] + \
|
|
htimings[3] + htimings[4] + htimings[5] + \
|
|
htimings[6]) / ( vtimings[1] + vtimings[2] + \
|
|
vtimings[3] + vtimings[4] + vtimings[5] + \
|
|
vtimgings[6]);
|
|
fr = fr * 1000;
|
|
|
|
# Remember the frame rate
|
|
modes[loop, 7] = int(fr + 0.5);
|
|
|
|
# Report the frame rate
|
|
printf("%d ", modes[loop, 7]) > "/dev/stderr";
|
|
|
|
# Is this the closest
|
|
if (closest > mod(modes[loop, 7] - modespec[4])) {
|
|
closest = mod(modes[loop, 7] - modespec[4]);
|
|
pos = loop;
|
|
}
|
|
|
|
# Do we have an exact match ?
|
|
if (modes[loop, 7] == modespec[4])
|
|
found = pos;
|
|
}
|
|
|
|
# If no exact match use the nearest
|
|
if (found == -1)
|
|
found = pos;
|
|
|
|
# Did we find any sort of match ?
|
|
if (found == -1) {
|
|
printf("Cannot find mode") > "/dev/stderr";
|
|
continue;
|
|
}
|
|
|
|
# Report the frame rate matched
|
|
printf("- %d", modes[found, 7]) > "/dev/stderr";
|
|
|
|
# Output the mode as part of the mode definition array
|
|
printf("\t{ %6d, %22s, %22s, %d, %d, %d },\n",
|
|
modes[found, 3], modes[found, 4], modes[found, 5],
|
|
cdepth(modespec[3]), modes[found, 6], modes[found, 7]);
|
|
|
|
printf("\n") > "/dev/stderr";
|
|
}
|
|
|
|
# Add a terminating entry and close the array.
|
|
printf("\t{ 0 }\n");
|
|
printf("};\n");
|
|
}
|
|
|
|
#
|
|
# cdepth() function
|
|
#
|
|
# This returns the colour depth as a power of 2 + 1
|
|
#
|
|
function cdepth(depth) {
|
|
if (depth == 16)
|
|
return 5;
|
|
if (depth == 256)
|
|
return 9;
|
|
if (depth == 32768)
|
|
return 16;
|
|
if (depth == 65536)
|
|
return 17;
|
|
return 9;
|
|
}
|
|
|
|
#
|
|
# Simple mod() function
|
|
#
|
|
function mod(a) {
|
|
if (a < 0)
|
|
return -a;
|
|
return a;
|
|
}
|