Video Signals And Timing: Difference between revisions

m
[unchecked revision][unchecked revision]
(Quick explanation of margins..)
 
(40 intermediate revisions by 5 users not shown)
Line 1:
{{Video warning}}
'''Work in progress. Needs explanation of the formulae'''
 
To make the video card and monitor independent of each other, there is a standard in communication. This page describes the technical parts of that link with the necessary information to program a video card and have it render properly on the attached screen.
'''TODO: Trick wanted to get the variable names out of the TOC'''
 
== Display Signal ==
'''Warning: Setting incorrect video settings can damage a monitor'''
There are 15 pins in a standard VGA Cable. When your video card sends its video data to the monitor, it uses 5 data channels:
 
= Display Signal =
There are a large amount of pins in a standard VGA Cable. When your video card sends its video data to the monitor, it uses 5 data channels:
* Analog Red
* Analog Green
Line 16 ⟶ 14:
The system is however not that simple. The first monitors were CRTs, which used magnetic fields to project electron beams onto a phosphoric layer, making them visible for a short period of time. The magnetic fields of a CRT had some inertia - they couldn't be set from a random location to another random location in the time available for one pixel. Hence the video signal has to have some gaps to cope with the time a monitor needs to alter the magnetic fields and point the electron beam back to the other side of the screen. In the meantime there could be no color signal, or you might have gotten stripes on the screen.
 
CRTs have improved a lot since then, and are now being superseded by the highly intelligent LCD display. The standard for signaling hasn't changed since. Since the original standard was made for CRTs, the rest of the document will implicitly assume an (old) CRT. LCD displays basically decode a CRT signal and then restructure it to fit their own screen grid under analog signaling methods. Similarly, in many other references you will see that the display unit of a video card is referred to as the "CRTC" or "CRT Controller"
 
 
 
== Display Composition ==
All frames of a video signal have a specific layout, and video cards have a semi-standard way of thinking about these signals. Basically, you will have to provide the video card with enough information to be able to derive all sizes present in the following diagram. [[VGA Hardware]] explains how you can give these sizes to a VGA compatible. For other hardware, you should check your card's documentation on how these values are stored within them.
 
Line 33 ⟶ 29:
* where the overscan goes into active display, where the scanline or frame is completed and the next one is started.
 
Video cards usually gives you the following registers to program (both horizontally and vertiallyvertically)
* Resolution (pixel size of active display)
* Total (total number of 'pixels' in a single run)
Line 39 ⟶ 35:
* Sync start and end (or start and size) - marks the location of the synchronization pulse
 
== Frequencies ==
 
When you increase the resolution, you will need to send more pixels to the display. If you would keep sending pixels at the same rate, the time to transmit one frame will go up, and consequently the amount of frames in a certain timespan will go down. Since a CRT displayed pixel only gives light for a short time before running out of energy, it needs to be repeatedly refreshed. If this is done fast enough (at about 60Hz, 60 times a second) the screen appears almost constant to the human eye. This improves further when the refresh rate goes up to a point where it doesn't matter to the human eye. However when it drops too much, the screen starts appearing flashing, causing headaches to the user. Hence, we need to keep the frequency at at least 60Hz for user's sanity, and below some other rate dictated by the monitor's capabilities. To make a full frame of pixels fit within one sixtieth of a second, we will have to adjust the speed at which these pixels are transmitted. This speed is called the pixel clock, or dot clock. For example, a VGA's dot clock is either 25MHz or 28MHz, corresponding to 25 million pixels per second or 28 million pixels per second, the latter one being only just enough to display a resolution of 720x480 at 60Hz (recall that the active display is only a part of the frame). Most higher resolution video can therefore use a wide range of dot clocks, well above 25MHz, with the current range allowing enough bandwith to easily exceed 1600x1200 at a 100Hz.
 
= Frequencies =
 
When you increase the resolution, you will need to send more pixels to the display. If you would keep sending pixels at the same rate, the time to transmit one frame will go up, and consequently the amount of frames in a certain timespan will go down. Since a CRT displayed pixel only gives light for a short time before running out of energy, it needs to be repeatedly refreshed. If this is done fast enough (at about 60Hz, 60 times a second) the screen appears almost constant to the human eye. This improves further when the refresh rate goes up to a point where it doesn't matter to the human eye. However when it drops too much, the screen starts appearing flashing, causing headaches to the user. Hence, we need to keep the frequency at at least 60Hz for user's sanity, and below some other rate dictated by the monitor's capabilities. To make a full frame of pixels fit within one sixtieth of a second, we will have to adjust the speed at which these pixels are transmitted. This speed is called the pixel clock, or dot clock. For example, a VGA's dot clock is either 25MHz or 28MHz, corresponding to 25 million pixels per second or 28 million pixels per second, the latter one being only just enough to display a resolution of 720x480 at 60Hz (recall that the active display is only a part of the frame). Most higher resolution video can therefore use a wide range of dot clocks, well above 25Hz, with the current range allowing enough bandwith to easily exceed 1600x1200 at a 100Hz.
 
While the resolution is limited by the video card, In most non-VGA scenario's, it is the monitor that can not handle the speed of the signal. The monitor has a allowed vertical frequency (the amount of frames per second, usually listed in Hz), and horizontal frequency (listed in KHz). Some CRTs are fixed frequency, only allowing certain frequencies to be used both horizontally and vertically. Old VGA displays are infamous for burning out when you feed them a signal that doesn't exactly match these rates. While modern CRTs are mostly protected from bad signaling, you must know that you can break hardware in this fashion, and that you need to be careful.
 
== General Timing Formula ==
 
In order to cope with all the CRT antiquities, VESA has produced a set of equations that allows you to compute the various display settings you need, given the desired resolution. There are three separate sets of formulas: One to compute all settings from resolution and desired refresh rate, one taking resolution and horizontal frequency, and one taking resolution and dot clock.
 
= General Timing Formula =
 
In order to cope with all the CRT antiquities, VESA has produced a set of equations that allows you to compute the various display settings you need, given the desired resolution. There are three separate sets of formulae: One to compute all settings from resolution and desired refresh rate, one taking resolution and horizontal frequency, and one taking resolution and dot clock.
 
Normally before setting a mode you would do the following:
Line 70 ⟶ 62:
The formula's provided by VESA use various scales of constants. Brendan's working on changing the scales to units. Right now, the scale space is still unknown.
 
=== GTFCommon Usingparts resolutionof andthe refreshGTF rateformulas ===
 
<tt>[[#H_PIXELS_RND|H_PIXELS_RND]] = ( ''ROUND'' ( [[#H_PIXELS|H_PIXELS]] / [[#CELL_GRAN_RND|CELL_GRAN_RND]] ) ) * [[#CELL_GRAN_RND|CELL_GRAN_RND]]
Line 77 ⟶ 69:
{<br />
:[[#V_LINES_RND|V_LINES_RND]] = ''ROUND'' ( [[#V_LINES|V_LINES]] / 2 )<br />
:[[#V_FIELD_RATE_REQUIRED|V_FIELD_RATE_REQUIRED]] = [[#REFRESH_RATE_REQUIRED|V_LINESREFRESH_RATE_REQUIRED]] * 2<br />
:[[#INTERLACE|INTERLACE]] = 0.5<br />
} '''else''' {<br />
:[[#V_LINES_RND|V_LINES_RND]] = ''ROUND'' ( [[#V_LINES|V_LINES]]) )<br />
:[[#V_FIELD_RATE_REQUIRED|V_FIELD_RATE_REQUIRED]] = [[#REFRESH_RATE_REQUIRED|REFRESH_RATE_REQUIRED]]<br />
:[[#INTERLACE|INTERLACE]] = 0<br />
}<br />
 
'''if''' ( [[#MARGINS_REQUIRED]] == '''true''' ) {<br />
:[[#TOP_MARGIN_LINES|TOP_MARGIN_LINES]] = ''ROUND'' ( [[#MARGIN_PRECENTMARGIN_PERCENT|MARGIN_PERCENT]] / 100 * [[#V_LINES_RND|V_LINES_RND]] )<br />
:[[#BOTTOM_MARGIN_LINES|BOTTOM_MARGIN_LINES]] = ''ROUND'' ( [[#MARGIN_PRECENTMARGIN_PERCENT|MARGIN_PERCENT]] / 100 * [[#V_LINES_RND|V_LINES_RND]] )<br />
:[[#LEFT_MARGIN_PIXELS|LEFT_MARGIN_PIXELS]] = ( ''ROUND'' ( ( [[#H_PIXELS_RND|H_PIXELS_RND]] * [[#MARGIN_PRECENTMARGIN_PERCENT|MARGIN_PERCENT]] / 100 / [[#CELL_GRAN_RND|CELL_GRAN_RND]] ) , 0 ) ) * [[#CELL_GRAN_RND|CELL_GRAN_RND]]<br />
:[[#RIGHT_MARGIN_PIXELS|RIGHT_MARGIN_PIXELS]] = ( ''ROUND'' ( ( [[#H_PIXELS_RND|H_PIXELS_RND]] * [[#MARGIN_PRECENTMARGIN_PERCENT|MARGIN_PERCENT]] / 100 / [[#CELL_GRAN_RND|CELL_GRAN_RND]] ) , 0 ) ) * [[#CELL_GRAN_RND|CELL_GRAN_RND]]<br />
} '''else''' {<br />
:[[#TOP_MARGIN_LINES|TOP_MARGIN_LINES]] = 0<br />
:[[#BOTTOM_MARGIN_LINES|BOTTOM_MARGIN_LINES]] = 0<br />
:[[#LEFT_MARGIN_PIXELS|LEFT_MARGIN_PIXELS]] = 0<br />
:[[#RIGHT_MARGIN_PIXELS|RIGHT_MARGIN_PIXELS]] = 0<br />
}
 
'''/* use one of the GTF equations here */'''
[[#H_PERIOD_ESTIMATE]] = ( 1 / [[#V_FIELD_RATE_REQUIRED]] - [[#MIN_V_SYNC_AND_BACK_PORCH]] / 1000000 )
:/ ( [[#V_LINES_RND]] + 2 * [[#TOP_MARGIN_LINES]] + [[#MIN_PORCH_RND]] + [[#INTERLACE]] ) * 1000000
 
[[#V_FRONT_PORCH|V_FRONT_PORCH]] = [[#MIN_PORCH_RND|MIN_PORCH_RND]] + [[#INTERLACE|INTERLACE]]<br />
[[#H_SYNC|H_SYNC]] = ( ''ROUND'' ( [[#H_SYNC_PERCENT|H_SYNC_PERCENT]] / 100 * [[#H_TOTAL|H_TOTAL]] / [[#CELL_GRAN_RND|CELL_GRAN_RND]] ) ) * [[#CELL_GRAN_RND|CELL_GRAN_RND]]<br />
[[#H_FRONT_PORCH|H_FRONT_PORCH]] = [[#H_TOTAL|H_TOTAL]] / 2 - [[#H_SYNC|H_SYNC]]<br />
[[#H_BACK_PORCH|H_BACK_PORCH]] = [[#H_FRONT_PORCH|H_FRONT_PORCH]] + [[#H_SYNC|H_SYNC]] <br />
</tt>
 
=== GTF Using resolution and refresh rate ===
[[#V_SYNC_AND_BACK_PORCH]] = ''ROUND'' ( [[#MIN_V_SYNC_AND_BACK_PORCH]] / [[#H_PERIOD_ESTIMATE]] )
 
<tt>
[[#V_BACK_PORCH]] = [[#V_SYNC_AND_BACK_PORCH]] - [[#V_SYNC_RND]]
[[#H_PERIOD_ESTIMATE|H_PERIOD_ESTIMATE]] = ( 1 / [[#V_FIELD_RATE_REQUIRED|V_FIELD_RATE_REQUIRED]] - [[#MIN_V_SYNC_AND_BACK_PORCH|MIN_V_SYNC_AND_BACK_PORCH]] / 1000000 )
:/ ( [[#V_LINES_RND|V_LINES_RND]] + 2 * [[#TOP_MARGIN_LINES|TOP_MARGIN_LINES]] + [[#MIN_PORCH_RND|MIN_PORCH_RND]] + [[#INTERLACE|INTERLACE]] ) * 1000000
 
[[#TOTAL_V_LINES]] = [[#V_LINES_RND]] +
:[[#TOP_MARGIN_LINES]] + [[#BOTTOM_MARGIN_LINES]] +
:[[#V_SYNC_AND_BACK_PORCH]] + [[#INTERLACE]] + [[#MIN_PORCH_RND]]
 
[[#V_SYNC_AND_BACK_PORCH|V_SYNC_AND_BACK_PORCH]] = ''ROUND'' ( [[#MIN_V_SYNC_AND_BACK_PORCH|MIN_V_SYNC_AND_BACK_PORCH]] / [[#H_PERIOD_ESTIMATE|H_PERIOD_ESTIMATE]] )
 
[[#V_BACK_PORCH|V_BACK_PORCH]] = [[#V_SYNC_AND_BACK_PORCH|V_SYNC_AND_BACK_PORCH]] - [[#V_SYNC_RND|V_SYNC_RND]]
[[#V_FIELD_RATE_ESTIMATE]] = 1000000 / [[#H_PERIOD_ESTIMATE]] / [[#TOTAL_V_LINES]]
 
[[#TOTAL_V_LINES|TOTAL_V_LINES]] = [[#V_LINES_RND|V_LINES_RND]] +
[[#H_PERIOD]] = [[#H_PERIOD_ESTIMATE]] * [[#V_FIELD_RATE_ESTIMATE]] / [[#V_FIELD_RATE_REQUIRED]]
:[[#TOP_MARGIN_LINES|TOP_MARGIN_LINES]] + [[#BOTTOM_MARGIN_LINES|BOTTOM_MARGIN_LINES]] +
:[[#V_SYNC_AND_BACK_PORCH|V_SYNC_AND_BACK_PORCH]] + [[#INTERLACE|INTERLACE]] + [[#MIN_PORCH_RND|MIN_PORCH_RND]]
 
[[#V_FIELD_RATE]] = 1000000 / [[#H_PERIOD]] / [[#TOTAL_V_LINES]]
 
[[#V_FIELD_RATE_ESTIMATE|V_FIELD_RATE_ESTIMATE]] = 1000000 / [[#H_PERIOD_ESTIMATE|H_PERIOD_ESTIMATE]] / [[#TOTAL_V_LINES|TOTAL_V_LINES]]
'''if''' ( INTERLACE_REQUIRED == '''true''' ) {<br />
 
:[[#V_FRAME_RATE]] = [[#V_FIELD_RATE]] / 2<br />
[[#H_PERIOD|H_PERIOD]] = [[#H_PERIOD_ESTIMATE|H_PERIOD_ESTIMATE]] * [[#V_FIELD_RATE_ESTIMATE|V_FIELD_RATE_ESTIMATE]] / [[#V_FIELD_RATE_REQUIRED|V_FIELD_RATE_REQUIRED]]
 
[[#V_FIELD_RATE|V_FIELD_RATE]] = 1000000 / [[#H_PERIOD|H_PERIOD]] / [[#TOTAL_V_LINES|TOTAL_V_LINES]]
 
'''if''' ( [[#INTERLACE_REQUIRED|INTERLACE_REQUIRED]] == '''true''' ) {<br />
:[[#V_FRAME_RATE|V_FRAME_RATE]] = [[#V_FIELD_RATE|V_FIELD_RATE]] / 2<br />
} '''else''' {<br />
:[[#V_FRAME_RATE|V_FRAME_RATE]] = [[#V_FIELD_RATE|V_FIELD_RATE]]<br />
}<br />
 
[[#TOTAL_ACTIVE_PIXELS|TOTAL_ACTIVE_PIXELS]] = [[#H_PIXELS_RND|H_PIXELS_RND]] + [[#LEFT_MARGIN_PIXELS|LEFT_MARGIN_PIXELS]] + [[#RIGHT_MARGIN_PIXELS|RIGHT_MARGIN_PIXELS]]
 
[[#IDEAL_DUTY_CYCLE|IDEAL_DUTY_CYCLE]] = [[#C_PRIME|C_PRIME]] - [[#M_PRIME|M_PRIME]] * [[#H_PERIOD|H_PERIOD]] / 1000
 
[[#H_BLANK_PIXELS|H_BLANK_PIXELS]] = ( ''ROUND'' (
::( [[#TOTAL_ACTIVE_PIXELS|TOTAL_ACTIVE_PIXELS]] * [[#IDEAL_DUTY_CYCLE|IDEAL_DUTY_CYCLE]] / ( 100 - [[#IDEAL_DUTY_CYCLE|IDEAL_DUTY_CYCLE]] ) / ( 2 * [[#CELL_GRAN_RND|CELL_GRAN_RND]] ) )
:) ) * 2 * [[#CELL_GRAN_RND|CELL_GRAN_RND]]
 
[[#H_TOTAL|H_TOTAL]] = [[#TOTAL_ACTIVE_PIXELS|TOTAL_ACTIVE_PIXELS]] + [[#H_BLANK_PIXELS|H_BLANK_PIXELS]]
 
[[#TOTAL_PIXELSPIXEL_FREQ|PIXEL_FREQ]] = [[#TOTAL_ACTIVE_PIXELSH_TOTAL|H_TOTAL]] +/ [[#H_BLANK_PIXELSH_PERIOD|H_PERIOD]] * 1000000
 
[[#PIXEL_FREQH_FREQ|H_FREQ]] = [[#TOTAL_PIXELS]]1 / [[#H_PERIOD|H_PERIOD]] * 1000000
 
[[#H_FREQ]] = 1 / [[#H_PERIOD]]
</tt>
 
=== GTF Using resolution and pixel clock ===
<tt>
[[#PIXEL_FREQ|PIXEL_FREQ]] = [[#PIXEL_FREQ_REQUIRED|PIXEL_FREQ_REQUIRED]]<br />
[[#TOTAL_ACTIVE_PIXELS|TOTAL_ACTIVE_PIXELS]] = [[#H_PIXELS_RND|H_PIXELS_RND]] + [[#RIGHT_MARGIN_PIXELS|RIGHT_MARGIN_PIXELS]] + [[#LEFT_MARGIN_PIXELS|LEFT_MARGIN_PIXELS]]<br />
 
[[#IDEAL_H_PERIOD|IDEAL_H_PERIOD]] = ( ( [[#C_PRIME|C_PRIME]] - 100 ) + ( ''SQRT'' ( ( ( 100 - [[#C_PRIME|C_PRIME]] ) ^ 2 ) +
== GTF Using resolution and horizontal frequency ==
:( 0.4 * [[#M_PRIME|M_PRIME]] * ( [[#TOTAL_ACTIVE_PIXELS|TOTAL_ACTIVE_PIXELS]] + [[#RIGHT_MARGIN_PIXELS|RIGHT_MARGIN_PIXELS]] + [[#LEFT_MARGIN_PIXELS|LEFT_MARGIN_PIXELS]] ) / [[#PIXEL_FREQ|PIXEL_FREQ]] / 1000000 ) ) )
:) ) / 2 / [[#M_PRIME|M_PRIME]] * 1000<br />
 
[[#IDEAL_DUTY_CYCLE|IDEAL_DUTY_CYCLE]] = [[#C_PRIME|C_PRIME]] - ( [[#M_PRIME]] * [[#IDEAL_H_PERIOD|IDEAL_H_PERIOD]] / 1000 )<br />
== Variable reference ==
These are the variables used in the equations above:
 
[[#H_BLANK_PIXELS|H_BLANK_PIXELS]] = ( ''ROUND'' ( [[#TOTAL_ACTIVE_PIXELS|TOTAL_ACTIVE_PIXELS]] * [[#IDEAL_DUTY_CYCLE|IDEAL_DUTY_CYCLE]] / ( 100 - [[#IDEAL_DUTY_CYCLE|IDEAL_DUTY_CYCLE]] ) / ( 2 * [[#CELL_GRAN_RND|CELL_GRAN_RND]] ) ) ) * 2 * [[#CELL_GRAN_RND|CELL_GRAN_RND]]<br />
==== C_PRIME ====
'''Todo''' Equals 40
 
[[#H_TOTAL|H_TOTAL]] = [[#TOTAL_ACTIVE_PIXELS|TOTAL_ACTIVE_PIXELS]] + [[#H_BLANK_PIXELS|H_BLANK_PIXELS]]<br />
==== M_PRIME ====
[[#H_FREQ|H_FREQ]] = [[#PIXEL_FREQ|PIXEL_FREQ]] / [[#H_TOTAL|H_TOTAL]]<br />
'''Todo''' Equals 600
[[#H_PERIOD|H_PERIOD]] = 1 / [[#H_FREQ|H_FREQ]]<br />
[[#V_SYNC_AND_BACK_PORCH|V_SYNC_AND_BACK_PORCH]] = ''ROUND'' ( [[#MIN_V_SYNC_AND_BACK_PORCH|MIN_V_SYNC_AND_BACK_PORCH]] * [[#H_FREQ|H_FREQ]] / 1000000 )<br />
[[#V_BACK_PORCH|V_BACK_PORCH]] = [[#V_SYNC_AND_BACK_PORCH|V_SYNC_AND_BACK_PORCH]] - [[#V_SYNC_RND|V_SYNC_RND]]<br />
[[#TOTAL_V_LINES|TOTAL_V_LINES]] = [[#V_LINES_RND|V_LINES_RND]] + [[#TOP_MARGIN_LINES|TOP_MARGIN_LINES]] + [[#BOTTOM_MARGIN_LINES|BOTTOM_MARGIN_LINES]] + [[#INTERLACE|INTERLACE]] + [[#V_SYNC_AND_BACK_PORCH|V_SYNC_AND_BACK_PORCH]] + [[#MIN_PORCH_RND|MIN_PORCH_RND]]<br />
[[#V_FIELD_RATE|V_FIELD_RATE]] = [[#H_FREQ|H_FREQ]] / [[#TOTAL_V_LINES|TOTAL_V_LINES]]<br />
 
'''if''' ( [[#INTERLACE_REQUIRED|INTERLACE_REQUIRED]] == '''true''')
==== CELL_GRAN_RND ====
{
Cell granularity - the amount of pixels the timings should be aligned to. For example, a VGA uses horizontal timings in multiples of the character clock, each character being 8 (graphics and some text modes) or 9 (most text modes) pixels wide. For a VGA graphics mode, you'll want to supply 8 here because of that. Depending on your specific hardware, you supply either 8 or 1.
:[[#V_FRAME_RATE|V_FRAME_RATE]] = [[#V_FIELD_RATE|V_FIELD_RATE]] / 2
} '''else''' {
:[[#V_FRAME_RATE|V_FRAME_RATE]] = [[#V_FIELD_RATE|V_FIELD_RATE]]
}</tt>
 
=== GTF Using resolution and horizontal frequency ===
==== MARGIN_PERCENT ====
<tt>
'''Todo''' Equals 1.8
 
[[#H_FREQ|H_FREQ]] = [[#H_FREQ_REQUIRED|H_FREQ_REQUIRED]]<br />
==== MIN_PORCH_RND ====
[[#V_SYNC_AND_BACK_PORCH|V_SYNC_AND_BACK_PORCH]] = ''ROUND'' ( [[#MIN_V_SYNC_AND_BACK_PORCH|MIN_V_SYNC_AND_BACK_PORCH]] * [[#H_FREQ|H_FREQ]] / 1000000 )<br />
'''Todo''' Equals 1. Used to force at least one unit of blanking around the sync period in order to not confuse graphics hardware?
[[#V_BACK_PORCH|V_BACK_PORCH]] = [[#V_SYNC_AND_BACK_PORCH|V_SYNC_AND_BACK_PORCH]] - [[#V_SYNC_RND|V_SYNC_RND]]<br />
[[#TOTAL_V_LINES|TOTAL_V_LINES]] = [[#V_LINES_RND|V_LINES_RND]] + [[#TOP_MARGIN_LINES|TOP_MARGIN_LINES]] + [[#BOTTOM_MARGIN_LINES|BOTTOM_MARGIN_LINES]] + [[#INTERLACE|INTERLACE]] + [[#V_SYNC_AND_BACK_PORCH|V_SYNC_AND_BACK_PORCH]] + [[#MIN_PORCH_RND|MIN_PORCH_RND]]<br />
[[#V_FIELD_RATE|V_FIELD_RATE]] = [[#H_FREQ|H_FREQ]] / [[#TOTAL_V_LINES|TOTAL_V_LINES]]<br />
 
'''if''' ( [[#INTERLACE_REQUIRED|INTERLACE_REQUIRED]] == '''true''') <br />
==== MIN_V_SYNC_AND_BACK_PORCH ====
{
'''Todo''' Equals 550
:[[#V_FRAME_RATE|V_FRAME_RATE]] = [[#V_FIELD_RATE|V_FIELD_RATE]] / 2
} '''else''' {
:[[#V_FRAME_RATE|V_FRAME_RATE]] = [[#V_FIELD_RATE|V_FIELD_RATE]]
}
 
[[#TOTAL_ACTIVE_PIXELS|TOTAL_ACTIVE_PIXELS]] = [[#H_PIXELS_RND|H_PIXELS_RND]] + [[#RIGHT_MARGIN_PIXELS|RIGHT_MARGIN_PIXELS]] + [[#LEFT_MARGIN_PIXELS|LEFT_MARGIN_PIXELS]]<br />
==== MARGINS_REQUIRED ====
[[#IDEAL_DUTY_CYCLE|IDEAL_DUTY_CYCLE]] = [[#C_PRIME|C_PRIME]] - ( [[#M_PRIME|M_PRIME]] / [[#H_FREQ|H_FREQ]] )<br />
The margins are used to add a visible black surrounding to the displayed picture. I assume small margins are intended to make sure the entire picture is still visible when the picture isn't perfectly centered on the screen.
[[#H_BLANK_PIXELS|H_BLANK_PIXELS]] = ( ''ROUND'' ( [[#TOTAL_ACTIVE_PIXELS|TOTAL_ACTIVE_PIXELS]] * [[#IDEAL_DUTY_CYCLE|IDEAL_DUTY_CYCLE]] / ( 100 - [[#IDEAL_DUTY_CYCLE|IDEAL_DUTY_CYCLE]] ) / ( 2 * [[#CELL_GRAN_RND|CELL_GRAN_RND]] ) ) ) * 2 * [[#CELL_GRAN_RND|CELL_GRAN_RND]]<br />
[[#H_TOTAL|H_TOTAL]] = [[#TOTAL_ACTIVE_PIXELS|TOTAL_ACTIVE_PIXELS]] + [[#H_BLANK_PIXELS|H_BLANK_PIXELS]]<br />
[[#H_PERIOD|H_PERIOD]] = 1 / [[#H_FREQ|H_FREQ]]<br />
[[#PIXEL_FREQ|PIXEL_FREQ]] = [[#H_TOTAL|H_TOTAL]] * [[#H_FREQ|H_FREQ]]<br />
</tt>
 
=== Variable reference ===
In theory it would be possible to use margins to simulate a small screen on a larger screen, or to simulate different aspect ratios perfectly. For example, if you were setting up a 640 * 480 video mode on a 16:10 display you could make the left and right margin 64 pixels each (with no top or bottom margins), so that it looks exactly the same as it would on a 4:3 display, rather than being stretched to fit. The opposite is also possible (e.g. displaying 16:10 video data on a 4:3 display with "letterboxing"). Unfortunately the GTF calculations don't actually support different sized left/right and top/bottom margins.
These are the variables used in the equations above:
 
==== INTERLACE_REQUIREDHardware properties ====
These are constant for a given monitor. They describe the capabilities and limitations of a CRT.
There are two kinds of video modes, interlaced and progressive modes. Progressive modes display the full frame in one go, while interlaced modes display each other scanline in each run, taking two frames to render the complete picture. Normally, you don't want this, and several video cards don't support it, so you will normally want to supply '''false''' here.
 
{{Anchor|C_PRIME}}
==== V_LINES ====
''' C_PRIME '''
Vertical resolution of the display you want. For a 640x480 resolution, supply 480.
:Defaults to 40, the actual value can be computed from EDID data.
 
{{Anchor|M_PRIME}}
==== H_PIXELS ====
''' M_PRIME '''
Horizontal resolution of the display you want. For a 640x480 resolution, supply 640. Note that video cards will usually want this to be a multiple of eight because of [[#CELL_GRAN_RND|cell granularity]].
:Defaults to 600, the actual value can be computed from EDID data.
 
{{Anchor|CELL_GRAN_RND}}
= Brendan's Original Posts =
'''CELL_GRAN_RND'''
>Any problems if I wikify this?
:Cell granularity - the amount of pixels the timings should be aligned to. For example, a VGA uses horizontal timings in multiples of the character clock, each character being 8 (graphics and some text modes) or 9 (most text modes) pixels wide. For a VGA graphics mode, you'll want to supply 8 here because of that. Depending on your specific hardware, the common values are either 8 or 1.
None at all - IMHO this information is required just to use VBE reliably; along with EDID (but you can find version 1.1 of the EDID data structures on Wikipedia) and details for the VBE DDC function (which VESA will let you have for free).
 
{{Anchor|MIN_PORCH_RND}}
However, I should point out that this information is incomplete - the value of certain constants are missing from my original post. The default values for these constants are: CELL_GRAN_RND = 8, MARGIN_PRECENT = 1.8, MIN_PORCH_RND = 1, MIN_V_SYNC_AND_BACK_PORCH = 550, C_PRIME = 40 and M_PRIME = 600. I'd also mention that for my version of the formulas REFRESH_RATE_REQUIRED, V_FIELD_RATE_REQUIRED, H_FREQ_REQUIRED, PIXEL_FREQ_REQUIRED, V_FIELD_RATE, H_FREQ, PIXEL_FREQ are all in Hz (and not a mixture of Hz, KHz and MHz), which helps to simplify the formulas.
'''MIN_PORCH_RND'''
:Usually 1. Probably used to force at least one unit of blanking around the sync period in order to not confuse graphics hardware that can not handle an absence of blanking around the synchronisation pulse.
 
{{Anchor|MIN_V_SYNC_AND_BACK_PORCH}}
There's also some strange things that can happen with these formulas. For example, if any of the calculations give a negative result then it indicates invalid input (e.g. if the PIXEL_FREQ_REQUIRED input parameter is too low, then you can end up with horizontal blanking that takes "negative N us"). In practice, some of these calculations probably have an allowed range (e.g. things like "horizontal blanking must be >= 20% of the horizontal total") but I've been unable to find anything indicating what the allowed ranges for anything is. :(
'''MIN_V_SYNC_AND_BACK_PORCH'''
:The time in microseconds the monitor needs to detect the vertical synchronisation signal and subsequently retrace to the top-left corner of the screen. Defaults to 550.
 
{{Anchor|V_SYNC_RND}}
---------
'''V_SYNC_RND'''
:The amount of scanlines with the vertical synchronisation pulse active. '''Todo''' Seems to depend on something VESA doesn't tell you. Equals 3, although two scanlines are used in legacy VGA mode 12/13.
 
{{Anchor|H_SYNC_PERCENT}}
This is for my own reference, and in case anyone is wondering what they look like... The GTF formulas.
'''H_SYNC_PERCENT'''
: The percentage of a scanline that should have the synchronisation pulse active. Equals 8%
 
==== Video mode inputs ===
There's actually 3 separate calculations here - finding all timing parameters from X & Y resolution and desired refresh rate, finding all timing parameters from X & Y resolution and desired horizontal frequency, and finding all timing parameters from X & Y resolution and desired pixel clock frequency.
These form the request of the user/programmer.
 
{{Anchor|MARGINS_REQUIRED}}
===GTF Formulas For Using Desired Refresh Rate===
'''MARGINS_REQUIRED'''
<pre>
:The margins are used to add a visible black surrounding to the displayed picture. I assume small margins are intended to make sure the entire picture is still visible when the picture isn't perfectly centered on the screen.
H_PIXELS_RND = ( ROUND ( H_PIXELS / CELL_GRAN_RND ) ) * CELL_GRAN_RND
 
:In theory it would be possible to use margins to simulate a small screen on a larger screen, or to simulate different aspect ratios perfectly. For example, if you were setting up a 640 * 480 video mode on a 16:10 display you could make the left and right margin 64 pixels each (with no top or bottom margins), so that it looks exactly the same as it would on a 4:3 display, rather than being stretched to fit. The opposite is also possible (e.g. displaying 16:10 video data on a 4:3 display with "letterboxing"). Unfortunately the GTF calculations don't actually support different sized left/right and top/bottom margins.
IF ( INTERLACE_REQUIRED == "y") {
V_LINES_RND = ROUND ( V_LINES / 2 )
V_FIELD_RATE_REQUIRED = REFRESH_RATE_REQUIRED * 2
INTERLACE = 0.5
} else {
V_LINES_RND = ROUND ( V_LINES) )
V_FIELD_RATE_REQUIRED = REFRESH_RATE_REQUIRED
INTERLACE = 0
}
 
{{Anchor|MARGIN_PERCENT}}
IF ( MARGINS_REQUIRED == "y" ) {
'''MARGIN_PERCENT'''
TOP_MARGIN_LINES = ROUND ( MARGIN_PRECENT / 100 * V_LINES_RND )
:'''(Fixme: Percentage!)''' Amount of margins you want to have around your screen. VESA suggests a default of 1.8 to allow for screens that do not perfectly fit the image to the center.
BOTTOM_MARGIN_LINES = ROUND ( MARGIN_PRECENT / 100 * V_LINES_RND )
LEFT_MARGIN_PIXELS = ( ROUND ( ( H_PIXELS_RND * MARGIN_PRECENT / 100 / CELL_GRAN_RND ) , 0 ) ) * CELL_GRAN_RND
RIGHT_MARGIN_PIXELS = ( ROUND ( ( H_PIXELS_RND * MARGIN_PRECENT / 100 / CELL_GRAN_RND ) , 0 ) ) * CELL_GRAN_RND
} else {
TOP_MARGIN_LINES = 0
BOTTOM_MARGIN_LINES = 0
LEFT_MARGIN_PIXELS = 0
RIGHT_MARGIN_PIXELS = 0
}
 
{{Anchor|INTERLACE_REQUIRED}}
H_PERIOD_ESTIMATE = ( 1 / V_FIELD_RATE_REQUIRED - MIN_V_SYNC_AND_BACK_PORCH / 1000000 ) / ( V_LINES_RND + 2 * TOP_MARGIN_LINES + MIN_PORCH_RND + INTERLACE ) * 1000000
'''INTERLACE_REQUIRED'''
:There are two kinds of video modes, interlaced and progressive modes. Progressive modes display the full frame in one go, while interlaced modes display each other scanline in each run, taking two frames to render the complete picture. Normally, you don't want this, and several video cards don't support it, so you will normally want to supply '''false''' here.
 
{{Anchor|V_LINES}}
V_SYNC_AND_BACK_PORCH = ROUND ( MIN_V_SYNC_AND_BACK_PORCH / H_PERIOD_ESTIMATE )
'''V_LINES '''
:Vertical resolution of the display you want. For a 640x480 resolution, supply 480.
 
{{Anchor|H_PIXELS}}
V_BACK_PORCH = V_SYNC_AND_BACK_PORCH - V_SYNC_RND
'''H_PIXELS '''
:Horizontal resolution of the display you want. For a 640x480 resolution, supply 640. Note that video cards will usually want this to be a multiple of eight because of [[#CELL_GRAN_RND|cell granularity]].
 
{{Anchor|PIXEL_FREQ_REQUIRED}}
TOTAL_V_LINES = V_LINES_RND + TOP_MARGIN_LINES + BOTTOM_MARGIN_LINES + V_SYNC_AND_BACK_PORCH + INTERLACE + MIN_PORCH_RND
'''PIXEL_FREQ_REQUIRED'''
:The speed of the dot clock (or pixel clock), in pixels per second. This is usually the same as the dot clock's frequency in Hz, but in some cases there's a factor two difference (2x the frequency when the clock is being doubled, half the frequency when pixels are emitted every other cycle) The dot clock is usually limited by the video card, as higher clocks are needed for higher framerates and resolutions.
 
{{Anchor|REFRESH_RATE_REQUIRED}}
V_FIELD_RATE_ESTIMATE = 1000000 / H_PERIOD_ESTIMATE / TOTAL_V_LINES
'''REFRESH_RATE_REQUIRED '''
:The amount of fields per second in Hz. This is also the number of frames per second for non-interlaced modes, or twice the number of frames per second for interlaced modes.
 
{{Anchor|H_FREQ_REQUIRED}}
H_PERIOD = H_PERIOD_ESTIMATE * V_FIELD_RATE_ESTIMATE / V_FIELD_RATE_REQUIRED
'''H_FREQ_REQUIRED'''
:The desired horizontal frequency in Hz. In the most common use, you'll want this to be the maximum horizontal frequency of the monitor, to find the best refresh rate possible that doesn't violate monitor limitations.
 
==== Outputs ====
V_FIELD_RATE = 1000000 / H_PERIOD / TOTAL_V_LINES
The final results of the GTF formula. These correspond to the parameters of the VGA CRTC model.
 
{{Anchor|PIXEL_FREQ}}
IF ( INTERLACE_REQUIRED == "y") {
'''PIXEL_FREQ'''
V_FRAME_RATE = V_FIELD_RATE / 2
:The dot clock required (check units?)
} else {
V_FRAME_RATE = V_FIELD_RATE
}
 
{{Anchor|H_TOTAL}}
TOTAL_ACTIVE_PIXELS = H_PIXELS_RND + LEFT_MARGIN_PIXELS + RIGHT_MARGIN_PIXELS
'''H_TOTAL'''
:Amount of pixels in a scanline
 
{{Anchor|LEFT_MARGIN_PIXELS}}
IDEAL_DUTY_CYCLE = C_PRIME - M_PRIME * H_PERIOD / 1000
'''LEFT_MARGIN_PIXELS '''
:Amount of margin at the left
 
{{Anchor|RIGHT_MARGIN_PIXELS}}
H_BLANK_PIXELS = ( ROUND ( ( TOTAL_ACTIVE_PIXELS * IDEAL_DUTY_CYCLE / ( 100 - IDEAL_DUTY_CYCLE ) / ( 2 * CELL_GRAN_RND ) ) ) ) * 2 * CELL_GRAN_RND
'''RIGHT_MARGIN_PIXELS '''
:Amount of margin at the right
 
{{Anchor|H_SYNC}}
TOTAL_PIXELS = TOTAL_ACTIVE_PIXELS + H_BLANK_PIXELS
'''H_TOTAL'''
:The duration of horizontal sync in pixels
 
{{Anchor|H_BACK_PORCH}}
PIXEL_FREQ = TOTAL_PIXELS / H_PERIOD * 1000000
'''H_BACK_PORCH'''
:The amount of pixels between the horizontal sync pulse and the start of the next scanline
 
{{Anchor|H_FRONT_PORCH}}
H_FREQ = 1 / H_PERIOD</pre>
'''H_BACK_PORCH'''
:The amount of pixels between the end of active display and the start of the horizontal sync pulse
 
{{Anchor|TOTAL_V_LINES}}
'''TOTAL_V_LINES'''
:The amount of scanlines in a frame
 
{{Anchor|TOP_MARGIN_LINES}}
===GTF Formulas For Using Horizontal Frequency===
'''TOP_MARGIN_LINES '''
<pre>
:Amount of margin at the top.
H_PIXELS_RND = ( ROUND ( H_PIXELS / CELL_GRAN_RND ) ) * CELL_GRAN_RND
 
{{Anchor|BOTTOM_MARGIN_LINES}}
IF ( INTERLACE_REQUIRED == "y") {
'''BOTTOM_MARGIN_LINES '''
V_LINES_RND = ROUND ( V_LINES / 2 )
:Amount of margin at the bottom
INTERLACE = 0.5
} else {
V_LINES_RND = ROUND ( V_LINES) )
INTERLACE = 0
}
 
{{Anchor|V_BACK_PORCH}}
IF ( MARGINS_REQUIRED == "y" ) {
'''V_BACK_PORCH'''
TOP_MARGIN_LINES = ROUND ( MARGIN_PRECENT / 100 * V_LINES_RND )
:The amount of scanlines between the Vertical Sync pulse and the start of the next field
BOTTOM_MARGIN_LINES = ROUND ( MARGIN_PRECENT / 100 * V_LINES_RND )
LEFT_MARGIN_PIXELS = ( ROUND ( ( H_PIXELS_RND * MARGIN_PRECENT / 100 / CELL_GRAN_RND ) , 0 ) ) * CELL_GRAN_RND
RIGHT_MARGIN_PIXELS = ( ROUND ( ( H_PIXELS_RND * MARGIN_PRECENT / 100 / CELL_GRAN_RND ) , 0 ) ) * CELL_GRAN_RND
} else {
TOP_MARGIN_LINES = 0
BOTTOM_MARGIN_LINES = 0
LEFT_MARGIN_PIXELS = 0
RIGHT_MARGIN_PIXELS = 0
}
 
{{Anchor|V_FRONT_PORCH}}
H_FREQ = H_FREQ_REQUIRED
'''V_FRONT_PORCH'''
:The amount of scanlines between the end of the field and the start of vertical retrace
 
The remaining three components needed to generate a complete signal are inputs. For reference, these are: [[#H_PIXELS|H_PIXELS]], [[#V_LINES|V_LINES]] which form the resolution, and [[#V_SYNC_RND|V_SYNC_RND]], which is a constant for a given monitor.
V_SYNC_AND_BACK_PORCH = ROUND ( MIN_V_SYNC_AND_BACK_PORCH * H_FREQ / 1000000 )
 
==== Intermediates ====
V_BACK_PORCH = V_SYNC_AND_BACK_PORCH - V_SYNC_RND
Other results that are either byproducts, but may be useful for error and compatibility checking.
 
{{Anchor|V_LINES_RND}}
TOTAL_V_LINES = V_LINES_RND + TOP_MARGIN_LINES + BOTTOM_MARGIN_LINES + INTERLACE + V_SYNC_AND_BACK_PORCH + MIN_PORCH_RND
'''V_LINES_RND '''
:Amount of active display scanlines per frame. Equals [[#V_LINES|the Y resolution]] unless interlaced modes are used.
 
{{Anchor|H_PIXELS_RND}}
V_FIELD_RATE = H_FREQ / TOTAL_V_LINES
'''H_PIXELS_RND '''
:Actual horizontal resolution used. Basically contains [[#H_PIXELS|the X resolution]] rounded to the nearest allowed boundary.
 
{{Anchor|V_FIELD_RATE_REQUIRED}}
IF ( INTERLACE_REQUIRED == "y") {
'''V_FIELD_RATE_REQUIRED '''
V_FRAME_RATE = V_FIELD_RATE / 2
:Rate of complete images being sent to the monitor per second. Unless interlaced mode is used, equals the refresh rate.
} else {
V_FRAME_RATE = V_FIELD_RATE
}
 
{{Anchor|H_FREQ}}
TOTAL_ACTIVE_PIXELS = H_PIXELS_RND + RIGHT_MARGIN_PIXELS + LEFT_MARGIN_PIXELS
'''H_FREQ'''
:The horizontal frequency in Hz
 
{{Anchor|H_PERIOD}}
IDEAL_DUTY_CYCLE = C_PRIME - ( M_PRIME / H_FREQ )
'''H_PERIOD'''
:The time in seconds spent on a scanline
 
{{Anchor|H_PERIOD_ESTIMATE}}
H_BLANK_PIXELS = ( ROUND ( TOTAL_ACTIVE_PIXELS * IDEAL_DUTY_CYCLE / ( 100 - IDEAL_DUTY_CYCLE ) / ( 2 * CELL_GRAN_RND ) ) ) * 2 * CELL_GRAN_RND
'''H_PERIOD'''
:The initial estimate of time in seconds spent on a scanline
 
{{Anchor|INTERLACE}}
TOTAL_PIXELS = TOTAL_ACTIVE_PIXELS + H_BLANK_PIXELS
'''INTERLACE'''
:Interlaced modes are indicated by skipping half a scanline, so that the horizontal sync shifts half a period. Equals 0 or 0.5 depending on whether the interlace signal is included.
 
{{Anchor|V_SYNC_AND_BACK_PORCH}}
H_PERIOD = 1 / H_FREQ
'''V_SYNC_AND_BACK_PORCH'''
:The number of scanlines spent on VSync and bottom blanking
 
{{Anchor|V_FIELD_RATE_ESTIMATE}}
PIXEL_FREQ = TOTAL_PIXELS * H_FREQ
'''V_FIELD_RATE_ESTIMATE'''
</pre>
:The initial estimate of fields per second (check unit?)
 
{{Anchor|V_FIELD_RATE}}
===GTF Formulas For Using Pixel Clock Frequency===
'''V_FIELD_RATE'''
<pre>
:The number of fields per second (check unit?)
H_PIXELS_RND = ( ROUND ( H_PIXELS / CELL_GRAN_RND ) ) * CELL_GRAN_RND
 
{{Anchor|V_FRAME_RATE}}
IF ( INTERLACE_REQUIRED == "y") {
'''V_FRAME_RATE'''
V_LINES_RND = ROUND ( V_LINES / 2 )
:The number of frames per second (check unit?)
INTERLACE = 0.5
} else {
V_LINES_RND = ROUND ( V_LINES) )
INTERLACE = 0
}
 
{{Anchor|TOTAL_ACTIVE_PIXELS}}
PIXEL_FREQ = PIXEL_FREQ_REQUIRED
'''TOTAL_ACTIVE_PIXELS'''
:The amount of horizontally visible pixels, which equals the active display plus overscan
 
{{Anchor|IDEAL_DUTY_CYCLE}}
IF ( MARGINS_REQUIRED == "y" ) {
'''IDEAL_DUTY_CYCLE'''
TOP_MARGIN_LINES = ROUND ( MARGIN_PRECENT / 100 * V_LINES_RND )
:Percentage. One of the steps to compute the amount of horizontal blanking.
BOTTOM_MARGIN_LINES = ROUND ( MARGIN_PRECENT / 100 * V_LINES_RND )
LEFT_MARGIN_PIXELS = ( ROUND ( ( H_PIXELS_RND * MARGIN_PRECENT / 100 / CELL_GRAN_RND ) , 0 ) ) * CELL_GRAN_RND
RIGHT_MARGIN_PIXELS = ( ROUND ( ( H_PIXELS_RND * MARGIN_PRECENT / 100 / CELL_GRAN_RND ) , 0 ) ) * CELL_GRAN_RND
} else {
TOP_MARGIN_LINES = 0
BOTTOM_MARGIN_LINES = 0
LEFT_MARGIN_PIXELS = 0
RIGHT_MARGIN_PIXELS = 0
}
 
{{Anchor|IDEAL_H_PERIOD}}
TOTAL_ACTIVE_PIXELS = H_PIXELS_RND + RIGHT_MARGIN_PIXELS + LEFT_MARGIN_PIXELS
'''IDEAL_H_PERIOD'''
:Optimal time to spend on a scanline. This can usually not be achieved since a scanline is a integer number of pixels.
 
{{Anchor|H_BLANK_PIXELS}}
IDEAL_H_PERIOD = ( ( C_PRIME - 100 ) + ( SQRT ( ( ( 100 - C_PRIME ) ^ 2 ) + ( 0.4 * M_PRIME * ( TOTAL_ACTIVE_PIXELS + RIGHT_MARGIN_PIXELS + LEFT_MARGIN_PIXELS ) / PIXEL_FREQ / 1000000 ) ) ) ) / 2 / M_PRIME * 1000
'''H_BLANK_PIXELS'''
 
:The total amount of blank pixels horizontally (including horizontal sync)
IDEAL_DUTY_CYCLE = C_PRIME - ( M_PRIME * IDEAL_H_PERIOD / 1000 )
 
H_BLANK_PIXELS = ( ROUND ( TOTAL_ACTIVE_PIXELS * IDEAL_DUTY_CYCLE / ( 100 - IDEAL_DUTY_CYCLE ) / ( 2 * CELL_GRAN_RND ) ) ) * 2 * CELL_GRAN_RND
 
TOTAL_PIXELS = TOTAL_ACTIVE_PIXELS + H_BLANK_PIXELS
 
H_FREQ = PIXEL_FREQ / TOTAL_PIXELS
 
H_PERIOD = 1 / H_FREQ
 
V_SYNC_AND_BACK_PORCH = ROUND ( MIN_V_SYNC_AND_BACK_PORCH * H_FREQ / 1000000 )
 
V_BACK_PORCH = V_SYNC_AND_BACK_PORCH - V_SYNC_RND
 
TOTAL_V_LINES = V_LINES_RND + TOP_MARGIN_LINES + BOTTOM_MARGIN_LINES + INTERLACE + V_SYNC_AND_BACK_PORCH + MIN_PORCH_RND
 
V_FIELD_RATE = H_FREQ / TOTAL_V_LINES
 
IF ( INTERLACE_REQUIRED == "y") {
V_FRAME_RATE = V_FIELD_RATE / 2
} else {
V_FRAME_RATE = V_FIELD_RATE
}
</pre>
 
Note: The "round()" function here rounds to the nearest integer (it doesn't round down or round up).
 
Cheers,
 
Brendan
 
=== More VESA Rants ===
 
=== Brendan's Sidenotes ===
Quoted:
 
I think part of the problem is that the original GTF formulas from VESA are copied from their spreadsheet, so that (for a silly example) instead of doing something like:
Line 371 ⟶ 386:
frequency = 10000000
period = 1 / frequency seconds
 
 
They'll do:
Line 377 ⟶ 391:
frequency_in_MHz = 10
period_in_ms = 1 / (frequency_in_MHz * 1000000) * 1000
 
 
And then simplify it to:
Line 383 ⟶ 396:
frequency_in_MHz = 10
period_in_ms = 1 / frequency_in_MHz / 1000
 
 
And then they'll remove any indication of what they've done:
Line 389 ⟶ 401:
frequency = 10
period = 1 / frequency / 1000
 
 
So that in the end, the formulas from VESA end up being a confusing mess where you're never too sure if there's a hidden scaling factor or not. Another simple example (that isn't made up) is "MARGINS_PERCENT", which is a value that would range from 0 to 50 that's typically divided by 100; and isn't a value that ranges from 0 to 0.5 that doesn't need scaling.
Line 402 ⟶ 413:
 
Finally, all of these calculations can be simplified a lot if you assume that the "default GTF values" are being used. I want to provide simplified versions of the formulas, because most of the time you can use the default GTF values and can skip a lot of work.
 
== See Also ==
 
=== Forum ===
* [[Topic:19119|Getting a list of usable video modes]] - with emphasis on ''usable''
 
=== External Links ===
* [http://www.cs.unc.edu/Research/stc/FAQs/Video/GTF_V1R1.xls http://www.cs.unc.edu/Research/stc/FAQs/Video/GTF_V1R1.xls] is one of the GTF spreadsheets you can find on the web.
* [http://en.wikipedia.org/wiki/VGA_connector VGA connector] on wikipedia
* [http://en.wikipedia.org/wiki/EDID EDID] on wikipedia
 
[[Category:Video]]
Anonymous user