The VDG uses the inputs on a number of pins to determine its current video mode. On the CoCo, this is used to switch between alphanumeric and semi-graphjcs modes automatically. The highest-order bit of each byte of screen data is fed back into the pin that selects between those modes, allowing each character to be displayed as intended. The selection between inverted and non-inverted characters is handled similarly.
In fact, there are other VDG-equipped machines that extend this same technique to control the pin that selects between the available palettes (i.e. the CSS pin). But for better or for worse, the CoCo has to use software to control the CSS value. So that begs the question of whether or not the CoCo can change the CSS value quickly enough to produce more colorful displays. In fact, the CoCo game Dragonfire does exactly this. While the Dragonfire display is a bit cartoon-ish, it suggests that more colorful displays are possible on the CoCo.
Timing Is Everything
Knowing that we can switch the active palettes "on the fly", we are now faced with the task of doing so in time to display what we want when we want it. To do that, we have to figure-out how often we can change the CSS value, and when to do so.
Let's start with the 'when' part... The CoCo hardware can generate an interrupt for each line of the (almost-)NTSC display, or 262 times for every frame. Processing these interrupts through the IRQ vector would take a lot of cycles -- enough to miss the beginning of the actively displayed portion of the next line! Fortunately, the 6809 provides a SYNC instruction that basically halts the processor until the next interrupt is signalled. This allows us to synchronize with the interrupt timing at a minimal cost of CPU time. A little extra processing lets us skip the 70 lines during the vertical blanking period (i.e. the non-active portion of the display at the top and bottom of the screen). After that, some judicious use of NOP instructions and cycle counting allows us to time our CSS updates as necessary.
Each VDG clock cycle corresponds to one "color clock" cycle on the NTSC display, or one color pixel on the screen. The CoCo CPU clock is the VDG clock divided by 4, so one CPU clock corresponds to 4 color pixels on the screen. The fastest way I have found to update the CSS value is to preset the A and B registers and then use STA or STB to store the appropriate CSS value to the register that controls the VDG mode (including the CSS input of the VDG). With the 6809's Direct Page register set appropriately, those STA/STB instructions each take 4 CPU cycles. That corresponds to 16 color pixels on the screen during each CSS update, allowing for 8 CSS updates per 128-pixel line. Presetting the CSS value could allow for up to 9 CSS values (the preset CSS value and 8 updates) per line, with each CSS value corresponding to a different palette selection.
Putting Things Together
With all that figured-out, it seems prudent to write something to prove that this all works! So, I wrote some boilerplate code to properly time the CSS updates and to divide each line into eight 16-pixel sections. I added some code that initialized the screen buffer to include the appropriate pixel data for a rainbow of colors, accounting for the changing palettes in each section.
|8 On-Screen Colors from VDG|
Keep in mind that for any given byte of screen data, only four colors are available. Yet, there are eight colors displayed on each line. Now we are getting somewhere! Stay tuned to hear about how I use this to improve the display of a real-life image... :-)