27

In the MS-DOS Editor, the only choices for colors were a collection of 16 colors:

The QBasic-based MS-DOS Editor 1.1, with the ‘Display’ dialog open, showing color customisation options.

That's 16 colors:

  • Black
  • Blue
  • Green
  • Cyan
  • Red
  • Magenta
  • Brown
  • White
  • Gray
  • Bright Blue
  • Bright Green
  • Bright Cyan
  • Bright Red
  • Pink
  • Yellow
  • Bright White

How were these colors chosen, and why were there only 16?

2
66

The original IBM Color Graphics Adapter (CGA) for the first IBM PC introduced the "80x25 at 16 colors" text display mode for use with output to color monitors like the IBM 5153 (as opposed to output to televisions, where you'd want the 40-column mode). All later color graphics adapters (EGA, VGA, etc.) provide compatibility with that mode and that's what MS-DOS Editor runs in as a common baseline.

As for why 16 colors, it's because RAM was very expensive. 4-bit color gives you 16 colors and lets you pack a foreground and a background color into a single byte so that each character cell is only two bytes of screen memory and it only takes 4000 bytes to represent the whole screen.)

(One bit to turn on the red electron gun, one bit for green, one bit for blue, and one bit to control whether they should be at low or high intensity. RGBI. Then, the character ROM installed on the video card is used to translate those into grids of pixels for each character.)

19
  • 13
    Black: 0000. Gray: 0001. White: 1110. BrWhite: 1111.
    – john_e
    Jun 7 at 7:30
  • 12
    Well actually, "I" (intensity) is the high bit, then R,G,B; but otherwise you have it correct for the case of MDA and 16-color CGA/EGA. Jun 7 at 7:39
  • 5
    Agree it's mainly about video memory - but it's also about number of wires to the CRT and whether you want to invest into a DAC (or, generally, analog video circuitry) in the computer or not.
    – tofro
    Jun 7 at 9:27
  • 9
    RAM was very expensive compared to now. In the mid-'70s I bought an 8k x 8 (S-100 bus) memory board for around $250. $0.0038/bit, $0.0305/byte. Jun 7 at 15:31
  • 7
    "One bit to blue them all, one bit to green them, one bit to bring red all, and then with brightness blind them" - from "Lord Of The Bits". The original seems to have been mistranslated... Jun 9 at 3:02
26

How were the colors selected kind of depends on why there are only 16 of them.

In short, a CGA monitor takes four bit RGBI color input which means 16 colors. Each RGB color bit turns an electron gun for that color and I bit adds intensity to all of the guns, and brown color is handled with an exception.

A color monitor has three electron guns for three color phosphors, and those color are red, green and blue. So if each color is simply turned on or off, you need three bits to control the electron guns, which allows for 8 colors. Black color is all guns off, white is all guns on. The three colors with single gun on are red, green and blue. The three colors with two guns on are cyan, magenta and yellow.

For each character cell in the color text mode, the CGA reserves one full byte for character code and one full byte for 8-bit character attributes.

If there had been 2 color bits per gun in the monitor (which is what EGA does), it would use 6 bits for 64 colors - too much to store. It would also make sense to still have more colors than 8, so the attribute byte was used to have 4 bits of foreground color and 4 bits for background color. This then left one bit for each color gun and one extra bit for intensity, so it was enough to have 4 colour bits allowing for 16 different colors. So three bits control the guns separately and one bit adds brightness to all of them.

There is one special mechanism to alter the color palette in the monitor. There is bright yellow, but no dark yellow. The bit pattern for dark yellow is special and the analog voltages for driving the electron guns are altered to produce brown instead. This basically means that the DAC or color lookup table to convert bit patterns of color values to analog video voltages is in the CGA monitor that takes digital 4-bit RGBI input.

Another special mechanism was implemented in the CGA card which affects text mode background color selection. The fourth background attribute bit functionality is selectable. By default it controls if the foreground color blinks or not, so only the 8 dark background colors are available for selection. It can be changed to control the background intensity bit, which allows for selecting all 16 background colors, but then blinking text is not possible.

Explanation how the color order is determined from RGBI bits controlling the electron guns:

X = IRGB bits = color
0 = 0000 = Black
1 = 0001 = Blue (Dark)
2 = 0010 = Green (Dark)
3 = 0011 = Cyan (Dark)
4 = 0100 = Red (Dark)
5 = 0101 = Magenta (Dark)
6 = 0110 = Brown (actually, Dark Yellow which is adjusted to Brown in monitor)
7 = 0111 = White (actually, Dark White, Gray, Bright Gray, Light Gray)
8 = 1000 = Gray (actually, Dark Gray, Bright Black, Intensity Black)
9 = 1001 = Blue (Bright)
A = 1010 = Green (Bright)
B = 1011 = Cyan (Bright)
C = 1100 = Red (Bright)
D = 1101 = Magenta (Bright, or Pink)
E = 1110 = Yellow (Bright)
F = 1111 = White (Bright)
13

Assuming PC and CGA/EGA/VGA graphics (based on your example image)

As mentioned in the other answer, colors require memory which was not cheap back then. Also more memory for rendered VRAM means you need faster CPU processing and memory bandwidth. So all boils down to find a compromise between:

  1. screen resolution
  2. color depth
  3. frame rate

based on biological (what we can see and what is acceptable/enough) and technical aspects and limitations (costs, speed limits, reliability, adhering to standards and compatibility).

Your example shows a text mode which uses 16 bits per character. Where 8 bits are the extended ASCII of displayed character and 8 bits per 2 colors and 1 blinking flag.

  • 8 ASCII
  • 1 flash (blinking on/off)
  • 3 paper (8 colors)
  • 4 ink (16 colors, where the highest bit is brightness)

Now, in 4 bits we can encode 16 colors (choice was made 16 colors was "enough"). The graphics modes use 4 bits per pixel instead (also 16 colors). The standard 16 color palette was carefully chosen so its dithering friendly meaning you can use dithering without adding too much unnecessary noise and also provides some basic colors for non dithered purposes.

Similarly, once VGA introduced 256 colors, the standard 256 VGA color palette was also dithering friendly, allowing easier view of true color images on 8bpp.

Of course you can change the palette (on EGA/VGA) to any colors (that is how the plasma and some animation effects where done) the colors DACs where 6 bits so you have 26+6+6 = 262144 colors at your disposal, however at once you can choose only 16 or 256, depending on the video mode.

Text modes where not as heavy on memory size and bandwidth as you need much less VRAM to store whole screen (that is why they usually had bigger resolutions) so the real limitation was from graphics modes. Let assume 640×480 resolution 4bpp (16 colors) and 60Hz refresh rate meaning you need:

  • VRAM: 640 × 480 × 4 / 8 = 153600 B = 150 KiB
  • Bandwidth: 60 × 640 × 480 × 4 / 8 = 9216000 Byte/s = ~8.78 MiB/s

Which was really a lot to handle for old computers like 8086, 80186, 286 already, but doable especially when skipping frames. Now assume 8bpp (256 colors):

  • VRAM: 640 × 480 × 8 / 8 = 307200 B = 300 KiB
  • Bandwidth: 60 × 640 × 480 × 8 / 8 = 18432000 B/s = ~17.58 MiB/s

I do not think 80286 could handle that fully, but 80386 could. That is one of the reasons why original VGA did have just 320×200×8bpp and bigger resolutions were still 1bpp or 4bpp until SVGA/VBE/VESA kicked in much latter on. Another reason was that higher resolutions would not fit into 256 KiB (640×480 is 300 KiB) which means even adding few more kilobytes would require to add more addressing lines and decoders...

Also why not chose 5bpp or 6bpp instead of 4bpp?

Because 4bpp nicely divides byte into 2 nybbles and CPUs have instructions handling those already allowing easier programming and faster code for graphics processing.

7
  • 3
    I wouldn’t say the CGA/EGA palette is very dithering-friendly; CGA barely had any graphics modes, especially ones where dithering would look anywhere near acceptable. The component values of the ‘brown’ colour are probably the biggest confounder here. The Windows 4-bit palette, on the other hand, was specifically designed for dithering. Jun 7 at 8:53
  • 4
    The standard sixteen-color palette was "chosen" in such a way that many monitors could convert an RGBI color into analog RGB voltage using nine resistors, though some monitors would include an extra circuit to reduce the amount of green in the non-intense red+green color compared to the other non-intense colors that included green.
    – supercat
    Jun 7 at 16:53
  • @supercat Any pointers how would digital RGBI be converted to analog RGB using 9 resistors? The IBM 5153 CGA monitor is a lot more complex than that.
    – Justme
    Jun 7 at 20:31
  • @Justme: If full-scale white is supposed to be about 0.7 volts, then wire the analog red input to the digital red via 1K resistor, digital intensity via 2K resistor, and ground via 100 ohm resistor. Do likewise for analog green and analog blue, but substituting digital green and digital blue (share digital intensity for all three).
    – supercat
    Jun 7 at 20:43
  • @supercat I do see your point at a block diagram level, but in practice, directly driving a resistor DAC over a cable with LS TTL signals would be problematic. For example, the IBM 5153 CGA monitor first uses a digital buffer for the RGBI inputs, and from that point on, the buffered digital signals are used to control high speed analogue transistor circuitry to reach the required bandwidth.
    – Justme
    Jun 7 at 21:42
4

In addition to the other reasons people have given, enabling those sixteen colors allowed the IBM PC (with an appropriate terminal emulator) to be compatible with the ECMA-48 standard of the late ’70s, also known as ANSI escape sequences or ANSI terminal codes.

This enabled a PC to connect to a server by modem or serial cable, and display screens written for a terminal such as the DEC VT series or IBM’s mainframe terminals. There was a device driver to enable ANSI terminal codes to work in MS-DOS, named ANSI.SYS. This was important to any PCs that connected to mainframes or time-sharing systems, especially those running UNIX or VMS, and Infocom’s text adventures were among the native software that used it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.