Setting Up X11
The display controller, usually called a CRT (Cathode Ray Tube) controller, is the part of the display board which creates the signals we've just been talking about. Early display controllers were designed to produce signals that were compatible with TVs. They had to produce a signal with sync pulses, front and back porches, and picture data in between. Modern display controllers can do a lot more, but the principles remain the same.
The first part of the display controller creates the framework we're looking for: the horizontal and vertical sync pulses, blanking, and picture information, which is represented as a series of points or dots. To count, we need a pulse source, which also determines the duration of individual dots, so it is normally called a dot clock. For reasons lost in history, CRT controllers start counting at the top left of the display, and not at the vertical sync pulse, which is the real beginning of the display. To define a line to the horizontal deflection, we need to set four CRTC registers to tell it:
The Horizontal Display End (HDE) register specifies how many dots we want on each line. After the CRTC has counted this many pixels, it stops outputting picture data to the display.
The Start Horizontal Retrace (SHR) register specifies how many dot clock pulses occur before the sync pulse starts. The difference between the contents of this register and the contents of the HDE register defines the length of the front porch.
The End Horizontal Retrace (EHR) register defines the end of the sync pulse. The width of the sync pulse is the difference between the contents of this register and the SHR register.
The Horizontal Total (HT) register defines the total number of dot clocks per line. The width of the back porch is the difference between the contents of this register and the EHR register.
In addition, the Start Horizontal Blanking (SHB) and End Horizontal Blanking (EHB) registers define when the video signals are turned off and on. The server sets these registers automatically, so we don't need to look at them in more detail.
The control of the vertical deflection is similar. In this case, the registers are Vertical Display End (VDE), Start Vertical Retrace (SVR), End Vertical Retrace (EVR), Vertical Total (VT), Start Vertical Blanking (SVB), and End Vertical Blanking (EVB). The values in these registers are counted in lines.
VGA hardware evolved out of older 8 bit character-based display hardware, which counted lines in characters, not dot clocks. As a result, all of these registers are 8 bits wide. This was adequate for character displays, but it's a problem when counting dots. The maximum value you can set in any of these registers is 255. The designers of the VGA resorted to a number of nasty kludges to get around this problem. The horizontal registers count in groups of 8 dot clocks, so they can represent up to 2048 dot clocks. The vertical registers overflow into an overflow register. Even so, the standard VGA can't count beyond 1024 lines. Super VGAs vary in how they handle this problem, but typically they add additional overflow bits. To give you an idea of how clean the VGA design is, on a standard VGA, the real Vertical Total (total number of lines on the display) is defined as the value of the VT register +256 if bit 0 of the overflow register is set, or +512 if bit 5 of the overflow register is set.
One of the steps in setting up XFree86 is to define these register values. Fortunately, you don't have to worry about which bits to set in the overflow register. The mode lines count in dots, and it's up to the server to convert the dot count into something that the display board can understand. A typical Mode line looks like:
"640x480a" 28 640 680 728 776 480 480 482 494
These ten values are required. In addition, you may specify modifiers at the end of the line. The values are:
A label for the resolution line. This must be enclosed in quotation marks, and is used to refer to the line from other parts of the XF86Config file. It is the only optional field—further down we'll look at what happens if it isn't present. Traditionally, the label represents the resolution of the display mode, but it doesn't have to. In this example, the resolution really is 640*480, but the a at the end of the label is a clue that it's an alternative value.
The clock frequency. This may be a label, like the mode line label, but sometimes it really does have to match the clock frequency in MHz.
The Horizontal Display End, which goes into the HDE register. This value and all that follow are specified in dots. The server mangles them as the display board requires and puts them in the corresponding CRTC register.
The Start Horizontal Retrace (SHR) value.
The End Horizontal Retrace (EHR) value.
The Horizontal Total (HT) value.
The Vertical Display End (VDE) value. This value and the three following are specified in lines.
The Start Vertical Retrace (SVR) value.
The End Vertical Retrace (EVR) value.
The Vertical Total (VT) value.
As I noted, not every mode line needs a label. It's possible to have a number of mode lines for the same resolution, each with a different dot clock frequency. In this case, only the first line of a group needs the label.
This is pretty dry stuff. To make it easier to understand, let's look at how we would set a typical VGA display with 640*480 pixels. Sure, you can find values for this setup in any release of XFree86, but that doesn't mean that they're the optimum for your system. We want a no-flicker display, which we'll take to mean a vertical frequency of at least 72 Hz, and of course we don't want interlace. Our multiscan monitor can any handle horizontal frequency between 15 and 40 kHz, so let's head for the highest and see what happens.
First, we need to create our lines. They contain 640 pixels, two porches, and a sync pulse. The only value we really know for sure is the number of pixels. How long should the porches and the sync pulses be? If you have a good monitor with good documentation, it should tell you, but most monitor manufacturers don't seem to believe in good documentation. When they do document the values, they vary significantly from monitor to monitor, and even from mode to mode. They're not as critical as they look. For example, here are some typical values from my NEC 5D handbook—Horizontal sync pulse: 1 to 4 µs, front porch 0.18 to 2.1 µs, back porch 1.25 to 3.56 µs.
As we'll see, the proof of these timing parameters is in the display. If the display looks good, the parameters are OK. I don't know of any way to damage the monitor purely by modifying these parameters, but there are other good reasons to stick to this range. As a rule of thumb, if you set each of the three values to 2 µs to start with, you won't go too far wrong. Alternatively, you could start with the NTSC standard values. The standard specifies that the horizontal sync pulse lasts for 4.2 to 5.1 iµs, the front porch must be at least 1.27 µs. NTSC doesn't define the length of the back porch—Winstead it defines the total line blanking, which lasts for 8.06 to 10.3 µs. For our purposes, we can consider the back porch to be the length of the total blanking minus the lengths of the front porch and the sync pulse. If you take values somewhere in the middle of the ranges, you get a front porch of 1.4 µs, a sync pulse of 4.5 µs, and total blanking 9 µs, which implies a back porch of 9 - 1.4 - 4.5 = 3.1 µs.
For our example, let's stick to 2 µs per value. We have a horizontal frequency of 40 kHz, or 25 µs per line. After taking off our 6 µs of total blanking time, we have only 19 µs left for the display data. In order to get 640 pixels in this time, we need one pixel every 19/640 µs, or about 30 ns. This corresponds to a frequency of 33.6 MHz. This is our desired dot clock.
The next question is: Do we have a dot clock of this frequency? Maybe. This should be in your display board documentation, but I'll take a bet that it's not. Never mind, the XFree86 server is clever enough to figure this out for itself—we'll see how the next article. At the moment, let's assume that you do have a dot clock of 33 MHz. You now need to calculate four register values to define the horizontal lines:
The first value is the Horizontal Display End, the number of pixels on a line. That's easy enough—it's 640.
You calculate SHR by adding the number of dot clocks that elapse during the front porch to the value of HDE. Recall that we decided on a front porch of 2 µs. In this time, a 33 MHz clock will count 66 cycles. So we add 66, right? Wrong. Remember that the VGA registers count in increments of 8 pixels, so we need to round the width of the front porch to a multiple of 8. In this case, we round it to 64, so we set SHR to 640 + 64 = 704.
The next value we need is EHR, which is SHR plus the width of the horizontal retrace, again 64 dot clocks, so we set that to 704 + 64 = 768.
The final horizontal value is HT. Again, we add the front porch—64 dot clocks—to EHR and get 768 + 64 = 832.
Next, we need another four values to define the vertical scan. Again, of the four values we need, we only know the number of lines. How many lines do we use for the porches and the vertical sync? As we've seen, NTSC uses about 45 lines for the three combined, but in practice modern monitors get by with many fewer. Again referring to the Multisync manual, we get a front porch of betwwen 0.014 and 1.2 µs, a sync pulse of between 0.06 and 0.113 µs, and a back porch of between 0.54 and 1.88 µs. But how many lines is that?
To figure that out, we need to know our real horizontal frequency. We were aiming at 40 kHz, but we made a couple of tradeoffs along the way. The real horizontal frequency is the dot clock divided by the horizontal total, in this case 33 MHz / 832, which gives us 39.66 kHz—not bad at all. At that frequency, a line lasts just over 25 µs, so our front porch can range between ½ and 48 lines, our sync pulse between 2 and 5 lines, and the back porch between 10 and 75 lines. Do these timings make any sense? No, they don't—they're just values which the monitor can accept.
In practice, we can go for the lowest value in each case. It's difficult to specify a value of ½, so we'll take a single line front porch. We'll take two lines of sync pulse and 10 lines of back porch. This gives us:
VDE is 480.
SVR is 481.
EVR is 483.
VT is 493.
Now we can calculate our vertical frequency, which is the horizontal frequency divided by the vertical total, or 39.66/493 kHz, which is 80.4 Hz—not bad at all. By comparison, if you use the standard entry in XF86config, you will get a horizontal frequency of 31.5 kHz and a vertical frequency of only 60 Hz.
If you know the technical details of your monitor and display board, it really is that simple. This method doesn't require much thought, and it creates results which work. This doesn't mean that they are optimal values—we'll look at that in the next article.
Greg Lehey is a partner in LEMIS-Lehey Micro-computer Systems. He resides in Germany.
- High-Availability Storage with HA-LVM
- Localhost DNS Cache
- DNSMasq, the Pint-Sized Super Dæmon!
- Real-Time Rogue Wireless Access Point Detection with the Raspberry Pi
- Days Between Dates: the Counting
- You're the Boss with UBOS
- The Usability of GNOME
- Linux for Astronomers
- PostgreSQL, the NoSQL Database
- Elementary, My Dear Linux User