Can you run NTSC at 1024x192, as long as every block of 4 pixels is really same
Dennis Ferron
Posts: 480
I'm writing a TV driver that will use 16 colors, but the Propeller only lets me do 2-bit color and I can only put four colors into a palette for a given block of 16 pixels. I thought I would get around that by just using the bit pattern 00_01_10_11 for the pixels and actually loading the colors I want the pixels to be into the palette register. Problem is, this would only work if you display only 4 pixels per waitvid; in reality you display 16 pixels per waitvid.
So I thought, what if I revv the pixel clock up so fast that it displays all 16 pixels in the time it normally takes to do 4, so that 4 pixels get output for every 1 "real" pixel on the TV? Then by loading the bit pattern 00_00_00_00__01_01_01_01__10_10_10_10__11_11_11_11 for the pixels, you could set the four palette colors and get four pixels of any color combination. Will this work? I realize it will throw off the timing for the color clock, and change all of my color codes. I'm not sure whether the color codes can tolerate a 4x speedup.
It also occurs to me that setting the vcfg mode to VGA, but outputting NTSC with the VGA mode set, may give me extra control to get around this. And it may be that I need more states for the outputs when the pixel clock is running 4x fast; I might actually have to run it even faster and use two palette entries for just one pixel.
Could this work?
So I thought, what if I revv the pixel clock up so fast that it displays all 16 pixels in the time it normally takes to do 4, so that 4 pixels get output for every 1 "real" pixel on the TV? Then by loading the bit pattern 00_00_00_00__01_01_01_01__10_10_10_10__11_11_11_11 for the pixels, you could set the four palette colors and get four pixels of any color combination. Will this work? I realize it will throw off the timing for the color clock, and change all of my color codes. I'm not sure whether the color codes can tolerate a 4x speedup.
It also occurs to me that setting the vcfg mode to VGA, but outputting NTSC with the VGA mode set, may give me extra control to get around this. And it may be that I need more states for the outputs when the pixel clock is running 4x fast; I might actually have to run it even faster and use two palette entries for just one pixel.
Could this work?
Comments
Actually, you can set VSCL so that FrameClocks = 4 * PixelClocks; that way the waitvid will end after 4 pixels have shifted out.
Here's a code snippet:
Check out CardboardGurus Easy NTSC program. Basically, it breaks down to one clock being 1/16 of the pixel clock timing period. From there, you can calculate the waitvid scale and framing to output the way shown here.
I've clocked up the video generator. Feeding it one byte per pixel ends up topping out at somewhere around 540 pixels or so, depending on how you code. It will easily go higher, using the 2 and 4 color modes, but it's gonna artifact and just generate more colors, or produce a monochrome display likely beyond most televisions. (My nice sony will do 640, and that's it.)
One way to get a 16 color display is to process the pixels in screen memory, shift them into position in the COG, then use a color lookup table (CLUT) in the COG (hub CLUT is too slow, IMHO) to map the colors to single byte color entries.
At 160 and probably 256 pixel horizontal resolution, there is enough time for this to happen. Higher and you might need to do tricks, like incorporate a scan line buffer in the COG, then fill it during all display times. Pixels can be packed in during HBLANK and overscan and during the actual scanline display. This might get you to 320, but I've not tried that.
Doing the waitvid trick, gets you direct pixel level access to the 125 colors the prop will generate without artifacting, multiple COG, or other sub-pixel / overlay tricks. About 80 of these are good, useful colors. I've a CLUT built in the high-color demo program that maps the 125 colors out.
grab long from video display (this is 8 pixels @ 16 colors)
shift 4 bits of it into temp storage
use that as index into CLUT
copy CLUT entry into tempoary long 4 pixel buffer
repeat 3 more times
do WAITVID
The code above reads directly from the HUB, but could easily read from the in COG buffer being built just ahead of the WAITVID wanting pixel data. There probably is enough time to do this in one COG, given moderate resolutions ~256 or less.
I thought I might go with 16 colors so that I can choose the ones that are closest to EGA colors, so that I can reuse graphics from old EGA computer games (like Commander Keen). I don't think I need all 80 or 64 colors. OTOH, 5 bit color might be a good compromise; it would still be a small CLUT, and 6 pixels would fit into a 32 bit long with only 2 wasted bits.
I'm wanting to use the same TV driver for a 3-d engine I'm planning, and also for a different, sprite-based game. I think that will work as long as the TV driver is just a "dumb" device that displays whatever scanline you feed it, and I can wrap the TV driver with other objects that generate the scan lines based on sprites or 3d math.
But if you always display at least 2 pixels of the same color together, you can go higher than 160 horizontally. And that's easy to arrange for sprite and tile games.