A CoCoVGA board consists of a 50MHz crystal, a SPI flash (containing FPGA configuration data), voltage level shifters/buffers, an Altera Cyclone IV, a 6847, and some other voltage regulators, header connectors, buttons, and passive components.
Within the FPGA, digital signals such as FS, HS, RP, GM[2:0], A/S, A/G, INV, CSS, DD[0:7], and the CLK are consumed. Early pre-release versions relied on the DA pins. Now address is generated internally based on HS, FS, and the CLK.
Outputs from the FPGA are 3 bits of red, 3 bits of green, and 3 bits of blue, for a total of a 512-color space. A resistor-ladder DAC is employed to convert these into the analog red, green, and blue values. The FPGA also outputs VGA VSYNC and HSYNC to produce timings appropriate for 640x480 @ 60Hz. The crystal is divided by 2 to create a 25MHz pixel clock.
CoCoVGA currently requires a 6847 because it relies on the 6847 to perform sync and address signalling to the SAM. One benefit of this is that the FPGA need not contain as much logic nor the board additional DACs to maintain backwards compatibility with either a RF-modulator can or composite output board.
The CoCoVGA FPGA uses full video display double-buffering so that it can run the VGA interface at a completely independent clock frequency from the computer interface clock and sync signalling. In other words, the microcomputer is filling one 6k buffer while the VGA display is reading the other. When the microcomputer fills one buffer, it moves on to the next, and the VGA display completes displaying the buffer it's working on and then works out of the other. Given that 640x480 60Hz VGA draws slightly faster than NTSC video from the 6847, there will occasionally be repeated frames on the VGA display. Doing double-buffering eliminates "tearing" effects that result from the two actions not being perfectly in sync. This should also improve compatibility with VGA monitors while enabling the 6847 to run at whatever frequency is required by the microcomputer hosting it. This also means that the VGA display will always be between 1/60 to 2/60 second behind what would be displayed on a TV.
Microcomputer Interface Buffering
The logic facing the microcomputer has the job of interpreting the mode (GM, A/G, A/S, CSS, INV, and CSS) and sampling it along with the data DD[7:0] and storing appropriate parts of each into one of two 6k x 16bit buffers, which is the max addressable video region of the 6847. Note that addresses may be repeated 2, 3, or 12 times between multiple pixel rows depending on the video mode. For example, the 6847 text and semigraphics mode attempts to read the same row of data 12 times per full text/semigraphics character row. Because of the dual-level addressing the SAM provides in a Color Computer, however, it is possible to address different data in each row to produce SG8, SG12, and SG24. To support this, it is necessary to keep all data that is read from every frame and display it, as though each row were independent.
VGA Interface Buffering
The VGA-side pipeline consumes complete 6k buffers. Because pixel rows are unrolled during buffer fill, we only need to line-double in most cases (64-column mode being an exception) as each byte is interpreted to be any of 8, 4, 2, or 1 pixels each.
In graphics modes, each group of 1 or 2 bits in combination with CSS is used to select the color to display.
An onboard pair of character ROMs (standard and T1) plus an SG ROM is row addressed modulo 12 to calculate pixel rows to display in text mode.
128x96 16-Color Graphics Mode (VG6)
VG6 is a new mode introduced with CoCoVGA which employs CG6 addressing but collects pairs of 2 32-byte rows into a single 64-byte row of pixels. Each pixel's color is specified by 4 bits (16 colors, programmable by way of the artifact palette registers) for a total of 128x96 pixel resolution in a 6kB RAM buffer.
64-Column Text Mode (W64)
64-column text and semigraphics modes are achieved by employing the full 640x480 VGA resolution, cutting the size of each character in half in X and in Y directions for a full text resolution of 64x32. This then requires 2kB of memory. The CG2 mode, which is not supported by CoCo ECB, is used for this and therefore requires patching the ROM via all-RAM mode. If it had been supported by the original ECB, it might have been PMODE "-1".
Enabling 64-column mode engages additional VGA hsync counter div12 and div3 hardware for the purposes of calculating MSBs of the buffer address. Given that CG2 is a 3 row-per pixel mode and pairs of 32-byte rows must be now interleaved, row input addresses inbound to the buffer are div3, meaning that only 1/3 of the bytes for a given half-row of text/SG will be buffered out of the 3 32-byte rows of pixel data. This makes any interesting software effects (such as changing data 3 times per half-row of text and SG4) impossible compared with using a simpler mode, such as the nicely linear RG6, however, RG6 would also be more wasteful and less intuitive when trying to lay out RAM. One other benefit of using a GM different from all those otherwise supported by BASIC is that now it is no longer necessary to select between text or graphics modes by pressing an additional button when doing 64-column text mode programming for graphics using ECB.