Sunday, July 13, 2014

VCSMC - Palette and Screen Dimensions

This is the second in a series of posts describing the video player software I'm putting together for the Atari 2600, called vcsmc. You can read the first post here.

There's no graphics buffer on an Atari 2600. Meaning, there's no area within memory of this device where a programmer can set pixel colors as they are computed, for display on the next scan out of the screen. Rather, the 6502 CPU marches in lock step with the CRT beam as it scans out each individual row of pixels on the screen while controlling a simple state machine, called the Television Interface Adaptor or TIA, that ultimately modulates the output beam to desired color. Timing is very tight, with 76 CPU clock cycles per scan line. A load to register/store to state machine address combination takes 5 clock cycles, and so the programmer is challenged to create interesting graphics by strategic choice of state changes to the TIA during scan out of the individual lines of the image. The ability to express complex imagery on the VCS output screen takes a level of programming mastery and creativity that is part of what makes Atari programming so much fun.

On NTSC machines the output color modulator supports 128 unique colors:

There are some advanced techniques, like ChronoColor, which may allow the Atari to represent a broader palette but for now I wanted to focus on the original palette, I think it is beautiful and colorful and I'm excited to see how video content will look rendered in these colors.

In terms of logical screen dimension the VCS renders 160 horizontal pixels on each output scanline. Documentation on vertical dimension seems more inconsistent. Most tutorial documents indicate 192 vertical scanlines as a standard but if you look at comments in emulator code like Stella it seems that legacy games used a variety of different vertical scanline counts based largely on timing considerations, with values varying from 80 to 230 vertical scanlines! Since in most games the time when the CRT beam is on, the primary (if not sole) concern of the code is rendering the graphics, this means that during vertical refresh and vertical blank, when the beam is off, is really the only time remaining for the code to update I/O, sound, AI, physics, or any other concerns the game software may have. There are also, it should be noted, generous affordances within the TIA to allow for halving vertical resolution by repeating each scanline twice.

Modern aspect resolutions seem a long distance from 160:192, roughly 16:19! Since vcsmc output is most likely to be rendered on 16:9 aspect ratio displays we will try to approximate 320 horizontal pixels with our 160 and cut vertical height to 180. Hopefully rendering 16:9 pixels on 93% of the vertical space on an actual 16:9 display won't look too funky. Thankfully the screen size constants are centrally located in the code so tweaking them later won't be too painful.

Up next, a discussion of an overall design approach for vcsmc.