The platform has produced some masterpieces of creativity under limitations. You have 128 bytes of RAM to work with (for all non-register variables and stack) and slavish timing requirements.
The timing is nightmarish because you're actually controlling the painting of each scanline as the raster sweeps across and down the screen. The design of an Atari 2600 game's "kernel" (as they're called) is one where timing and cycle counting dominates.
Game logic has to sit in specific points in time where the video raster isn't painting (horizontal and vertical blanking intervals). When the raster is sweeping across the phosphors your code is concerned primarily with manipulating the registers of the Television Interface Adapter (TIA) chip to produce the desired video output. There are some "tricks" the TIA can perform itself (mirroring the playfield output across a vertical center line, etc) that can be used to free up some cycles. Creative use of the 5 movable objects (two "player" sprites, two "missile" sprites, and a "ball" sprite) can be used to make more detailed graphics than would be possible with the playfield alone (which has a fairly coarse resolution).
And as the CPU was a 6502, you had three 8-bit registers within the CPU, one 8-bit accumulator and two 8-bit index registers.
There's more tricks with the stack pointer on this machine too. Set it to point to the top of a sequence of video registers, and then you can rapidly write values to that sequence of registers just by issuing push instructions, which are faster than load/store/decrement!
I am remound of the perennial HN favorite: http://blog.moertel.com/posts/2013-12-14-great-old-timey-gam...
What you do is set the stack pointer to that video register, compare on the object's Y-coordinate, then push the flags register to turn the object on or off! So the code needs no shifts or conditions or branches. It's even cycle invariant which is a great property on this machine.
The video hardware was deliberately designed to do this (by chip legend Jay Miner), and Combat's code does. Also, the registers for the two missiles and the ball are adjacent, so you can do this trick to all of them in succession without resetting the stack pointer.
BTW - I saw in your other comments that you wrote INV+. This counts as my little brush with "celebrity" for the day. >smile<
How did that work on the 2600? The 6502's stack pointer is also only 8-bits, just like the other registers, and hardwired to use page 1 as the upper byte of the ultimate 16-bit stack address. Were the video registers mapped into the page 1 address zone?
It's not so much a mapping as a lack of mapping. The hardware simply doesn't decode address line 8. So accessing 0x002F and 0x012F are the same video register for example. If you push something to 0x01FF, you can read it from 0x00FF.
There are more duplications within the address space as well. Address lines 13 and above don't exist in hardware on the 2600, so 0x20FF and 0x40FF and 0x60FF etc also access the same thing. The video registers from 0x00 through 0x3F are also duplicated from 0x40 through 0x7F, by not decoding address line 6 either. The important one is address line 12, which enables the cartridge ROM instead of the video/RAM; in fact that line is wired directly to the chip-enable pin on the cartridge slot.