VA0/VA1 LCD Interface (Game Gear)
I enjoy reverse engineering as much as the next guy, and I love sharing my knowledge more. During the creation of the Game Gear CleanScreen to bring modern screens to the Game Gear, I learned a lot, and despite the dangers of businesses sharing their knowledge, it is for the better of the community and scene to give back. Below are my personal findings and understandings of the Game Gear LCD interface of VA0/1 boards, when T10 is pulled to 5V enabling NTSC video output.
The Game Gear interface is described below. This allows reading in of the pixel data to a frame buffer.
The Game Gear produces signals with NTSC timing 525 lines at 30 FPS.
The video resolution for Game Gear games is 160x144 or when using Master System games or rare GG games, they output 256x192.
As we want to output at a different resolution and frequency (VGA 640x480 60Hz or TFT 320x240 Parallel RGB) we need a frame buffer to store the full frame between changing frames.
Our maximal resolution is 256x192 = 49152 pixels. Game Gear produces 4bit x 3 colors = 12bit color (R4G4B4).
The pixel clock is a continuous pulse all the time, running at 32Mhz. This runs the console and the LCD interface timing, so we call the system clock the pixel clock.
All measurements and changes in values are checked on each rising edge of this clock.
The Csync pulse is used to register the next set of RGB data about to be clocked out, as well as register the newline (VSYNC).
Csync is high for the majority then pulses low for a specific period (varies based on HSYNC or VSYNC), then goes high while pixel data is being read.
Csync pulses low for 156 pixel clocks for each new line, and then has a short glitch pulse of 11/12 cycles, followed by 3 pulses that are longer (1884 cycles) signalling the start of a new image frame, finally one more glitch pulse of 11/12 cycles, and then after that the line pulses start again for the new frame.
The HSYNC pulses low are exactly 156 pixel clocks. So CSync is low for 156 clock pulses. Then it goes high and starts the sub-pixel clock counting to read in the RGB data.
No data is ever sampled on the low pulse time of Csync. All data pins are low during this time.
Here is the pixel clock count on a HSYNC pulse low.
And here is the full frame of Csync pulses over a full screen of data, before the VSYNC (next image frame) Csync pulses starts to signal the next frame. There are 259 Csync edges for horizontal data, so 259 lines.
Technically it is NTSC 525 format (525 interlaced lines, so every other full frame is the other half of the 525 frames). That means each full frame is actually 525/2 so 263 lines in this case, and we can get 262/263 lines by including the last 2 longer pulses (signalling the next frame). As the start and end lines for many cycles are ignored anyway, this is irrelevant, so long as we time it correctly from the same starting point.
You see D2 pulsing before all other data lines is the blank lines that you just ignore. That is 69 to the left edge, and 200 (from the start) to the right edge, however as we know the output is 144 lines, this only gives 131 lines, we are 13 short. So we presume that 6 before and 7 after the other data pins start sending data are actual vertical lines.
That gives us a Y line start of 63 and a Y end line of 207, so 144 valid lines out of the total 263 lines that are clocked out for each frame.
The complete frame of an image generally looks like this, which as you can see is 60Hz refresh rate.
Sub-pixel and Data pins
Now we have the frame timings, we need to extract the horizontal line pixels. Once a HSYNC Csync pulse occurs on the rising edge after its low pulse, we start to count the pixel clock cycles after that rising edge.
We count from 0, 1, 2, 3, 4 then 5 pulses.
At the first high pulse after Csync went high, we clock out the D0, D1, D2 and D3 pins as the 4 bit information about the red color.
Then we ignore a clock and on the 3rd clock we do the same but for green data.
Finally we ignore one more and then on the 5th clock we extract the blue data.
After that the next clock is classed as zero and is ignored, and then the cycle starts over again.
The D0 to D3 are the bits from 0 being least significant to 3 being the most. In this example below the first red has data of 1110, being (D3D2D1D0), which in binary is decimal 14, or hexadecimal E. The possible range of the 4 bits is 16 possible levels of red from 0 to 15.
The green is 0100 so decimal 4. Finally the blue is 0000 so decimal 0.
If we presume the colors are on a scale of 0 to 255 we can multiply the values by 16 to get a value we can represent. This would make the final color red 244, green 64 and blue 0.
The pixel clocks total from the rise of Csync to the fall ready for the next line to around 1887 cycles. Given each RGB pixel set is 6 clocks (0 to 5), 1887 divide by 6 is approximately 314 pixels per line. As we ignore the end and start windows it is ok that the final end clocks vary slightly as it is non-information.
The video mode pin is pulled to 5V by default. When a Game Gear game is inserted, it is sunk low to ground. When a Master System game is used through a converter (or some Game Gear games that output master system video) this pin is left floating and the video signals are then a different format (larger video resolution).
Game Gear games output a resolution of 160 x 144 by default, but when a Master System game is inserted it changes the resolution to 256x192. This new larger information is sent in the exact same format except now the X and Y start and end values change.
Game Gear: X 87 to 247 Y 63 to 207
Master System X 47 to 303 Y 40 to 232