#!/bin/sh

# pal_modeline.sh, Version: 0.0.9
# utility for modeline and fbset parameter calculation

#
# INPUT PARAMETERS (between 'config start' and 'config end'):
#
#    DOTCLK_G in kHz:
#      you may give reasonable values here lets say
#      between 6000 and 20000. higher values display more
#      pixels per length unit on your screen. the upper limit is
#      confined to the bandwidth of your monitor.
#
#    XRES_G in pixels:
#      enter your desired horizontal resolution here. this value is
#      seen by the the application of your Xserver or
#      framebuffer device. due to overscan it possibly may not equal
#      the amount of pixels actually visible on your screen.
#
#    XSKEW_G in nanoseconds:
#      this value defines where the monitor starts to display the first
#      pixels within a scanline. to reduce overscan you must adjust this
#      value as close as possible to the left edge of the visible
#      area of your screen.
#
#    YRES in pixels:
#      enter your desired vertical resolution here. this value is
#      seen by the the application of your Xserver or
#      framebuffer device. due to overscan it possibly may not equal
#      the amount of pixels actually visible on your screen.
#
#    UPPER in pixels:
#      this value defines where the monitor starts to display the first 
#      scanline. to reduce overscan you must adjust this value as close as
#      possible to the upper edge of the visible area of your screen.
#
# OUTPUT PARAMETERS:
#
#    all calculated timing values should represent RGB PAL compatible 
#    format of 15.625 kHz horizontal and 50 Hz vertical sync frequency 
#    (interlaced). if PAL compatible timing is not possible with 
#    supplied input parameters the program exits with an error message.
#
#    the output of this program is ment to drive directly an xorg.conf
#    modeline or fbset command.
#
# *** WARNING ***
# use at your own risk. though the program normally ceases from
# accepting PAL incompatible input values I cannot guarantee error free
# operation under all circumstances. wrong values could damage a
# connected cathode ray tube TV set.
#

awk '
BEGIN {

# --- config start ---

# following parameter sets are sample setups only.
# tested successfully with my own cathode ray tube TV set.

# parameter set for 720x576 resolution with overscan
    DOTCLK_G = 13500     # [ kHz ]
    XRES_G = 720         # [ pixels ]
    XSKEW_G = 4740       # [ ns ]

    YRES = 576           # [ pixels ]
    UPPER = 39           # [ lines ]

# parameter set for 720x520 resolution without overscan
#    DOTCLK_G = 15000     # [ kHz ]
#    XRES_G = 720         # [ pixels ]
#    XSKEW_G = 7000       # [ ns ]
#
#    YRES = 520           # [ pixels ]
#    UPPER = 72           # [ lines ]

# parameter set for 800x520 resolution without overscan 
#    DOTCLK_G = 17000     # [ kHz ]
#    XRES_G = 800         # [ pixels ]
#    XSKEW_G = 8300       # [ ns ]
#
#    YRES = 520           # [ pixels ]
#    UPPER = 72           # [ lines ]

# --- config end ---

# horizontal section
    DOTCLK = int((DOTCLK_G + 62) / 125) * 125
    XRES = int((XRES_G + 4) / 8) * 8
    HFL = int(64000 * DOTCLK / 1e+6)
    HSLEN = int((4740741 * DOTCLK / 1e+9 + 4) / 8) * 8
    LEFT = int((XSKEW_G * DOTCLK / 1e+6 + 4) / 8) * 8
    RIGHT = HFL - XRES - LEFT - HSLEN
    PIXCLK = int(1e+9 / DOTCLK)
    if (RIGHT <= 0) {
        print "invalid horizontal parameters, exiting"; exit
    }

# vertical section
    VFL = 625
    VSLEN = 5
    LOWER = VFL - YRES - UPPER - VSLEN
    if (LOWER <= 0) {
        print "invalid vertical parameters, exiting"; exit
    }

# output
    print "# DOTCLK: " DOTCLK " [ " DOTCLK_G " ]"
    print "# XRES:   " XRES   " [ " XRES_G " ]"
    print "# XSKEW:  " int(LEFT * 1e+6 / DOTCLK) " [ " XSKEW_G " ]"
    print "# YRES:   " YRES   
    print "# UPPER:  " UPPER
    print "Modeline \"" XRES "x" YRES "i\" " \
           DOTCLK / 1e+3 " " \
           XRES " " \
           XRES + RIGHT " " \
           XRES + RIGHT + HSLEN " " \
           XRES + RIGHT + HSLEN + LEFT " " \
           YRES " " \
           YRES + LOWER " " \
           YRES + LOWER + VSLEN " " \
           YRES + LOWER + VSLEN + UPPER " " \
           "Composite interlace"

    print "fbset -g " XRES " " YRES " " XRES " " YRES " " "32" " " \
          "-t " PIXCLK " " LEFT " " RIGHT " " UPPER " " LOWER " " \
          HSLEN " " VSLEN " " "-hsync true -vsync true -laced true"
}
'

