Now that we have an IDE set up for creating our 2600 game, we need to know what we're actually having to program. Here's a breakdown of (what I've garnered is) the core of the Atari 2600 architecture:
We have a game cartridge [A], our program ROM. We have [B], a MOS 6532 RAM / IO/ Timer (RIOT) chip. [C] is a MOS 6507 microprocessor, practically identical to the 6502 of fame. Last we have [D], a custom Television Integrated Adapter (TIA) chip designed specifically for the machine.
The links above will give you more than enough information to discern the relationship between these circuits, but in a nutshell, the Atari 2600 basically has 8K of addressable space to work with. 4K is reserved for the RIOT chip, the other 4K for our program. The RIOT chip generously provides us 128 BYTES (not KILO-bytes, but BYTES for crying out loud) of RAM (0x0080 through 0x00FF), as well as I/O and timer functions (0x0280 through 0x0297), I/O referring to the joysticks, paddles, etc. If you've downloaded DASM, a file VCS.h should have come with it. This header already has the RIOT and TIA mnemonics mapped out to the appropriate addresses. The TIA chip handles the presentation “stuff” for us, basically drawing to the TV display and registering collisions and I guess what you could call audio. In our 8K of addressable space, addresses 0x0000 through 0x003F are TIA chip stuff. Again, the VCS.h file has these mapped out to their official mnemonics.
I don't feign to be an electrical engineer or care to be an expert on the internal workings of televisions, because I believe our modern newfangled LCD, projection and plasma HDTVs probably don't work this way, but at least when the TIA was designed, it was designed to handle synchronizing the game logic and output with the TV's rasterized method of rendering it's display. An electron beam will hit a portion of phosphor on the TV screen, lighting that point to a particular degree of intensity. It will do this for each of three colors: red, green, and blue (well, and white for luminosity). Doing this for a color at a particular point is referred to as a color-clock.
The beam will do this across the screen until it is done with the line it is working on (the scan-line), take a moment to reposition back on the other side of the screen at the next line (a duration called the horizontal blank), and then start again. When all the lines are “finished”, we say a frame has been completed, and when a frame has been completed, the beam returns all the way back kiddy-corner to start a new frame (a duration called the vertical blank). NTSC-based systems will do 262.5 lines 60-times per second (or 525 interlaced at 30 frames per second), PAL-based systems 312.5 lines at 50-times per second. There other systems out there (like SECAM, whatever that is), but from here on in this series, I will just be dealing with all things NTSC unless otherwise noted. Also, these lines-per-frame-per-second numbers are approximate for purposes of this series. The links provided go to respective Wikipedia articles with much more detail (and accuracy). We only need to know so much, and the TIA chip takes care of the rest. :)
…but I digress.
Below is a simple diagram of how my aging brain is grokking all this (it could therefore obviously be incredibly wrong):
With the TV knowledge and this delicious diagram in hand, we now can see how we bridge the TV and gaming platform gap via the TIA chip. The “motherboard” is architected such that a machine cycle – the unit of time used for measuring the duration of a completed 6507 instruction – equals the time it takes for all the colors for a given point on the TV (do not think pixel; analog TVs apparently do not have pixels) to be scanned. That is, scanning a set of color-clocks for one point on the screen equals a machine cycle, and machine cycles are how we measure program execution timing. So, if the 6507 chip takes 2 machine cycles to perform an instruction – say, LDA #5, or Load-Accumulator with integer 5 – and a given point on a scan line is made up of 3 (or 4 counting the white luminescence one) color-clocks, then that LDA instruction will take the equivalent of 6 color-clocks to complete. This leads us to another important image:
We see that, according to the TIA, we have 228 color-clocks before a scan line is “finished”: 68 for the horizontal blank, and 160 for the actual TV picture. The first 3 scan lines perform a vertical sync, then 37 more account for the vertical blank. The next 192 are our display lines. A final 30 are overscan lines. Also, the TIA is synchronized such that 3 color-clocks equal one machine cycle. Therefore, in the time a TV completes a scan line and returns to the next line, 76 machine cycles will have occurred. That's at most 38 instructions. And we have 262 of these we can do before the process starts all over again, less than 10,000 instructions. Sweet.
So, a quick recap of this concept: game logic processing by the 6507 is literally in sync with the rasterization process of the TV. The TIA chip is our bridge between what the 6507 is doing and what the TV is doing. Ergo, while your program is executing, the TV is scanning lines, so your program itself needs to take this into account and know when as well as what to tell the TV to do while its scanning.
We actually have a bunch more constraints believe it or not. Just positioning something horizontally is kind of a nightmare. Basically, you have to write to a register on the TIA when you want the object to appear at the same time on the following scan line. We'll get to that giant ugly later. For now, I, like you, will sit and zen on this a bit. We'll pick up next time from here and actually look at executing some code in Stella. In the meantime, here are several good links / documents / tools to start looking at: