Progress 2600

After a couple of weeks of breaking my brain on the Atari 2600 game I’ve been working on, I’ve finally made some significant progress.  I now have a gradient sky and grass background, the castle, a player-controlled ballista, and the ability for the ballista to shoot an arrow upwards into the sky when the player presses the joystick button!

castle20180201

After my last post on the game, I spent three weeks working on a general purpose “kernel” (the part of the program responsible for drawing what you see on the screen) that would do everything I wanted in one little package.  It took too long for me to realize that this was never going to happen.  There is just not enough processing power for it in the Atari 2600.

The visible image displayed by the Atari is divided into 192 horizontal lines (called “scanlines”).  This means the Atari effectively outputs a 192p resolution image — a far cry from the 1080p resolution many TVs have today.

Each scanline is drawn from the left to the right.  In old CRT televisions, an electron beam is shot at the screen from the inside of the tube.  This beam is what actually illuminates the screen with colors.

crtbeam

After the right edge of the screen is reached, the electron beam moves back to the left and down in order to start drawing the next scanline.

During each scanline, the Atari programmer has 76 “cycles” worth of processor time to execute commands which will tell the TV what to draw on that specific line. Individual instructions (like adding two numbers, storing a value into memory, reading a value from memory, etc.) typically take between 2 and 7 cycles each to execute.  At best you can perform 38 2-cycle-long instructions per line.  In reality, however, doing something useful will require that you run instructions that take more than 2 cycles to run.

As if being starved of processing power wasn’t enough, you actually only get 22 of those 76 cycles to work with before the graphics for that line start getting drawn!  (Technically, this is the time that the electron beam is not drawing as it moves from the right edge of the screen back to the left edge in order to start drawing the next scanline).  If you try to tell the Atari to draw something on the left edge of the screen by the 23rd cycle in the scanline, it’ll be too late and the TV won’t draw what you wanted.  Because of this, your program always has a few steps ahead of the TV’s drawing beam in telling the TV what it’s supposed to draw.

It typically takes a minimum of 21 cycles to execute the necessary instructions to prepare the “playfield graphic” for the current scanline:

lda PFData0,y   ; Load playfield graphics 1 to draw (takes 4 cycles)
sta PF0         ;  Set playfield graphics 1 to draw (takes 3 cycles)
lda PFData1,y   ; Load playfield graphics 2 to draw (takes 4 cycles)
sta PF1         ;  Set playfield graphics 2 to draw (takes 3 cycles)
lda PFData2,y   ; Load playfield graphics 3 to draw (takes 4 cycles)
sta PF2         ;  Set playfield graphics 3 to draw (takes 3 cycles)

The very next instruction after that will finish on at least the 23rd cycle of the current scanline, which means that it’s too late to get the TV to draw anything else directly along the left edge of the screen.

In my program, this background graphic is the castle.  On a scanline where any part of the castle appears I can’t draw anything else along the left edge of the screen.  Anything I want to draw on the same scanline (like the player-controlled ballista) will have to be positioned a little ways from the left edge if I want it to appear.

By a fortuitous happenstance, I had originally planned for the ballista’s movement to be limited to within the castle — the player could never move the ballista past the towers to the left and right.  Thanks to this limited movement range, I had enough time after setting the castle playfield graphics to also set the ballista graphics before the ballista itself ever needed to be draw.

Drawing the ballista currently takes about another 24 cycles in my code.  This brings me to a total of 45 out of the 76 cycles available for the current scanline.  At this point, the TV has drawn half the scanline, so I can’t draw anything more on the left half of the screen.  If I want to draw a second object on the same line, it will always have to appear on the right half of the screen.  This isn’t acceptable with my current goals for the game.

What most Atari programmers end up doing is to halve the vertical resolution of their game in order to double the amount of processing power they have per line.  This works due to various technicalities with the Atari hardware which can cause it to draw every other scanline in the exact same way as the one before it (this technique is typically called a two-line kernel).  The side effect is that the vertical resolution of the game is now reduced to 81p.

This double-scanline processing gives you more time to properly draw another object on the same line, but it still wasn’t quite enough for what I originally wanted. This is due to the fact that in order to draw all the objects I wanted I would have to reuse the limited amount of sprites (i.e. animated objects) available in the Atari.

Re-using a sprite meant I would have to re-position it in the middle of the screen.  Re-positioning a sprite while the screen is drawing results in a thin black horizontal line appearing on the left edge of the screen.  These black lines can be seen on many professionally released Atari games from back in the day, like Vanguard (pictured below), and was the only way to get the Atari to draw more than two complex shapes on the screen at a time:

atari_vanguard_hmove

While attempting to create a general purpose kernel, I decided it would be smart to really think about what I actually needed the program to do.  I took a look at all the possible things I wanted to have happen on the screen, and from this I determined how many things would need to be drawn on the same line, and where on the screen they would be drawn.

I took a screenshot of my game and, using a graphics editor, added some fake graphics to it to mock up a game screen with all the possible things that could appear onscreen being drawn at once (e.g. the ballista, an arrow, two dragons, fireballs, the castle, etc.).  The game would never be in this state, but it gave me a starting point for dividing up the entire screen into multiple horizontal sections.  These sections defined points where the program would have to draw different things.  For example, the player-controlled ballista will not be able to move vertically, so I divided the part of the screen where it would be drawn into its own section.

After splitting the screen into several sections, I then focused on looking at how many things could possibly be drawn simultaneously within the same horizontal section.  I made a couple of game design decisions at this point which would limit the amount of work I would ever have to possibly do within one horizontal section.  For example, I decided that if two dragons were onscreen at the same time, they would always appear at two different, non-overlapping altitudes, and only the lower dragon would ever shoot fireballs.  This meant that I would never have to worry about drawing either two dragons or a dragon and a fireball on the same line.  This helped a bit, but my ideas were still too much for a general purpose kernel.

During all this time, I was also researching how other people were able to draw multiple sprites onscreen at once.  I came across a forum post somewhere which mentioned that some people write multiple kernels to handle this, with each kernel being responsible for drawing only a certain portion of the screen.

With this new approach in mind,  I took my program, threw away most of what I had written, and started over again almost from scratch.  This time, instead of using a single general purpose kernel which would be responsible for drawing the screen, I created multiple kernels, each one of which would be responsible for only drawing a small section of the screen.  I made the program change the background color within each section to help visualize everything:

castle20180128

This seemed like a promising new start.

With this done, I decided to implement the arrow sprite, which is what the player would be shooting up at enemies.  The arrow sprite would only ever need to be drawn in the sections above the one in which the ballista would be drawn, so I modified only the kernels responsible for those sections, making them call a subroutine which would draw the arrow.

I got this working in fairly short order with the arrow moving from the lower-middle of the screen to the top.  The arrow would then looping to the bottom and repeat the animation indefinitely.  In the image below you can see the arrow being drawn near the top-left corner of the screen.

castle20180129

Next, I tweaked the program so that the arrow would no longer loop and, instead, would only rise to the top of the screen once.  In effect, I made the program automatically shoot the arrow once when the program started.

After this I hooked up the joystick button input to the arrow drawing logic and made it so the player would control the shooting of the arrow.  Every time the player pressed the joystick button, a new arrow would fire up toward the top of the screen.

Then I decided to re-implement the code which controlled the ballista’s horizontal movement, and made it so that the arrow would be fired from whatever horizontal position the ballista happened to be at.  I didn’t actually get the ballista to draw at this point, but I was now able to control when and where the arrow would be fired.

With the arrow graphics logic pretty much completed, I then added in code to draw the ballista.  At this point, things got a little screwy:

castle20180130

My code was taking too long to draw the ballista, so it ended up getting stretched out and drawn incorrectly.  I was also unnecessarily re-positioning the ballista to the same point multiple times on ever frame, resulting in all the black lines to the left of the ballista.  I cleaned up my code a bit and resolved these issues.

Adding in the castle graphics screwed everything up again, and it took a little longer to resolve all that (I neglected to take a screenshot of it, but, trust me, it was a mess).  Once I got the castle drawing correctly, however, a new problem appeared: whenever an arrow was being shot, the section it was currently in would expand in height if that section also had some of the castle drawn within it.  This took further refinement of the code to resolve.

Eventually I got things drawing mostly the way I wanted with only some minor glitches, such as the uneven bottom of the left half of the rear castle.  I’m living with that for now and might try to fix it later.

castle20180201

One thing I’ve certainly learned about programming for the Atari 2600 is that “the perfect is the enemy of the good”.  If you try to get things perfect, you’ll a) never reach that point, and b) miss out on things being “good enough”.

Again, you can see the acceptance of small imperfections in professional games, such as with the black lines on the left edge of the screen in Vanguard (pictured earlier), or the dip in the left edge of the ground in Space Invaders:

atari_space_invaders_imperfection

In any case, it might be time to try getting the ballista in my game to appear in multiple colors and/or display an animation whenever the player fires an arrow.  We’ll see what the next few weeks will bring.

Atari 2600 Programming

It’s been a while since I last looked into writing programs for the Atari 2600. The last thing I was messing with was drawing a sort of castle onto the screen. I was having a bit of trouble with that and my interest eventually just petered out.

I recently returned to this project and got the castle to draw nicely. I then added a sky and grass to the background, then I added some fancy shading to the grass. Here’s a screenshot of what I have so far:

I would like to eventually use this as the basis for some sort of game. The idea currently swimming in my head is to have the player control a ballista inside the castle which he could move to the left and right. Dragons would fly across the screen in the sky and the player would have to shoot them.

The dragons would vary in color, with certain colored dragons being faster than others. The dragons would also shoot fireballs down at the player. If possible, it would be cool to add swooping dragons as well.

We’ll see if any of that ends up happening.

I’m experimenting with drawing sprites right now (sprites are things that can move, like the player for example). I’ve managed to get the player 1 sprite to display, but it’s not anything usable for a game yet.

I’m optimistic that I can get a moveable player on the screen soon. I’m a little worried that the sprite logic might force me to simplify the color gradient for the grass — processing power is very limited on the Atari.

I’ll probably post the source code for this program once I have a moveable player implemented.

Atari 2600 Programming

atari 2600When I was a kid, our family had an Atari 2600 Video Computer System, as did many of our friends and relatives.  We had a good number of games, and many great memories were made playing them.

A few years back I got a book (Racing the Beam: The Atari Video Computer System, by Nick Montfort and Ian Bogost) that talked about how those old games were programmed.  It was quite fascinating.  The approach to programming the Atari 2600 is quite a departure from what I do every day as a software developer.  I gained a lot of respect for the old Atari game programmers; they performed incredible feats of coding.

More recently, on a whim, I decided to read up on Atari 2600 programming about a month ago.  Here’s a little bit of what I’ve learned:  To run games, the Atari 2600 uses a MOS Technology 6507 microprocessor (a variant of the MOS Technology 6502, a generic 8-bit microprocessor which was first produced in 1975 and is still used in hundreds of millions of devices to this day).  This is the central processing unit: the chip that executes the software written by Atari programmers.

The central processor interacts with two other chips.  One is the MOS Technology 6532, another generic chip designed to provide RAM (only 128 bytes — your computer probably has at least eight billion bytes or more), a couple of I/O ports for interfacing with peripherals (e.g. joysticks), and a timer. The other is a custom chip called the Television Interface Adapter (or TIA), nicknamed “Stella”.  The TIA is responsible for generating the signals that are sent to a TV in order to generate images and sound.  The TIA was designed to keep costs down, and cost-cutting measures led to the chip exhibiting some very peculiar behaviors which required arcane knowledge and carefully timed commands to effectively control.

After learning about programming the 6507 to control the TIA, I’ve discovered that the Atari’s reputation for being notoriously difficult to program games for is not overstated.  First of all, in 1975 we didn’t have computers powerful enough to provide layers of abstraction between the programmer and the hardware which act to simplify programming tasks. The Atari requires coding in an assembly language — literally the lowest level of programming possible in a computer (sometimes called “bare-metal” programming because of the programmer’s metaphorical proximity to the physical hardware).

To illustrate the difference between modern software development and programming in assembler, imagine that you want to write a poem on a piece of paper.  Modern programming is like you grabbing a pencil, then manipulating that pencil to write the desired words on a piece of paper.  With assembly programming, if you want a pencil, you can’t just grab one — you have to first chop down a tree to get some wood, mine some graphite out of the ground for the lead, etc.  Programming in assembler for the Atari’s Stella chip is like you having to time those axe and pick swings in step with your heartbeat or you die.

The ultimate testament to the skill of the original Atari programmers is the fact that the games for the Atari 2600 could not be longer than 4096 bytes.  The entire text of this blog post you are reading takes up a little bit more than that!

So, I decided to try my hand at doing a little Atari 2600 programming myself. I followed a tutorial by Andrew Davie to get started.  Unfortunately, some of the code examples had bugs in them that made learning Atari programming very frustrating at times — I had to debug code that I was in the process of learning!

Here is my first Atari 2600 program (hosted on Google Drive — please leave a comment if there’s a problem with the link).  All this program does is display a Canada flag.  It might not seem very impressive, but if you’re familiar with Atari programming you’ll know it’s no trivial task.

canflag0 screenshotThis zip file contains the compiled ROM that you can load up and run in an Atari emulator like Stella (named after the Atari’s custom chip).  If I had the hardware, I could literally burn this ROM file into a writable Atari cartridge and run it on an actual Atari 2600 machine.

Also included is the source code to which I’ve added copious amounts of comments to make it easier to follow (feel free to tinker with it), and a symbol dump file generated by the program that compiled my code which shows exactly how each command in the source code is converted into numbers that the 6507 can understand.

Also, if you’re interested, here is a PDF of the 1979 Stella Programming Guide.

Edit: Spiceware has also put up an excellent programming tutorial as multiple topics on the AtariAge forums.