[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Double hires mode color artifacts



Linards Ticmanis wrote:
Dirk Thierbach wrote:


Is that TN #3, "Double High-Resolution Graphics"? I read that, but couldn't make much sense out of it. If there's really a sliding window of only 4 bits width, then colors should change continously throughout 3 bits between different colors. Is that what actually happens in
the hardware?


Definitely yes, there is continuous change. The four-bit groups are
merely a conceptual help to understanding the stuff - there is nothing
that really marks one four-pixel group off from the next one.

As regards the actual Apple hardware, double hires simply drives out a
high voltage for every pixel that's set and a low voltage for every
pixel that's not set, using seven pixels from each byte, at a speed of
(theoretically) 14,318,181.8181... pixels per second.
That's all there is to it. The End.

All the rest stems from the fact that this 14,318,181 number is exactly
four times the NTSC color carrier. Thus by producing a repeating pattern
four DHR pixels in length, you can do various wave forms that will be
interpreted as color. You'll really have to get a hold of how quadrature
modulation works; for short: the average level of the signal is the
brightness; the height of the "waves" are the saturation (i.e. it tells
you how garish the colors are); and the phase of the waves (i.e. how far
they're shifted left or right relative to an imagined continuous wave
starting at the start of the line) is the the hue of the color.

Four bits give you sixteen different combinations. These combinations
are the sixteen lo-res colors (though in reality they're only fifteen
because the two grays should look identically if your monitor is
correctly set up). The lo-res modes simply produce repeating bit
patterns for each color. In DHR, you simply create these same patterns
"by hand" to get a specific color.

Further considerations lead to these facts:

Apart from black (no pixels set, so no wave), the two grays (which are
"too fast" waves with directly alternating black and white pixels that
do not trigger any color), and white (all pixels set, so again no wave),
your get these real colors:

1.) 1 pixel set in each group of four - the four "dark" colors.
2.) two adjacent pixels set, then two pixels not set - the four "hires"
colors
3.) three adjacent pixels set, then one not set - the four "light" colors.

Fourier Analysis of the resulting waves will tell you the following:
each of the four light colors has the same hue as one of the dark
colors, namely the one whose only set bit corresponds to the middle of
the three set bits of the bright color.  The hue of the four "hires"
colors is in the in the middle between pairs of two dark (or two light)
colors. The "hires" colors are more saturated than the light colors by a
factor of "square root of 2" (the latter is the case because it is the
height of the first sine component wave that counts, not the height of
the actual square wave itself).

A fairly good algorithm for reproducing an Apple DHR screen is this, for
each line of pixels: Take three "zeroes" (for the left black border) and
the first bit from the Apple screen. Look at these four pixels (each
either 1 or 0), interpret them as one four-bit number, map this to one
of 16 colors, draw a single pixel. Now forget the leftmost of the four
bits and replace it with the next one on the Apple screen. Map to one of
16 colors and draw one pixel. Now replace the *second* bit with the next
one from the Apple screen, map and draw a pixel. Now the third bit, then
the fourth, and then start over at the first. Do this until you have
only one bit left from the apple screen and three "zero" bits from the
right border have been shifted in.

Here's a RGB color table that works well enough for this (derived from
Fourier Analysis and the usual YUV-to-RGB formulas):

static struct {
        unsigned short  red;
        unsigned short  green;
        unsigned short  blue;
} AppleIIColor[16]= {
        {0x00,0x00,0x00},       /* Black */
        {0x90,0x17,0x40},       /* Deep Red */
        {0x40,0x2c,0xa5},       /* Dark Blue */
        {0xd0,0x43,0xe5},       /* Purple */
        {0x00,0x69,0x40},       /* Dark Green */
        {0x80,0x80,0x80},       /* Gray 1 */
        {0x2f,0x95,0xe5},       /* Medium Blue */
        {0xbf,0xab,0xff},       /* Light Blue */
        {0x40,0x54,0x00},       /* Brown */
        {0xd0,0x6a,0x1a},       /* Orange */
        {0x80,0x80,0x80},       /* Gray 2 */
        {0xff,0x96,0xbf},       /* Pink */
        {0x2f,0xbc,0x1a},       /* Light Green */
        {0xbf,0xd3,0x5a},       /* Yellow */
        {0x6f,0xe8,0xbf},       /* Aquamarine */
        {0xff,0xff,0xff}        /* White */
};


All other modes can be "mapped" to double hires in terms of their
output. So for every lores, double lores, or standard hires screen you
can construct a double hires screen that will look exactly the same;
even when there's four lines of text at the bottom (mixed mode). For
pure text modes (whether 40 or 80 char) this is also possible with the
caveat that of course the pure text modes switch off the color burst, so
you'd need to turn down color to zero on your monitor to get the equality.

I hope I have amused you, if not I hope I have confused you. ;-)

This analysis is what would happen in an NTSC monitor if the two chroma
channels had infinite bandwidth.  In fact, they have quite limited
bandwidths, on the order of 1MHz, and the two channels have different
bandwidths!

In addition, the bandwidth of the luminance channel is also limited, but
to a larger value, on the order of 3MHz.

The result is that a larger window (more FIR samples) must be considered
to adequately simulate the analog processing--in fact, closer to 14
(which would correspond to about 1 microsecond of time).

When the analysis that Linards describes is applied to the larger
window, with appropriate weighting of the "early" and "late" dots,
the result should approximate what you would actually see on an NTSC
monitor with the equivalent filter response.

Ideally, one would literally construct a DSP simulation of the analog
stream processing, complete with quadrature demodulation, FIR filters,
and delays to match the output of the luminance filter with the outputs
of the two chrominance filters, add in the gamma correction, and then
derive the appropriate RGB at each dot time in some chosen PC color
gamut.  (Remember, the point is not to *improve* on the analog
processing, but to faithfully simulate it with its limitations.)

Since the effect of preceding and following dots has a rapidly
diminishing effect, it would be possible to use this precise
simulation to fill in a color table corresponding to, say, the
16384 states of a 14-bit shift register, so the translation from
video signal to color display could be easily done in real time.

Of course, one could always give up a little more accuracy and
use a 12-bit shift register and a 4096-color table...

I'm not aware of anyone taking the time to do this, but it would be
appropriate for a machine-independent NTSC monitor emulation.  At
one time, the MAME project seemed to be heading in this direction.

-michael

NadaPong: Network game demo for Apple II computers!
Home page:  http://members.aol.com/MJMahon/

"The wastebasket is our most important design
tool--and it's seriously underused."