PAL and NTSC on a VGA video card under X without external circuitry.

Warning: this has big pictures in small files

Why I did it.

My monitor died about mid January 2004.
My Mother suggested that I use the 34cm TV that wasn't being used at the time.
This just has composite and RF inputs, and composite outputs (it's a NEC N-3453).

What I did.

I first tried using just the green, but I couldn't do anything.
I then tried connecting the HSync and green pins together, and I was able to sort of see what I was doing.
I used VT1 (a text console that I'd actually set up at 1024x768). I tried to edit XF86Config-4, but (later I found) I was forgetting to change the horizontal frequency to 15-16kHz.
Failing that, I ran xf86cfg (the graphics mode XFree86 configurator). I was able to adjust the vertical total until I had a stable picture (albeit doubled up - 320x240 doublescan, 43Hz x 31kHz).
I then was able to edit the XF86Config-4 file to include a new Monitor section for the TV, which I set up to match the capabilities of this TV. Like so:
Section "Monitor"
	Identifier "NEC-TV"
	VendorName "NEC"
	ModelName  "N-3453"
	DisplaySize 272 204
	HorizSync 15 - 17
	VertRefresh 43 - 65
	Modeline "640x240@50"	16.7	640 788 848 1068  240 268 272 312    -hsync -vsync
	ModeLine "720x288@50"   16.7    720 828 888 1068  288 292 296 312    -hsync -vsync
EndSection
I've tried to get Interlacing, but the nv and nvidia drivers don't seem to support it on my hardware (a nVidia Geforce2 MX 400 - NV11). I've looked on Google, and they say that interlacing is not supported on hardware above the NV15.

I tried to use the greyscale visual on 8bpp, but a few programs did not like it (e.g. Mozilla, which only showed the underlines and not the actual text.
I eventually tried hooking 5 pins together - HSync, VSync, Red, Green and Blue. This made everything happy. I do have to disconnect it when rebooting, since the video card refuses to continue in POSTing when the 5 pins are hooked together, so on 11 February 2004, I'd be getting some components to convert the RGB to greyscale composite properly.

I later looked into PAL/NTSC colour encoders, but the only one listed in the DSE catalog has already been discontinued. So I would not be able to get one locally by the looks. The only good RGB to PAL/NTSC encoder that I could see from looking in Google would be the AD724.
I looked at its data sheet and found that it's fairly simple.
So I decided to try to get colour out of a mode with a 40MHz pixel clock. This is just over 9 pixels per full cycle of the 4.43MHz PAL colour subcarrier.
I finally got colour when the line length was a multiple of 9 pixels. This occurred at Horizontal Totals of 2520 and 2592 (280 and 288 cycles). The colour was out of phase a bit, so I went down to 9 x 4.43MHz, which is 39.899MHz. The colour was perfect now.
The modeline is:
ModeLine "2048x300" 39.899 2048 2316 2500 2520 300 304 308 312
Note that the video card can come fairly close (within 400ppm) to 39.899MHz, since 14.318MHz * 39 / 14 = 39.886MHz.
4.43MHz is close to 26/21 times 3.58MHz.

The pattern I was using is here:

Note that this is a NTSC pattern - it does not have the V reversed every other line.

Later, I decided to make 8 colour bars.
So, I created an NTSC pattern:

I then created a PAL pattern from that NTSC pattern:

Note that I actually made those from XPMs that were edited using Vim. They are here (bzipped to make them real small): PAL and NTSC.

I altered them so that I could feed them to PALcol, which I got from techmind.org's Software-based PAL colour decoding page.
Here's the output for PAL 4.43:

Here's the output for NTSC 3.58:

At the moment, because I've got the three colour pins hooked together, the third bar looks the brightest, and the second last bar the darkest.
The colours for PAL should be something like:
Orange  Pink    Magenta Red-
Blue   
Green-
Blue   
Blue-
Green  
Green   Red-
Green  
The colours for NTSC should be something like:
Orange  Peach   Purple  Red-
Blue   
Green-
Blue   
Blue-
Green  
Green   Red-
Green  

I've tried various modes, trying to get proper PAL and NTSC proportions (283.75 cycles per line for PAL 4.43 and 237.5 cycles per line for NTSC 3.58), but haven't had any success yet.

I have created a program that converts a PPM picture to a greyscale picture with PAL or NTSC encoding. It's source is here: ppmtopal.c. It uses the Netpbm library to read ppm files. It acts as a filter, taking a ppm file on stdin, and spitting out a pgm file with PAL or NTSC encoding on stdout. I have not decided what license to have it under yet - probably LGPL.
I've successfully encoded colour bars and the Windows logow.sys with it. Here they are:
Colour: Colour Bars and logow.sys
PAL: Colour Bars and logow.sys
NTSC: Colour Bars and logow.sys

My ultimate goal would be to create a program or library that encodes RGB to PAL/NTSC in real time. Unfortunately, it'd probably need CPU-specific optimization.

13 February 2004

On Wednesday, I got most of the components. The 74HC86 is on backorder, so I'm just using the resistors at the moment.
I've currently got it like:

Red    o---.
           |    _________
Green  o---*---| 22 Ohm  |---.
           |                 |
Blue   o---'                 |
                _________    |
VSync  o-------| 100 Ohm |---*----o  Out
                _________    |
HSync  o-------| 82 Ohm  |---'

Ground o--------------------------o Ground
I'm also using pins (the type used to hold fabric together whilst sewing) to connect with the VGA socket, instead of bare wires. The moire-like pattern (about 4 times the HSync frequency) is not as noticable now. The dark vertical lines, which are spaced about 64 pixels apart (from transients in the graphics chip?), are still visible, but are not as bad now.
The video signal is now about equivalent to 45 Ohms (Red, Green, Blue) driving a 45 Ohm local (Hsync and VSync) and 70 Ohm remote (TV) load. The HSync and VSync drive about 150 Ohms and 170 Ohms (sourcing about 20mA and 18mA, plus or minus about 5mA each) respectively.
It's not impedence matched, but at least it's better than a wired-and CSync driving into 70 Ohms, with a RGB source impedence of about 23 Ohms.

19 February 2004

I discovered that the crystal used by my Geforce2 MX 400 seems to be a 14.324MHz crystal instead of 14.318MHz as I had thought. The 39.899MHz mode reads as 39.903MHz according to grabmode (in the SVGATextMode package).
The 16.700MHz mode (720x288) reads as 16.712MHz. That's 14.324MHz * 14 / 12
The 32.216MHz mode (3.58x9) reads as 32.230MHz. That's 14.324MHz * 18 / 8
The 35.000MHz mode (PAL 15625) reads as 35.015MHz. That's 14.324MHz * 22 / 9
The 39.899MHz mode (4.43x9) reads as 39.904MHz. That's 14.324MHz * 39 / 14
So, the 39.899MHz mode is out by about 125ppm. On the other hand, the 32.216MHz and 35.000MHz modes are out by about 430ppm.
I cannot read the actual crystal at the moment (it's very close to the slot), so I cannot confirm that it actually is a 14.324MHz crystal.

16 March 2004

I've decided to put this project on SourceForge.net under GPL.
I hope to continue refining this project. However, the main reason for actively testing it is no longer an issue, since I have a monitor now.

Contact:

Please feel free to contact me via email at nothamtrap@austarnet.com.au.

This page copyright ©2004 Ben Peddell