Programming like it's 1977: exploring the Atari VCS
by Adam Tornhill, May 2024
Earlier this year I started a new hobby: writing games on the Atari VCS. The Atari VCS -- or Atari 2600 as later versions were labeled -- is a curious piece of hardware. It's heavily constrained with its 128 bytes(!) of RAM, no operating system, and limited types of sprites. The good news are that you're compensated for the lack of RAM by a full 4K of Read Only Memory (ROM) at your disposal. Wonderful. The slight downside is that you have to fit all your game logic, graphics, and sounds into those 4K. As if that wasn't constraining enough, you also have to trace and time the electron beam on the TV to output graphics. Just saying. Still, people at the dawn of computer gaming managed to squeeze amazing art out of this platform.
My primary goals with the Atari VCS is to understand how that magic was achieved, what tricks they used, and learn enough to code my own games. But I came to the VCS community with a secondary goal, too. After reading about this platform from 1977, I got curious about how those constraints force you to re-think programming strategy. Perhaps there's a learning experience which transcends the specific platform? Given that I'm at least 40 years late to the party, I'm clearly not doing this for commercial purposes. Besides, coding on the Atari is more fun than reading up on the latest Kubernetes options. So there we go -- let's travel back to 1977.
Computing at the dawn of gaming
The Atari VCS was designed with early 70ies arcade hits like Pong and Tank in mind. This becomes obvious when you start to learn about the hardware. The Atari comes with two player sprites (although the term sprite hadn't been invented yet, so the manuals call them "player objects"), two missile sprites (think a tank shooting at another), and a ball sprite (Pong -- here we go!). The platform was never designed to last, yet it had a commercial run stretching from 1977 to 1992 which is absolutely amazing.
This commercial longevity was possible due to all the software innovations. Programmers quickly started to expand the gaming space, and radically expanded beyond Pong style games. Doing so required a lot of creativity from the programming pioneers. However, and of particular fascination to me, the reason these later games were possible at all on such a limited platform was because, well, the platform was limited. There are basically no hardware checks on the Atari, meaning you can work around its limitations in software.
As an example on such a software workaround, there's nothing in the hardware which prevents you from drawing the same sprite multiple times. With the right timing, you can vastly (well...everything is relative) surpass the limitations of the hardware. That's what made Space Invaders such a hit on the VCS.
Cutting costs: how to make a constrained platform even more constrained
At this stage, you might wonder why the hardware is so constrained. Couldn't we have more than 128 bytes back in 1977? Indeed we could, but RAM was expensive and the Atari was intended as an affordable console expected to sell in volume. RAM was the obvious victim, but the cost cutting went deeper. Consider the CPU as an example. The Atari VCS is based on the legendary 6502 CPU from MOS Technologies. (Yes, the same CPU that fueled the Commodore computers, Nintendo's NES, and many other classic consoles).
By cutting a few address pins, creating the 6507 CPU version, Atari could save some manufacturing cost. The flip side? Well, with fewer pins the address bus was reduced from 16 bits to just 13 in the 6507. This means the Atari VCS can only address 8k of memory as opposed to the 64k capacity of the original 6502.
The memory reduction might not have been a big issue back in 1977. After all, the launch title Combat fits in just 2k (!). However, as the platform kept thriving, we consumers demanded more. Techniques such as bank switching made it possible to use more memory, but it came at a steep cost. In fact, the lack of memory might explain one of the largest VCS failures, the lackluster Pac-Man port -- a game which had to sacrifice both its looks and playability in order to fit in cheap 4k ROM cartridges.
Anyway, it's exactly limitations like those that got me interested in the platform. Now I just had to understand how to get something done on the VCS. So on to coding.
How I learned to code on the Atari 2600
I tend to learn best from books where I can mix a bit of theory with some code examples, and then tweak those examples myself so that I internalize the specific concept. The VCS was no exception. I ended up buying two books:
- Making Games for the Atari 2600 by Steven Hugg.
- Programming Games for the Atari 2600 by Oscar Toledo G.
Both books are good. Really good. If you're serious about the VCS, then I recommend getting them both. The fundamentals obviously overlap, but the authors have different programming styles and approach problem solving from different perspectives. That said, if I had to chose just one of them, then I'd go with Oscar Toledo's book. That book has the advantage of providing the full code and context for each game, and I found it easier to follow the examples.
I chose to code directly in 6502 assembly, simply because I wanted to get as close to the 1977 feel as possible. Also, the advantage of assembly is that you really get to understand how the hardware works. That was an important goal for me. (If assembly doesn't float your retro boat, then there's also stuff like batari Basic which might offer a gentler introduction to the platform).
I did most work using the excellent Stella emulator. One big advantage now compared to the old days is that we have so much shorter development cycles. Using emulation, you can turn retro computer programming into a largely interactive experiment. Sweet.
Modernizing the Atari Hardware
My Atari learning journey coincided with the release of the Atari 2600+ platform. The 2600+ is a modern re-imagination of the classic console. It looks just like the real thing, although slightly smaller. However, unlike many other modern replicas, the genius move with the 2600+ is that it supports the old hardware, joysticks and gaming cartridges included. This means you can get the old games and play them on a modern TV with a minimum of effort. The 2600+ comes with a convenient HDMI port, so it's really plug an play. Beautiful.
The 2600+ opened up the Atari world to me. I soon started to hang out on auction sites to grab original copies of the games whose implementation fascinated me the most. This took me in an unexpected direction. You see, to a modern eye, an Atari VCS game looks ridiculously dated, primitive, and raw. Also, the first generation of games from 1977-1980 tend to have a repetitive feel to them: there's a single screen with action, and that's it. Repeat the same gaming sequence over and over, ad infinitum. However -- and to my own surprise -- that repetitiveness comes with a certain charm, too. Playing a VCS game has a meditative feel to it. It's relaxing, simple, and -- yes -- still fun after all those years.
How Coding Experience adds a Dimension to Retro Gaming
Learning to code on the VCS platform made me appreciate the gaming experience at a deeper level. Not only did the games enhance my respect for the pioneering work which went into these old cartridges; I could also appreciate what the programmers attempted to achieve and how they did it. That ridiculous screen flicker in my favorite game, the Wizard of Wor? Well, try to squeeze six moving sprites onto a hardware which only supports two(!). Instead of a nuisance, that screen flicker becomes an explanation: most likely, the programmer managed to put multiple sprites on screen by rendering them in different frames, e.g. alternating between rendering players and enemies. (And yes: this technique worked better on the old-school CRT TVs which have an afterglow that's absent on modern TVs). Trying the technique myself, I can attest that it's non-trivial to pull off. Timing is of essence, often down to the level where you need to count CPU cycles for your assembly instructions. (A lost art?)
Perhaps even more fascinating are the open world games like Berzerk or Pitfall. It's hard to imagine these days, but there was a first for everything. Pitfall was the pioneering side scrolling platformer. Think of getting 255 different scenes into 128 bytes of RAM and a mere 4K of ROM. Yes, I understand how a compression algorithm allows us to dynamically render scenes, but coming up with that idea in a time when there was nothing like it is beyond impressive. Very cool.
Finally, some things we take for granted today weren't on the Atari VCS. The console lacks a character set, yet you often come across later games that include both text and/or a player score. How was that done? Well, those characters and digits had to be rendered using the hardware sprites. Again: remember that you really only had two player sprites, and now you need to stretch those sprites to also render a potential game score. Yep, knowing the CPU cycles for your instructions and converting them to TIA cycles (Atari's proprietary "graphics" card) becomes an essential skill to get the rendering right. It's as low-level as it gets.
Obviously my newfound fascination for Atari VCS gaming fueled my collector gene, and I'm spending way too much money on original games. (I guess there's a downside to every hobby). On the other hand, a good VCS game is a piece of true art. Few things beat the over-selling from the box art on the cover when you compare it to how the actual game looks on screen.
Next Steps on the Atari VCS Programming Journey
Now that I have a decent grasp on the machine and the key programming tricks, it's natural to raise the bar. At some point I'm planning to release my own game. It will be hard work, but I seem to be in good company: the Atari VCS has a very active homebrew scene with a flood of novel games together with a friendly community.
Learning to code on the Atari VCS has been -- and still is -- a fun and rewarding hobby. You see, I started my Atari hobby during the time we pioneered using AI for automated code improvements. Going from Clojure, Python, and Generative AI during the day to 6502 assembler at night proved to be an interesting contrast. Those two tech stacks are worlds apart, and different enough to serve as a valuable way to decompress and re-charge. Also, there's something special about traveling back to simpler times when we could still understand the full software and hardware stack.
So do I recommend exploring the Atari VCS? Yes, I think this old platform still has a lot to offer. The coding itself will bring you little of immediate value, but there are deeper merits to it. Constraints frequently drive both innovation and creativity. As such, forcing yourself to re-think computer programming is something I recommend to all developers. And nothing I've come across forces you to think differently as effective as the Atari VCS. Is it a nerdy hobby? Definitely. Fun? You bet! And it's been fun since 1977.
About Adam Tornhill
Adam Tornhill is a programmer who combines degrees in engineering and psychology. He's the founder of CodeScene where he designs code analysis tools that empower teams to build great software.
Adam is also the author of Software Design X-Rays: Fix Technical Debt with Behavioral Code Analysis, the best selling Your Code as a Crime Scene, Lisp for the Web, Patterns in C and a public speaker. Adam's other interests include modern history, music, retro computing, and martial arts.