FreeDOS 的 16 种颜色的由来
颜色 DOS

> 
> 为什么文本只能使用这些有限的颜色显示，为什么 FreeDOS 使用这些颜色和阴影，而不是其他颜色？答案就像技术中的许多事情一样，历史原因。
> 
> 
> 


![](/data/attachment/album/202209/21/171602vhhj99xkxshxbbvk.jpg)


如果你仔细了解过 FreeDOS，你可能已经注意到文本使用有限的颜色范围 —— 16 种文本颜色和 8 种背景颜色。这类似于 Linux 显示文本颜色的方式 —— 你或许能够在 Linux 终端中更改 *文本颜色*，但你仍然只能使用 16 种文本颜色和 8 种背景颜色。


![终端颜色](/data/attachment/album/202209/21/173211vkhjyhfgydk9lfjf.png "DOS text comes in 16 colors and 8 background colors")


*DOS 文本有 16 种颜色和 8 种背景颜色（吉姆·霍尔，[CC-BY SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/)）*


为什么文本只能使用这些有限的颜色显示，为什么 FreeDOS 使用这些颜色和阴影，而不是其他颜色？


答案就像技术中的许多事情一样，历史原因。


### PC 色彩的由来


为了解释为什么文本只有 16 种颜色，让我给你讲一个关于第一台 IBM 个人计算机的故事。这个故事的部分内容可能有些杜撰，但基本内容已经足够接近。


IBM 于 1981 年发布了<ruby> 个人计算机 <rt>  Personal Computer </rt></ruby> 5150（“IBM PC”）。该 PC 使用了一个简单的监视器屏幕，以绿色显示文本。由于此显示器仅适用于一种颜色，因此被称为 <ruby> 单色 <rt>  monochrome </rt></ruby>（“IBM 5151 单色显示器”，搭载 IBM <ruby> 单色显示适配器 <rt>  Monochrome Display Adapter </rt></ruby>，即 MDA）。


同年，IBM 发布了 PC 的更新版本，带来了惊人的技术成就 —— 颜色！新的 IBM 5153 彩色显示器依赖于新的 IBM <ruby> 彩色图形适配器 <rt>  Color Graphics Adapter </rt></ruby>（CGA）。正是由于这个原始的 CGA，所有的 DOS 文本都继承了它们的颜色。


但在我们讨论那一部分之前，我们首先需要了解一些关于颜色的东西。当我们谈论计算机屏幕上的颜色时，我们谈论的是混合 *三原色*（红色、绿色和蓝色）的不同值。你可以将不同级别（“亮度”）的红光、绿光和蓝光混合在一起，以创建几乎任何颜色。混合红色和蓝色光，你会得到洋红色。混合蓝色和绿色，你会得到青色或浅绿色。均匀地混合所有颜色，你会得到白色。没有任何浅色，你会看到黑色（没有颜色）。


![三原色](/data/attachment/album/202209/21/173211pagulp62besyg0s6.png "Mix red, green, and blue light to get different colors")


*混合红色、绿色和蓝色光以获得不同的颜色（吉姆·霍尔，[CC-BY SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/)）*


IBM 5153 彩色显示器通过在<ruby> 阴极射线管 <rt>  cathode ray tube </rt></ruby>（CRT）上点亮微小的红色、绿色和蓝色光点来向用户呈现颜色。这些小点排列得非常紧密，并以红色、绿色和蓝色的三色点组成一个“像素”的模式排列。通过控制同时点亮哪些荧光点，IBM 5153 彩色显示器可以显示不同颜色的像素。


![CRT 像素](/data/attachment/album/202209/21/173211ytgt0xoxmxvxo0rt.png "Each red, green, and blue triad is a single pixel")


*每个红色、绿色和蓝色三元组都是一个像素（吉姆·霍尔，[CC-BY SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/)）*


顺便说一句，即使是现代显示器也使用这种红色、绿色和蓝色点的组合来表示颜色。现代计算机的不同之处在于，每个像素都使用红色、绿色和蓝色 LED 灯（通常并排排列），而不是微小的荧光点。计算机可以打开或关闭每个 LED 灯，以混合每个像素中的红色、绿色和蓝色。


![液晶像素](/data/attachment/album/202209/21/173211gg4um8ukozsxq888.png "Each red, green, and blue triad is a single pixel")


*每个红色、绿色和蓝色三元组都是一个像素（吉姆·霍尔，[CC-BY SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/)）*


### 定义 CGA 颜色


IBM 工程师意识到他们可以通过混合红色、绿色和蓝色像素来显示多种颜色。在最简单的情况下，你可以假设单个像素中的每个红色、绿色和蓝色点要么“开”，要么“关”。正如任何计算机程序员都会告诉你的那样，你可以将“开”和“关”表示为二进制 —— 1（1 = 开）和 0（0 = 关）。


用 1 或 0 表示红色、绿色和蓝色意味着你可以组合多达八种颜色，从 000（红色、绿色和蓝色都关闭）到 111（红色、绿色和蓝色都打开）。请注意，位模式类似于“RGB”，因此 RGB=001 是蓝色的（只有蓝色是打开的），RGB=011 是青色的（绿色和蓝色都打开了）：




| 颜色 | 代码 | 名称 |
| --- | --- | --- |
| 　 | 000 | 黑 |
| 　 | 001 | 蓝 |
| 　 | 010 | 绿 |
| 　 | 011 | 青 |
| 　 | 100 | 红 |
| 　 | 101 | 洋红 |
| 　 | 110 | 黄 |
| 　 | 111 | 白 |


但这只是最简单的情况。一位特别聪明的 IBM 工程师意识到，只需再添加一点，你就可以将颜色数量从 8 种颜色增加到 16 种。因此，我们可以使用像 iRGB 这样的位模式，而不是像 RGB 这样的位模式。我们将把这个额外的“i”位称为“强度”位，因为如果我们将“强度”位设置为 1（开），那么我们将在全亮度下点亮红色、绿色和蓝色；如果“强度”位为 0（关闭），我们可以使用一些中级亮度。


有了这个简单的修复程序，现在 CGA 可以显示 16 种颜色！为了简单起见，IBM 工程师将高强度颜色称为常规颜色名称的“明亮”版本。因此，“红色”与“亮红色”配对，“洋红色”与“亮洋红色”配对。




| 颜色 | 代码 | 名称 | 颜色 | 代码 | 名称 |
| --- | --- | --- | --- | --- | --- |
| 　 | 0000 | 黑 | 　 | 1000 | 亮黑 |
| 　 | 0001 | 蓝 | 　 | 1001 | 亮蓝 |
| 　 | 0010 | 绿 | 　 | 1010 | 亮绿 |
| 　 | 0011 | 青 | 　 | 1011 | 亮青 |
| 　 | 0100 | 红 | 　 | 1100 | 亮红 |
| 　 | 0101 | 洋红 | 　 | 1101 | 亮洋红 |
| 　 | 0110 | 黄 | 　 | 1110 | 亮黄 |
| 　 | 0111 | 白 | 　 | 1111 | 亮白 |


哦不，等等！这实际上不是十六种颜色。如果你注意到 iRGB=0000（黑色）和 iRGB=1000（亮黑色），它们都是相同的 *黑色*。没有颜色可以“亮”，所以它们都是普通的黑色。这意味着我们只有 15 种颜色，而不是我们希望的 16 种颜色。


但 IBM 有聪明的工程师为他们工作，他们意识到如何解决这个问题以获得 16 种颜色。IBM 实际上没有实现直接的 RGB 到 iRGB，而是实现了 *类* iRGB 方案。随着这一变化，IBM 为每个光点设置了四个亮度级别：完全关闭、三分之一亮度、三分之二亮度和全亮度。如果“亮度”位被关闭，那么每个红色、绿色和蓝色光点将以三分之二的亮度点亮。如果你打开“亮度”位，RGB 颜色中的所有 0 都将以三分之一的亮度点亮，而所有 1 都将以全亮度点亮。


让我用另一种方式向你描述这一点，使用 Web 颜色代码表示。如果你熟悉 HTML 颜色，你可能知道你可以使用 `#RGB` 表示颜色，其中 RGB 表示红色、绿色和蓝色值的组合，每个值都在十六进制值 0 到 F 之间。因此，使用 IBM 修改后的 iRGB 定义，iRGB=0001 是 #00a（蓝色），iRGB=1001 是 #55f（亮蓝色），因为对于高亮度颜色，RGB=001 中的所有零点都以三分之一的亮度点亮（0 到 F 刻度上的“5”左右），RGB=001 中的所有零点都以三分之二的亮度点亮（0 到 F刻度上的“A”）。




| 颜色 | 代码 | 名称 | 颜色 | 代码 | 名称 |
| --- | --- | --- | --- | --- | --- |
| 　 | 0000 | 黑 | 　 | 1000 | 亮黑 |
| 　 | 0001 | 蓝 | 　 | 1001 | 亮蓝 |
| 　 | 0010 | 绿 | 　 | 1010 | 亮绿 |
| 　 | 0011 | 青 | 　 | 1011 | 亮青 |
| 　 | 0100 | 红 | 　 | 1100 | 亮红 |
| 　 | 0101 | 洋红 | 　 | 1101 | 亮洋红 |
| 　 | 0110 | 黄 | 　 | 1110 | 亮黄 |
| 　 | 0111 | 白 | 　 | 1111 | 亮白 |


有了这些颜色，我们终于完成了！我们拥有从 iRGB=0000（黑色）到 iRGB=1111（亮白色）以及介于两者之间的所有颜色的全光谱。就像彩虹般的颜色，这很漂亮。


除了……不，等等，这里有问题！我们实际上还不能复制彩虹的所有颜色。我们在小学学到的方便的助记符是 ROYGBIV，它可以帮助我们记住彩虹的颜色有红色、橙色、黄色、绿色、蓝色、靛蓝和紫色。我们修改后的 iRGB 配色方案包括红色、黄色、绿色和蓝色——我们可以将其“伪造”为靛蓝和紫色，但是我们缺少橙色。遭了！


![彩虹](/data/attachment/album/202209/21/173211prhdq6muh3mp6oo2.jpg "A beautiful rainbow - which unfortunately contains orange ")


*一条美丽的彩虹——不幸的是它含有橙色。（[Paweł Fijałkowski](https://www.pexels.com/photo/landscape-photography-of-field-with-wind-mill-with-rainbow-1253748/)，公共）*


为了解决这个问题，聪明的 IBM 工程师对 RGB=110 做了最后的修复。高强度颜色（iRGB=1110）以全亮度点亮红色和绿色荧光粉点以产生黄色，但是在低亮度颜色（iRGB=0110）下，他们以三分之二的亮度点亮红色，以三分之一的亮度点亮绿色。这将 iRGB=0110 变成了橙色——尽管它后来被称为“棕色”，因为 IBM 不得不在某处弄乱标准名称。




| 颜色 | 代码 | 名称 | 颜色 | 代码 | 名称 |
| --- | --- | --- | --- | --- | --- |
| 　 | 0000 | 黑 | 　 | 1000 | 亮黑 |
| 　 | 0001 | 蓝 | 　 | 1001 | 亮蓝 |
| 　 | 0010 | 绿 | 　 | 1010 | 亮绿 |
| 　 | 0011 | 青 | 　 | 1011 | 亮青 |
| 　 | 0100 | 红 | 　 | 1100 | 亮红 |
| 　 | 0101 | 洋红 | 　 | 1101 | 亮洋红 |
| 　 | **0110** | **棕** | 　 | 1110 | 黄 |
| 　 | 0111 | 白 | 　 | 1111 | 亮白 |


这就是 CGA 以及扩展的 DOS 获得十六种颜色的方式！如果你好奇，这也是为什么会有“亮黑色”的原因，即使它只是一种灰色阴影。


### 表示颜色（位和字节）


但是你可能想知道：为什么 DOS 可以显示 16 种文本颜色，却只能显示 8 种背景颜色？为此，我们需要快速了解计算机如何将颜色信息传递给 CGA 卡。


简而言之，CGA 卡希望将每个字符的文本颜色和背景颜色编码在一个字节数据包中，一共八位。那么八位是从哪里来的呢？


我们刚刚了解了 iRGB（四位）如何生成十六种颜色。文本颜色使用 iRGB ，四位，背景颜色仅限于八种低强度颜色（RGB，三位），加起来只有七位。丢失的第八位在哪里？


最后一个位可能是为 DOS 时代最重要的用户界面元素保留的 —— 闪烁文本。虽然闪烁的文本在如今可能很烦人，但在整个 1980 年代初期，闪烁的文本是表示错误消息等关键信息的友好方式。


将这个“闪烁”位添加到三个背景颜色位（RGB）和四个文本颜色位（iRGB）中会产生八个位或一个字节！计算机喜欢以完整字节为单位进行计数，这使其成为将颜色（和闪烁）信息传输到计算机的便捷方式。


因此，表示颜色（和闪烁）的完整字节是 `Bbbbffff`，其中 `ffff` 是文本颜色的 iRGB 位模式（从 0 到 15），`bbb` 是低强度的 RGB 位模式背景颜色（从 0 到 7），而 `B` 是“闪烁”位。


十六种文本颜色和八种背景颜色的限制一直持续到今天。当然，DOS 坚持使用这种颜色组合，但即使是像 GNOME 终端这样的 Linux 终端仿真器也仍然受限于 16 种文本颜色和 8 种背景颜色。当然，Linux 终端可能允许你更改使用的特定颜色，但你仍然限于十六种文本颜色和八种背景颜色。为此，你要感谢 DOS 和最初的 IBM PC。别客气！




---


via: <https://opensource.com/article/21/6/freedos-sixteen-colors>


作者：[Jim Hall](https://opensource.com/users/jim-hall) 选题：[lujun9972](https://github.com/lujun9972) 译者：[gpchn](https://github.com/gpchn) 校对：[wxy](https://github.com/wxy)


本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


OK
If you've looked carefully at FreeDOS, you've probably noticed that text only comes in a limited range of colors—sixteen text colors, and eight background colors. This is similar to how Linux displays text color—you might be able to change *what text colors are used* in a Linux terminal, but you're still stuck with just sixteen text colors and eight background colors.

![DOS text comes in 16 colors and 8 background colors terminal colors](https://opensource.com/sites/default/files/uploads/16colors.png)

DOS text comes in 16 colors and 8 background colors

(Jim Hall, [CC-BY SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/))

Why does text only come in this limited palette, and why does FreeDOS use *those* colors and shades, instead of some other colors? The answer, like many things in technology, is because of *history*.

## The origins of PC color


To explain why text only comes in sixteen colors, let me tell you a story about the first IBM Personal Computer. Parts of this story may be somewhat apocryphal, but the basics are close enough.

IBM released the Personal Computer 5150 (the "IBM PC") in 1981. The PC used a simple monitor screen that displayed text in green. Because this display only worked with one color, it was dubbed *monochrome* (the "IBM 5151 monochrome display," with the IBM Monochrome Display Adapter card, or "MDA").

That same year, IBM released an updated version of the PC that sported an amazing technical achievement—color! The new IBM 5153 color display relied on a new IBM Color Graphics Adapter, or "CGA." And it is because of this original CGA that all DOS text inherited their colors.

But before we go there, we first need to understand something about color. When we talk about colors on a computer screen, we're talking about mixing different values of the three *primary* light colors—red, green, and blue. You can mix together different levels (or "brightnesses") of red, green, and blue light to create almost any color. Mix just red and blue light, and you get magenta. Mix blue and green, and you get cyan or aqua. Mix all colors equally, and you get white. Without any light colors, you see black (an absence of color).

![Mix red, green, and blue light to get different colors light colors](https://opensource.com/sites/default/files/uploads/rgb.svg_.png)

Mix red, green, and blue light to get different colors

(Jim Hall, [CC-BY SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/))

The IBM 5153 color display presented color to the user by lighting up tiny red, green, and blue phosphor dots on a cathode ray tube (a "CRT"). These tiny dots were arranged very close together and in a pattern where a triad of red, green, and blue dots would form a "pixel." By controlling which phosphor dots were lit at one time, the IBM 5153 color display could show different colored pixels.

![Each red, green, and blue triad is a single pixel CRT pixels](https://opensource.com/sites/default/files/uploads/crt.svg_.png)

Each red, green, and blue triad is a single pixel

(Jim Hall, [CC-BY SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/))

By the way, even modern displays use this combination of red, green, and blue dots to represent colors. The difference in modern computers is that instead of tiny phosphor dots, each pixel uses a triad of red, green, and blue LED lights—usually arranged side by side. The computer can turn each LED light on or off to mix the red, green, and blue colors in each pixel.

![Each red, green, and blue triad is a single pixel LCD pixels](https://opensource.com/sites/default/files/uploads/lcd.svg_.png)

Each red, green, and blue triad is a single pixel

(Jim Hall, [CC-BY SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/))

## Defining CGA colors

The IBM engineers realized they could display several colors by mixing each red, green, and blue pixels. In the simplest case, you could assume each red, green, and blue dot in a single-pixel was either "on" or "off." And as any computer programmer will tell you, you can represent "on" and "off" as binary—ones (1=on) and zeroes (0=off).

Representing red, green, and blue with ones or zeroes means you can combine up to eight colors, from 000 (red, green, and blue are all off) to 111 (red, green, and blue are all on). Note that the bit pattern goes like "RGB," so RGB=001 is blue (only blue is on) and RGB=011 is cyan (both green and blue are on):

000 Black | |

001 Blue | |

010 Green | |

011 Cyan | |

100 Red | |

101 Magenta | |

110 Yellow | |

111 White |


But that's just the simplest case. A particularly clever IBM engineer realized you could double the number of colors from eight to sixteen simply by adding another bit. So instead of a bit pattern like RGB, we can use a bit pattern like iRGB. We'll call this extra "i" bit the "intensity" bit because if we set the "intensity" bit to 1 (on), then we'll light up the red, green, and blue phosphor dots at full brightness; if the "intensity" bit is 0 (off) we can use some mid-level brightness.

And with that simple fix, now CGA could display sixteen colors! For the sake of simplicity, the IBM engineers referred to the high-intensity colors as the "bright" versions of the regular color names. So "red" pairs with "bright red," and "magenta" pairs with "bright magenta."

0000 Black | 1000 Bright Black | ||

0001 Blue | 1001 Bright Blue | ||

0010 Green | 1010 Bright Green | ||

0011 Cyan | 1011 Bright Cyan | ||

0100 Red | 1100 Bright Red | ||

0101 Magenta | 1101 Bright Magenta | ||

0110 Yellow | 1110 Bright Yellow | ||

0111 White | 1111 Bright White |


Oh no! But wait! This isn't actually sixteen colors. If you notice iRGB=0000 (black) and iRGB=1000 (bright black), they are both the same *black*. There's no color to make "bright," so they are just both regular black. This means we only have fifteen colors, not the sixteen we were hoping for.

But IBM has clever engineers working for them, and they realized how to fix this to get sixteen colors. Rather than implement a straight RGB to iRGB, IBM actually implemented a *modified* iRGB scheme. With this change, IBM set four levels of brightness for each phosphor dot: completely off, one-third brightness, two-thirds brightness, and full brightness. If the "intensity" bit was turned off, then each red, green, and blue phosphor dot would light up at two-thirds brightness. If you set the "intensity" bit on, any zeroes in the RGB colors would be lit at one-third brightness, and any ones in the RGB colors would be lit at full brightness.

Let me describe this to you another way, using web color code representation. If you are familiar with the HTML colorspace, you probably know that you can represent colors using #RGB, where RGB represents a combination of red, green, and blue values, each between the hexadecimal values 0 through F. So using IBM's modified iRGB definition, iRGB=0001 is #00a (blue) and iRGB=1001 is #55f (bright blue) because with high-intensity colors, all zeroes in RGB=001 are lit at one-third brightness (around "5" on the 0 to F scale) and all ones in RGB=001 are lit at two-third brightness (about "A" on the 0 to F scale).

0000 Black | 1000 Bright Black | ||

0001 Blue | 1001 Bright Blue | ||

0010 Green | 1010 Bright Green | ||

0011 Cyan | 1011 Bright Cyan | ||

0100 Red | 1100 Bright Red | ||

0101 Magenta | 1101 Bright Magenta | ||

0110 Yellow | 1110 Bright Yellow | ||

0111 White | 1111 Bright White |


And with those colors, we are finally done! We have a full spectrum of colors from iRGB=0000 (black) to iRGB=1111 (bright white) and every color in between. Like a rainbow of colors, this is beautiful.

Except, no. Wait. Something's wrong here. We can't actually replicate all of the colors of the rainbow yet. The handy mnemonic we learned in grade school was ROYGBIV, to help us remember that a rainbow has colors from red, orange, yellow, green, blue, indigo, and violet. Our modified iRGB color scheme includes red, yellow, green, and blue—and we can "fake" it for indigo and "violet." But we're missing orange. Oh no!

![A beautiful rainbow - which unfortunately contains orange rainbow](https://opensource.com/sites/default/files/uploads/rainbow.jpg)

A beautiful rainbow - which unfortunately contains orange

([Paweł Fijałkowski](https://www.pexels.com/photo/landscape-photography-of-field-with-wind-mill-with-rainbow-1253748/), public domain)

To fix this, the smart IBM engineers made one final fix for RGB=110. The high-intensity color (iRGB=1110) lit up the red and green phosphor dots at full brightness to make yellow. But at the low-intensity color (iRGB=0110), they lit the red at two-thirds brightness and the green at one-third brightness. This turned iRGB=0110 into an orange color—although it was later dubbed "brown" because IBM had to mess up the standard names somewhere.

0000 Black | 1000 Bright Black | ||

0001 Blue | 1001 Bright Blue | ||

0010 Green | 1010 Bright Green | ||

0011 Cyan | 1011 Bright Cyan | ||

0100 Red | 1100 Bright Red | ||

0101 Magenta | 1101 Bright Magenta | ||

0110 Brown | 1110 Yellow | ||

0111 White | 1111 Bright White |


And that's how CGA—and by extension, DOS—got the sixteen colors! And in case you're curious, that's also why there's a "bright black" color, even though it's just a shade of gray.

## Representing colors (bits and bytes)

But you may wonder: why can DOS only display eight background colors if it can display sixteen text colors? For that, we need to take a quick diversion into how computers passed color information to the CGA card.

In brief, the CGA card expected each character's text color and background color to be encoded in a single byte packet. That's eight bits. So where do the eight bits come from?

We just learned how iRGB (four bits) generates the sixteen colors. Text color uses iRGB, or four bits. The background color is limited to the eight low-intensity colors (RGB, or three bits). Together, that makes only seven bits. Where is the missing eighth bit?

The final bit was reserved for perhaps the DOS era's most important user interface element—blinking text. While the blinking text might be annoying today, throughout the early 1980s, blinking text was the friendly way to represent critical information such as error messages.

Adding this "blink" bit to the three background color bits (RGB) and the four text color bits (iRGB) makes eight bits or a byte! Computers like to count in full bytes, making this a convenient way to package color (and blink) information to the computer.

Thus, the full byte to represent color (and blink) was `Bbbbffff`

, where `ffff`

is the iRGB bit pattern for the text color (from 0 to 15), `bbb`

is the RGB bit pattern for the low-intensity background color (from 0 to 7), and `B`

is the "blink" bit.

The limit of sixteen text colors and eight background colors continues to this day. Certainly, DOS is stuck with this color palette, but even Linux terminal emulators like GNOME Terminal remain constrained to sixteen text colors and eight background colors. Sure, a Linux terminal might let you change the specific colors used, but you're still limited to sixteen text colors and eight background colors. And for that, you can thank DOS and the original IBM PC. You're welcome!

## 2 Comments