The GPU uses three 4-bit counters (scan counter and V register) to control the vertical resolution of the display. This combined 12 bits can render up to 4096 vertical lines. Only part of this range can be displayed at standard video refresh rates using the 30.875 MHz dot clock though. The display is limited to 512 lines at 60 Hz or 400 lines at 75 Hz. Overclocking allows more lines with the potential for 1024 lines using a 64 MHz dot clock.
As well as the counters, he GPU uses two additional registers: The Color Register (C) and Glyph Register (G). The C register stores the current color(s) being displayed and can be used in two ways: It can represent a single 8-bit color as a 3:3:2 RGB value, or two 3-bit RGB colors and a 2-bit font value. Note: The pipeline timing dictates this 2-bit value will select the font of the next character.
The G register acts as a pipeline to hold the next glyph pattern while the current one is being rendered. The value of the G register is loaded into a shift register (SR) that is clocked at the 32 MHz dot clock. The output of this shift register is used to select one of the two 3-bit colors stored in the C register. The C register and this multiplexer can be thought of as an extremely simple RAMDAC.
In text mode the GPU uses two process cycles per character: The first to load the G register and the second to load the C register. Both must be synchronized so the shift register load happens at the same time as the C register load. The exact timing is shown in the diagram below.
The GPU repeats the same line from the video memory either 8 times in hi-res text mode, or 16 times in lo-res text mode. The scan counter counts to either 8 or 16 to select the specific line from the font ROM to render for the character's glyph.
The hi-res graphics mode uses all the same logic as the text mode, but operates on a single process cycle. The C and G/SR load signals now happen at the same time, so the same byte is loaded by the C register and passed though the font ROM to load the G register.
The GPU reads the same line only twice in the hi-res graphics mode and the shift register will output only 4 bits before the next value is loaded. The rendered character is therefore 4x2 pixels rather than the hi-res 8x8 or lo-res 8x16 text mode characters. This mode uses a special font where all the characters have the same glyph. There are still 4 fonts available though, since only 6 bits are used for the two colors.
The first font (dither 0) consist of a 2x2 block of foreground pixels followed by a 2x2 block of background pixels. The other 3 fonts provide dithering patterns that blend the two colors to provide a wider pseudo palette of up to 32 colors. The patterns also alternate on odd/even lines as shown below repeated 4 times.
The example below shows how the dithering (on the left) is used to represent an intermediate color (shown on the right). Note: The hi-res graphics mode defines a typical resolution of 320x240 pixels, but the dithering is rendered at the native 640x480 resolution.
Finally, in lo-res graphics mode all the glyph logic is bypassed and the C register is treated as a single 8-bit color value via its own video DAC. The GPU reads the same line four or five times to define a resolution of 160x120 with a simple one-byte-one-pixel format. Only half the video memory is used for one screen in this mode, so it provides room for double buffering. This is essential to prevent flicker when updating sprites on the screen, making it the preferred video mode for retro games.