• Please review our updated Terms and Rules here

More fun with CGA composite color

resman

Veteran Member
Joined
Dec 31, 2013
Messages
709
Location
Lake Tahoe
I've been playing with composite artifact colors on the Apple IIGS and IIe computers for years. I've just recently made some breakthroughs with RGB image conversions to the Apple's Double Hi Res Graphics mode that I decided to port to the CGA's 640x200 hi res mode, as they implement artifact colors almost identically. This is a very simple algorithm to implement, but took quite a while to figure out.

TLDR:​

cgargb_000.png
cgargb_001.png
cgargb_002.png
cgargb_003.png
cgargb_004.png

The included ZIP file has the code and DOS executable along with these sample images. To run yourself, DOSBox with the video mode set to CGA. I've tried DOSBox-X with cga_composite but I can't get it to stick - it reverts to regular CGA after fully booting.

To use your own images:​

  • Install 'The GIMP' (https://www.gimp.org/) and load your image into it.
  • Crop if needed to fit a 4:3 aspect ratio.
  • Scale the image to 640x200 (very important!). You will need to unlink the chain icon forcing the original aspect ratio.
  • Check the image color precision to ensure it is 8 bits and not 16 bits.
  • Finally, export the image as a .pnm image. This is a brain dead simple 24BPP format.

To display the image:​

cgargb <pnmfile>

If you omit the pnmfile, you will get a list of options. The most useful options are:
-g# - with # being 2, 1, 0, -1, -2. This will use different gamma correction from dark (2) to light(-2)
-t# - with # from -180 to 180. This is the tint adjustment in degrees. Try big values for cool effects.

Now the screen captures above were taken with DOSBox. To truly get the best experience requires a real composite color CRT. This algorithm was designed based on how TV's and monitors decode the NTSC signal and not all emulators are as faithful in this regard.

To compile the code:​

I compiled with MSC5.1 but TurboC/BorlandC should compile, too. I tried to keep the code very simple.
cl -DDOS cgargb.c

Implementation details:​

This algorithm started many years ago with my experiments with artifact colors on the IIGS using the Super Hires Graphics Mode:
This evolved recently when I started creating a toolkit for the Apple II's Double Hi Res mode in PLASMA: https://github.com/dschmenk/PLASMA/wiki/DHGR-RGB-Image-Converter - a much more challenging environment.

By thinking NTSC in reverse, I started formulating an algorithm to convert RGB pixels into a best-case string of bits that would display an acceptable image given the constraint that the NTSC chroma cycle is divided up into only 4 pieces, and there is only one bit per piece. This actually simplified the decisions to be made a great deal. You only have to decide to set a bit or not, with only four colors to choose from (the four sections of the chroma cycle). By breaking with tradition and treating the scanline as a sliding window into the chroma cycle, more resolution can be retained.

Enjoy!
 

Attachments

Last edited:
First of all: This is crazy impressive. Great work! The rainbow artifacts, in the latter two pictures especially, have a wonderful charm.

This is a very simple algorithm to implement, but took quite a while to figure out.
I'd be curious to hear what aspects of the port between these ecosystems was most challenging, if you feel up for elaborating. Both on the software side and accounting for the *almost* identical color implementation (as you say).
 
First of all: This is crazy impressive. Great work! The rainbow artifacts, in the latter two pictures especially, have a wonderful charm.


I'd be curious to hear what aspects of the port between these ecosystems was most challenging, if you feel up for elaborating. Both on the software side and accounting for the *almost* identical color implementation (as you say).
The porting of the algorithm was pretty easy, as long as there is a pixel plot routine. For CGA, this was quite simple and entirely written in C. For the Apple II, I used my own language environment called PLEIADES: https://github.com/dschmenk/PLASMA which is similar enough to languages like C or Pascal so it was straight forward. One thing I discovered is that the Apple II and CGA have a color burst signal 180 degrees out of phase with each other.
 
There is a bug in the ZIP file I posted above that fails to work on real CGA hardware, but worked in the emulator I was using.

I wrapped the fixed EXE up in an IMG file you can load in to martypc.net if you'd like to try it for yourself - rendering is a bit slow at 4.77 Mhz so you might wanna crank the turbo and emulation speed.
And don't forget to turn on composite....


1765277628695.png
 

Attachments

One thing I discovered is that the Apple II and CGA have a color burst signal 180 degrees out of phase with each other.
Interesting... I knew they were different, but isn't it more like 90 degrees? (going by the usual fringe artifacts you see in white-on-black text: CGA gives you red and blue, and the Apple has purple and green - respectively those hues are 90 degrees apart on the NTSC color wheel).

Wonder if you've seen CGAArt by @reenigne (source link included). It supports more modes and conversion algorithms, but then it's a Windows program - if you feel inspired to port some of those ideas, it'd be very cool to see them in something that runs on DOS.
 
Interesting... I knew they were different, but isn't it more like 90 degrees? (going by the usual fringe artifacts you see in white-on-black text: CGA gives you red and blue, and the Apple has purple and green - respectively those hues are 90 degrees apart on the NTSC color wheel).

Wonder if you've seen CGAArt by @reenigne (source link included). It supports more modes and conversion algorithms, but then it's a Windows program - if you feel inspired to port some of those ideas, it'd be very cool to see them in something that runs on DOS.
I literally initialized the tint (the start of the NTSC color cycle) to 180 for the CGA, 0 for the Apple II DHGR. All other color calculations are the same.

Code:
int tint         = 180; /* CGA is 180 degrees out of phase with color burst */

Edit for additional useless trivia nobody cares about anymore:

As for the color fringing, it is the Apple II that is 180 degrees out of phase with itself every character (in 40 column mode) and byte in hires mode (280 horizontal pixels). This is due to the Apple II scanning out only 7 pixels per byte. The hires hi-bit hack to delay the shift register by half a clock gives you the colors that are 90 degrees out of phase with the un-delayed bytes. This is where all the fun of calculating pixels addresses and masks comes into play. In double hires, it gets more exciting: the half clock pixel delay doesn't come in to play, but you are still only shifting 7 pixels out per byte and every other byte is in a different memory bank! The consolation prize for double hires is that you get 4 pixels per chroma cycle, just like CGA, although the horizontal resolution is only 560 instead of 640.
 
Last edited:
Back
Top