The color palette can unequivocally identify a computer with a certain aesthetics, think of the vivid but few colors found in the ZX spectrum or the characteristic ’70ish colors found in the Atari to the grayish/blueish look of the C64. In short, the color palette gives the computer a certain personality.
Choosing a color palette is a big commitment.
Later on, VGA broke that commitment offering a “true color” palette, where you can choose between an universe of 16M colors, but VGA is far beyond the limits of what we would want for an 8 bit computer like Compy, also the memory and CPU speed would make it impossible to use that amount of colors.
The approach used by Chroni has the best of both worlds, instead of using a fixed palette to start with, let’s choose a 256 color palette from a bigger colorspace (RGB565) and provide methods to use as little as memory as possible.
RGB565 Global Palette
How many colors can be displayed depends on the Digital to Analog Converter (DAC) used in the computer, older computers have limited colors because just a few bits were used per RGB channel, but today computers can use many more bits per RGB channel thus giving more color options. For example, using 4 bits per RGB channel gives 64 colors (4³) 8 colors, and using 5 bits per channels gives 125 colors (5³).
Chroni is designed to be used through emulation or FPGA devices. Using emulation we have “true color” (16M), but using FPGA the available devices are restricted to the real DAC converting bits to analog colors. Of course, we can build our own resistor ladder DAC but if we look at the off the shelf options available, most VGA connectors use RGB 565, which is 5 bits for Red, 6 bits for Green and 5 bits for Blue thus giving 2¹⁶ = 64K colors, which is more than enough for an 8 bit computer.
In Chroni you define a base palette of 256 colors, but each color is an RGB565 entry, so you pick a subset of a 64K colorspace for your game or program. Using this method you can match any of the existing 8-bit computer palettes and also you can use a palette that didn’t exist on any of those computers.
The computer is not committed to a specific palette, but your program is, so you can define the style of how you want your game to look like. Take a look on this site about how a color palette can define the aesthetics of a movie.
Now, Chroni avoid to have fixed addresses and use pointers instead, this method helps avoid the CPU having to copy blocks of memory. Just change the palette pointer to another place in VRAM and Chroni will use that.
VPALETTE = $9004 lda #<vram_pallette_addr sta VPALETTE lda #>vram_palette_addr sta VPALETTE+1
Sub Palettes
Once you define your 256 color palette, which colors will be used in 4 color mode? or 16 color mode? To better understand this part, let me explain how older computers worked.
The Atari 8 bit computer had a fixed 256 color palette, to select a color you write to a specific register with the index of the desired color in that 256 color palette. If you write 3 to the color register you were referring to the palette[3] entry, if you write 29, it was the palette[29] entry and so on. For a 4 color mode you had 4 registers for the visible area and 1 register for the border color, thus 5 registers were needed to define all colors.
In Chroni there are no fixed registers for colors except for the border color, the display colors are defined by a memory area where these color indexes are stored. Again, this is not a fixed area and it can be placed anywhere, you only need to set a pointer to this area. This area is called a subpalette, so depending on the video mode you will have 4 color subpalettes, 16 color subpalettes and so on.
A subpalette base address is set through a display list instruction, so it is part of your screen definition and you can change it for every scanline. More info about display lists will be added in this series of Chroni articles, for now think that for each line on the screen you can define a video mode and a subpalette to be used.
SUBPAL_BASE = $A806 VCOLOR0 = $9010 ; this is the border color lda #0 sta VCOLOR0 ; border has palette[0] color ; now write a subpalette base address ; in the default display list mwa my_subpalette_vram_addr SUBPAL_BASE
Color Attributes
Now, you can use an entire subpalette for your whole screen but that would restrict you to use up to X color in the whole screen. Of course, you can modify the subpalette or palette for each line but wouldn’t be awesome to have more than one subpalette for each line?
Chroni uses a similar method found in the Spectrum, C64 and NES to define colors through “attributes”. In Chroni there is display data and attribute data: Display data defines the pixels, characters or tiles to be displayed, while attributes define which subpalette or colors will be used in that display.
For example, bitmap and tiled modes have attributes defining which subpalette will be used. So if you have a 4 color mode you will be using 4 color subpalettes. Look at the following code:
subpalettes: .byte 0x34, 0x43, 0x85, 0x23 .byte 0x82, 0x01, 0x0F, 0xFF .byte 0x22, 0x21, 0x44, 0x23 .byte 0x74, 0x29, 0x99, 0xA0 .byte 0x33, 0x32, 0x44, 0x42
The code shows 5 subpalettes, so using attributes you can select any of those subpalettes for each display block (depending on the mode). If you use 0 as the attribute for a display entry, that will use first subpalette (0x34…), if you use 3 it will use the third subpalette (0x22…) and so on.
Using this method you can change the colors used for any part of the screen just changing one byte (attribute), or you can point Chroni to use a different set of subpalettes just updating the subpalette base address in your display list as shown in the previous section.
Text modes use attributes in a similar way that the spectrum used the attributes. For each attribute byte a foreground and background color is defined, so you can use up to 16 colors for each foreground and backgound. Which colors? These are defined in a 16 color subpalette.
In the following shots you can see one same program using different global palettes. The border color is changed through VCOLOR0, and the foreground and background colors of each char is defined by the attributes. Which colors to take from the 256 colors are defined in the subpalette. Floating objects are sprites using their own subpalettes