Understanding WAITVID
Vega256
Posts: 197
Hey,
I have been experimenting with WAITVID in different ways, however, I am not sure that I fully understand its function. If someone could confirm what I understand, I would appreciate it.
WAITVID is said to pass to the video generator two parameters; colors and pixels. I think that I understand colors. In 2-color mode, colors is a 32-bit value with two bytes representing two colors in the lower word. In 4-color mode, colors is a 32-bit value with four bytes representing four colors.
In 2-color mode, pixels is a 32-bit value representing 32 pixels with each bit being either 0 or 1 which in turn corresponds to the one of two values in colors.
In 4-color mode, pixels is a 32-bit value representing 16 pixels with every two bits being %00-%11 which in turn corresponds to the one of four values in colors.
If in 4-color mode, 16 pixels are generated, how is it possible that some graphics drivers, more or less pixels are said to be generated?
I have been experimenting with WAITVID in different ways, however, I am not sure that I fully understand its function. If someone could confirm what I understand, I would appreciate it.
WAITVID is said to pass to the video generator two parameters; colors and pixels. I think that I understand colors. In 2-color mode, colors is a 32-bit value with two bytes representing two colors in the lower word. In 4-color mode, colors is a 32-bit value with four bytes representing four colors.
In 2-color mode, pixels is a 32-bit value representing 32 pixels with each bit being either 0 or 1 which in turn corresponds to the one of two values in colors.
In 4-color mode, pixels is a 32-bit value representing 16 pixels with every two bits being %00-%11 which in turn corresponds to the one of four values in colors.
If in 4-color mode, 16 pixels are generated, how is it possible that some graphics drivers, more or less pixels are said to be generated?
Comments
The answer to your question has to do with the frame size. VSCL has two components. One is the pixel clock in terms of PLLA cycles. The other is the frame size, expressed the same way.
PLLA cycles are determined by how you setup the PLL, and are your base pixel "clock". Once that is determined, the actual number of pixels, and the size of the pixels output by the waitvid is controlled by VSCL.
Let's say the pixel clock is 5 PLLA, and one wants to output 4 pixels per waitvid. That would be a frame size of 5*4 = 20.
VSCL := 20 << 12 + 5
If you want 8 pixels, then it's:
VSCL := 40 << 12 + 5
Shift the frame size into the upper bits, then add the pixel size.
If you want 8 smaller pixels, it might be:
VSCL := 24 << 12 + 3
Larger pixels would be:
VSCL := 80 << 12 + 10
Waitvid ends when it's frame size is reached, not when all the data is consumed. Frame sizes are often used to produce specific delays in the signal, as well as sets of pixels.
Frame size is generally flexible, if one is using 2 or 4 color mode, because all the pixels can have adequate color data. If "full color" is desired, the frame size must be 4 pixels, or less.
"waitvid pixels, #%%3210" always outputs the same 4 pixels, essentially turning the colors argument into a pixels one, with a fixed set of pixels, where only the color varies. This depends on being able to set the frame size to a value other than the max number of pixels possible.
The higher the resolution desired, the shorter the overall waitvid period. This is the primary reason why full color drivers run at lower overall resolutions than 2 or 4 color ones. It's also why most tile drivers operate on 2 or 4 color tiles, and at the 16 or 32 pixel size.
Where you can use the full set of pixels, you've got more time in the waitvid, which basically equates to higher possible resolution, at the expense of color flexibility.
Edit: For NTSC TV, I like to use 2560 PLLA for the active area. This breaks down to nice pixel clocks, equalling 640, 512, 320, 256, 160, 128, 64, etc... pixels per scan line.
If 320 pixels are desired, 8 pixels per waitvid, then it's all calculated like this:
320 / 8 = 40 bytes of pixel data, 2 color.
2560 / 320 = 8 PLLA / pixel
VSCL := 64 << 12 + 8
40 waitvids required in two color mode, or 4 color mode.
2 color mode = 1 byte per 8 pixels; one word of color data
4 color mode = 1 word per 8 pixels; one long of color data
Full color needs to be 4 pixels, due to how waitvid works, so that's 80 waitvids!
VSCL := 32 << 12 + 8
Half the time!
One long of color data required per waitvid, pixels are fixed "#%%3210", or "#%%0123", depending on the output order desired. You get to reverse the pixels automatically when running waitvid this way.
If one cuts back on the color flexibility, perhaps 20 waitvids are required.
VSCL := 128 << 12 + 8
Now it's 16 pixels per frame, with only the opportunity to change colors once per frame, but there is a lot more compute time in the video loop too.
That's the classic Propeller video trade-off right there. Higher resolutions demand lower color depths and or flexibility in color placement.
I have noticed this especially. In some drivers, the colors argument is used as an entry from a palette and in other drivers, it is used as the color of the pixel while the pixel argument is %%3210. When the driver calls these pixels, are they referring to colors? One color on the TV can be composite of pixels if the resolution is small enough.
What people do then, is set the output order they want, "#%%3210", for example, and just put the colors into the waitvid, as if they were pixels. It's not about small pixels, or what the TV does. It's just the frame size allows arbitrary color placement.
If that same waitvid were extended by a pixel, say "#%%32102", now what happens? The color "2" will appear twice no matter what. This is essentially useless, but for some clever pattern or texture tricks. It has to be 4 pixels, so that the 4 colors can be placed anywhere in the frame.
Where there is "waitvid colors, pixels", there now is "waitvid colors, #%%3210", usually written as: "waitvid pixels, #%%3210", just because the colors long is now a pixels long, with each color displayed in order determined by the #%%3210 fixed pixel definition.
It's a hack, but a nice one!
That's a different thing, and the timing on the driver needs to be carefully controlled. Eric has a nice one in his blog "4x4 NTSC" doing exactly that, Apple ][ graphics style. When doing TV graphics that way, higher resolutions are used, say 640 or more pixels, and the pixels themselves render as colors, and groups of them render as white, or some "solid" color.
Of all the drivers produced, I think only Eric and I have gone down that artifact road. Eric has also done software generated color, with a fast PLLA, 14Mhz, manually "drawing" the color signal for some additional control not possible with straight pixel artifacting, or the Propeller chroma signal generator.
Really, the "waitvid pixels, #%%3210" is just using a 4 pixel frame to achieve any color, any pixel placement. Since 4 colors can be defined per waitvid, it makes sense that 4 pixel frames would come with no limitations on color placement.
We either have a 2 color, or 4 color palette, or "full color", one byte per pixel display options. This is one reason why 16 color displays are difficult. Some color lookup has to happen, and that takes COG time, which consumes resolution, because the waitvid loop gets longer. Or, it consumes COGS to keep the waitvid loop short, while another COG does the lookups into a buffer.
Scan-line buffer type drivers are needed for sprites, odd color sizes, and such. A single COG can do tiles or a bitmap, with the standard color definitions, but little else while drawing the video signal.
Are you using a real crystal, or resonator? Resonators really don't have the tolerances needed to do a color display on TV.
Does the driver output a color TV signal? Some don't. Most do though.
Do you have all the resistors connected?
That's the list of stuff I would check, as well as running a known good color driver, just to vet the setup.
Is the pin mask set so that all the TV pins are outputs?
What about VCFG? Are the color bits set? Compare that driver to a known color one. Look at the high order bits.
Are you using a real crystal, or resonator? Resonators really don't have the tolerances needed to do a color display on TV. Crystal
Does the driver output a color TV signal? Some don't. Most do though. Yes
Do you have all the resistors connected? Yes
That's the list of stuff I would check, as well as running a known good color driver, just to vet the setup.
Is the pin mask set so that all the TV pins are outputs? Yes
What about VCFG? Are the color bits set? Compare that driver to a known color one. Look at the high order bits. Yes
It is the driver used in the Donkey Kong remake.
http://forums.parallax.com/showthread.php?94733-Donkey-Kong-Now-playable!
You can run a very similar display, using the same overall parameters with this driver:
http://forums.parallax.com/showthread.php?94975-High-color-TV.bitmap-driver-demo.
They use the same technique for the display. I built my first drivers off of Cardboard Guru's work some years back.
Have you run the game stand alone, no modifications? Does it display color?
Have you got the basic clock setup the same?
If FrameClocks / PixelClocks is greater than 32 (2 color mode) or 16 (4 color mode) then the last pixel color is repeated until the end of the frame. This is often used during inactive periods which are all the same color. Some drivers may also say "number of pixels" when they mean "number of PLLA clocks".
All knowledge and wisdom about the Propeller Video Generator may be found at http://propeller.wikispaces.com/Video+Generator
I did try to run the game by itself but some of the files were missing, so, it wouldn't compile. I left clock set at xtal1 + pll8x with _xinfreq being 10 MHz.
Have you had the demo to display color?
IMHO, Eric is on the right track. I didn't even look at the value, but he's right about it. Should have distorted your display significantly. The fact that it's grey indicates some other setup thing going on. Some capture devices will deal with the sync level, most TV's won't, unless there is only a little bit of it present in the display.
Does anything display color on your setup? If so, compare the VCFG, pin mask, etc... and adjust the Cardboardguru driver accordingly, verifying the state of each bit.
...or post up some code, and a schematic of your current setup. Kind of hard to just keep guessing at reasons.
@Eric: Nicely done on the video generator page. Bookmarked.
Just fixed it. It was not the color data, it was the system clock. It was set to xtal + pll8x with xinfreq at 10 MHz. I changed it to xtal + pll16x with xinfreq at 5 MHz. Strange; shouldn't both equal 80 MHz system clock?
This is artifact colors. Since the Propeller Video generator uses a 16 phase shifter for color, PLLA is normally 16x the colorburst frequency. Depending on the number of PLLA per pixel (VCFG.PixelClocks) a series of white / black pixels will be close enough to the colorburst frequency to be demodulated as colors.
If you have 2560 PLLA / active graphics scan line, 16 PLLA / pixel would deliver about 160 pixels. In my experience, composite signals at that resolution, do not artifact much. That is your baseline "artifact free" resolution. Go lower and it's golden, looking good. Go higher, and it will show artifacts. That's true for non-phase change signals, which is what your DK driver does.
It's possible to basically double the resolution to 320 pixels, if a more complex signal is applied to the display. The Parallax driver, Some of Eric's, my Potatotext, all do more complex, interlaced signals, and can display better resolution on TV.
Will I be able to maintain a four-thirds aspect ratio with 320 pixels per line? Are there any drivers at that res that has a line buffer that can be loaded?
[Edit]
I was looking at the screenshots of the Donkey Kong remake and it doesn't appear to have any issues with artifacts, at least from what I can tell from the screenshots. Every color appears spot on compared to the actual game.
The artifacting colors are clearly seen in this picture!
"Normal" color transitions will just be blurry. (read "dot crawl")
There are two phases that will output the same color, and they are 180 degrees apart. For brevity, and a lack of ability to explain it on my part, I'll just say that there are two possible "positions" for a color to appear rendered on screen correctly. In a single phase driver, there is only one position, and that has the upside of not showing color dot crawl on composite inputs, and it has the downside in that artifacts are very visible. Any series of higher resolution vertical stripes will show a artifact color, and do so consistently.
In a phase change driver, those artifacts cancel out every other scan line, producing a higher overall color resolution, trading frame update time for clarity of signal. A single phase driver can draw 60 frames / second NTSC, where a phase change one really only does 30 frames per second, because it takes two frames for the color to fully render.
When graphics on the NES, or C64, and other machines move at specific speeds, you can see a loss of detail as the image is moving just fast enough to not have all of it's pixels rendered.
It's also important to note that it is not just the number of pixels that determines artifacts. It is the PLLA / pixel. In the example of 256 pixels, one could stretch them to nearly fill the screen horizontally, which will allow more time for the color signal to be processed, generally delivering fewer artifacts, though there may be some color banding present, depending on the TV display used. Or, one could compress them to occupy a smaller part of the screen, resulting in a lot of artifacts. In the former case, there is more PLLA / pixel, in the latter, fewer PLLA / pixel.
High contrast transitions contain lots of higher frequencies, which resonate above the color burst frequency, and those are seen by the TV as color.
BTW: A S-video display will render much better. If you have one of those, it's only a few edits to change the output.
Generally speaking, avoid color transitions that are extreme in both intensity, and distance on the color wheel. Larger hue differences will produce artifacts between the colors as that hue change exceeds the minimum phase change time present in the color signal.
Another good trick is to limit the hue changes, changing intensity more. Atari computers used white, or very light blue on dark blue for the text screen, for example. That same text screen shown as white on black, appears colorful because of the artifacts. When the blue is used, artifacts are still there, but subdued. They end up variations of light greens, browns, etc... which all kind of wash out in the strong blue, leaving the user a clearer display.
Make color changes the lower level of detail in the display, using intensity changes, and modest hue changes as the detail requirement goes up, avoiding white on black, which is the worst one, second only to black on white.
PixelClocks is VSCL[19.12]. However, because the TV PLLA frequency and line period are fixed, the number of PLLA per pixel is inversely proportional to the horizontal resolution.
With the normal TV 3640 PLLA per line, 2987 PLLA correspond to the "square pixel" 640x480 (240 non-interlaced) frame. So 320 at 9 PLLA per pixel will be fairly close.
Just for reference: square pixel NTSC is 12.272727MHz or 780 pixels per line (640 active). The NES has a 5.369MHz pixel clock (3/2 * colorburst) for 341 pixels per line (256 active).