[HN Gopher] Atari 2600 hardware design: Making something out of ...
       ___________________________________________________________________
        
       Atari 2600 hardware design: Making something out of almost nothing
        
       Author : zdw
       Score  : 80 points
       Date   : 2023-01-12 04:38 UTC (2 days ago)
        
 (HTM) web link (www.bigmessowires.com)
 (TXT) w3m dump (www.bigmessowires.com)
        
       | aswanson wrote:
       | I look at stuff like this, amazed at the efficiency, and then
       | realize I scoff at a new 32 bit cortex MO chip for shipping with
       | only 64K of ram and 12K of flash at 48 Mhz.
        
       | cardanome wrote:
       | I have actually recently picked up Atari 2600 homebrew
       | development as a hobby.
       | 
       | My reasons are:
       | 
       | 1. The hardware is simple enough that you can completely
       | understand everything that is going on. And you absolutely need
       | to understand it, if you want to make good games. Just a great
       | feeling of power and control.
       | 
       | 2. You need to use assembly. Even with 8-bit era computers you
       | don't really need to use assembly. Sure, for performance but for
       | many task even the dog-slow Basic of the C64 could get you far.
       | Not many excuses to write substantial amounts of assembly these
       | days, so I really enjoy the challenge.
       | 
       | 3. You are forced towards radical simplicity but the hardware is
       | still strong enough that you can make games people might want to
       | play. Even in 2023.
       | 
       | There are great fantasy-consoles like the pico-8 these days but
       | they don't scratch the same itch for me. I enjoy the historicity
       | of programming for a real and very influential console.
       | 
       | Plus, the 6502 instructions set you learn used to be ubiquitous,
       | giving you a head start if you want to program for the C64, NES,
       | Apple ][ and many more systems.
       | 
       | I recommend using https://8bitworkshop.com/ as you can get an
       | instant feedback loop when developing your game.
       | 
       | I haven't yet finished making a game but I am having great fun!
        
       | corysama wrote:
       | > Look at this image of Pitfall, and notice how the tree canopy,
       | tree trunks, ground, pit, and underground cave all show left-
       | right symmetry. These are all built from the playfield (plus
       | additional tricks to be described later). The only sprites are
       | Pitfall Harry, the vine he's swinging from, the rolling log, and
       | the scorpion.
       | 
       | I read in a similar article that the branches of the trees are
       | too finely detailed to be drawn with the playfield layer. So,
       | they are added on with sprites.
        
         | Eleison23 wrote:
         | [citation needed] for that assertion. Atari 2600 is extremely
         | limited in the number of sprites available on-screen at the
         | same time. If you've played Pac-Man then you know that 5 is too
         | many, because all of the so-called "ghosts" are actually
         | flickering. They're doing that not for a spooky effect, but
         | because they can't be simultaneously displayed. That sort of
         | sprite flicker doesn't happen in Pitfall!
        
           | tom_ wrote:
           | The sprites can be replicated by adjusting NUSIZn for the
           | player of interest: https://archive.org/details/Atari_2600_TI
           | A_Technical_Manual/...
           | 
           | Looks like the tree branches could be two copies on the left,
           | then two more on the right. Not much going on in that region
           | so plenty of time.
           | 
           | EDIT: presumably this bit: https://github.com/johnidm/asm-
           | atari-2600/blob/8b613f3c4bc80...
        
       | alex_suzuki wrote:
       | I can recommend ,,Racing the Beam" to anyone curious about the
       | Atari 2600. It's a great book!
       | https://en.m.wikipedia.org/wiki/Racing_the_Beam
        
         | jdblair wrote:
         | +1, a super interesting read
        
       | tenebrisalietum wrote:
       | > What's worse, this tiny amount of RAM had to serve as both the
       | scratchpad/heap and as the stack!
       | 
       | Heap? Lol you are not doing ANY dynamic allocation of any kind on
       | the Atari 2600.
       | 
       | Also you're not using the stack to pass parameters to routines
       | here either. You might not even use subroutines.
       | 
       | > This pin-reduced 6507 eliminated the 6502's NMI and IRQ pins,
       | so there was no hardware interrupt capability at all. Everything
       | had to be accomplished with software timing and polling.
       | 
       | STA WSYNC will make the CPU halt until the TIA is at the next
       | scan line. This is the chief video synchronization tool on the
       | Atari 2600. You do have to keep track of the number of scanlines
       | you've generated. Horizontal timing takes care of itself but you
       | need to track that too for various effects.
        
         | djmips wrote:
         | Every time you do a JSR $XXXX it's doing dynamic allocation of
         | sorts. The return address is kept on the stack. I honestly have
         | never seen a game of any complexity that doesn't use
         | subroutines (it saves ROM).
        
           | tom_ wrote:
           | No idea whether it meets your personal complexity bar, but
           | 2600 Centipede seemingly doesn't contain a single JSR or RTS:
           | https://github.com/DNSDEBRO/Disassemblies/blob/master/Atari2.
           | ..
        
         | LastTrain wrote:
         | Thanks, I almost had to stop reading after seeing multiple
         | fundamental misunderstandings like that. I respect the author
         | and have BMOW stuff for my Mac, but he should throw a big "I'm
         | new to this" caveat around this article.
        
           | kgwxd wrote:
           | Geez, it wasn't that bad, but the article is literally
           | wrapped in disclaimers.
           | 
           | "Recently over the holiday break, I became interested in the
           | 2600's hardware architecture"
           | 
           | "Did I butcher some technical explanation here, or omit
           | important details? Please let me know! I'm just a beginner on
           | this Atari hardware journey, with much still to learn."
        
         | klelatti wrote:
         | > Also you're not using the stack to pass parameters to
         | routines here either. You might not even use subroutines.
         | 
         | Well that 128 bytes was in the upper half of page 1 and the
         | 6502's stack was in page 1, but at least one source says that
         | the upper half of page 1 was also mapped to page 0.
         | 
         | I'd guess that at least some programs would push to the stack -
         | if nothing else you could save a byte when storing a byte to
         | memory (PHA vs STA #FF).
        
           | erosenbe0 wrote:
           | Yes, if the 128 of the 6537 is mapped starting at 0x100, then
           | one would use ldx, txs, pha, pla, etc., for any possible
           | optimization. S register is a precious resource! Anything to
           | squeeze between those hsyncs.
        
           | cardiffspaceman wrote:
           | I worked on a system in which the address decoding for the
           | RAM mapped $0-$1FF to 256 bytes of RAM. Fortunately it was
           | easier to do graphics on that than on the 2600
        
       | mgkimsal wrote:
       | Can't remember if I read it here recently, or on reddit, but this
       | conference session with David Crane on Pitfall/Atari is pretty
       | good. He doesn't _as_ technical as some folks may want, but there
       | 's some coolness in just hearing him explain this in person.
       | Couple of interesting Q&A bits towards the end too.
       | 
       | https://www.youtube.com/watch?v=MBT1OK6VAIU
        
       | a1k0n wrote:
       | > If anyone has an idea why the TIA's designers used LFSRs for
       | this stuff, I'd love to hear about it.
       | 
       | I'm guessing because a counter would have ripple carry (i.e. five
       | extra gate delays when rolling over from 111111 to 000000) or
       | need extra gates for carry lookahead and an LFSR is constant-
       | delay.
        
         | djmips wrote:
         | The latency notwithstanding, you can implement a counter with
         | an LFSR that hits every unique value in a 2^n-1 sequence with
         | less transistors than a standard counter.
        
           | userbinator wrote:
           | This is the reason. LFSRs are much simpler to implement, and
           | in those days, every transistor saved was very important.
           | 
           | Some early microprocessors used LFSRs instead of a regular
           | counter for their instruction pointer register for this
           | reason: https://news.ycombinator.com/item?id=8375577
        
       | kgwxd wrote:
       | There's new games being made for the 2600 all the time. A few
       | years ago I got really into it but never made anything worth
       | sharing. However, I found a Twitch stream called ZeroPageHomebrew
       | [0] that I've been watching religiously ever since. They used to
       | just cover 2600 homebrews but they've recently branched into
       | homebrews on other early Atari systems as well. The developers of
       | the featured games are often in chat, sometimes they do call-in
       | interviews. It's on twice a week and they never run out of new
       | things to show.
       | 
       | [0] https://www.twitch.tv/zeropagehomebrew
        
       | Waterluvian wrote:
       | > These LFSRs also use two separate clocks, 180 degrees out of
       | phase
       | 
       | Does that just mean they take turns ticking with equal interval
       | between ticks?
        
       | thought_alarm wrote:
       | I haven't read _Racing the Beam_, but the impression I get is
       | that while the 2600 looks crazy, it actually wouldn't be _that_
       | difficult or insane to write a graphics kernel to generate the
       | screen layout you need. It 's just a matter of keeping track of
       | what line you're on and feeding in the correct data. It seems
       | tedious, but that's what computers are for.
       | 
       | Once the graphics kernel is written, it just a matter of playing
       | with the data that's fed into it.
       | 
       | The real challenge, it seems, it simply that there are so few
       | cycles left over to implement the actual game logic.
        
         | Someone wrote:
         | > The real challenge, it seems, it simply that there are so few
         | cycles left over to implement the actual game logic.
         | 
         | I haven't programmed the 2600, but I expect that, in about
         | every program for the 2600, running out of time for your game
         | logic is unavoidable, and will make you go back to your
         | universal, (relatively) easy to use kernel and tweak it to make
         | it just a little bit faster for your particular use case.
         | 
         | Given that that kernel will be written in tight assembly, I
         | expect that more or less amounts to a rewrite. You'll use your
         | knowledge f the kernel to write a new one.
        
           | psychphysic wrote:
           | Even on the NES and I'm sure more modern consoles and maybe
           | any game.
           | 
           | You often round robin game logic.
           | 
           | Here's a fun example Castlevania on the NES by timing your
           | movement precisely you can make it skip certain blocks being
           | loaded. Making it leave a stair case or even a door.
           | 
           | Works because alternate even and odd frames responsible for
           | loading different y coords for level data in blocks.
           | 
           | https://m.youtube.com/watch?v=Dw7NkOzp8tE
           | 
           | It might seem like there's no point now..but even in a 120fps
           | game do you need absolutely everything to update at 120hz?
        
             | djmips wrote:
             | Believe it or not we still amortize work and have game
             | architecture where the sim updates at a much lower
             | frequency than the game presentation.
        
         | kgwxd wrote:
         | Many new games are made with an arm processor built in the
         | cart[0]. I'm not super familiar with how it works but they do
         | some really fancy graphics kernels. Still limited by how the
         | graphic/color registers work and not many cycles to change them
         | all at the right time.
         | 
         | [0] https://forums.atariage.com/topic/330778-part-1-cdfj-
         | overvie...
        
           | djmips wrote:
           | Despite the arm processor in the cart it barely helps with
           | the kernel and game code in most games. Typically they are
           | older not so powerful Cortex M0 and it is largely tied up
           | emulating the cartridge hardware. It can give modest gains
           | when doing the kernel but most of the fancy graphic kernels
           | are designed as they always have been - with a lot of deep
           | human thought.
        
         | ant6n wrote:
         | Here's a detailed video by retro game mechanics that shows how
         | the logo graphics of the infamous E.T. game is rendered:
         | https://youtu.be/sJFnWZH5FXc
         | 
         | It seems incredible, very difficult. And remember, back then
         | cartridges only had 8KB of memory.
         | 
         | This means even more hacks are required, if your game needs
         | more than a few levels. Theres a recurring hn post how Pitfall
         | encoded levels in a single byte (bitfield), then used some sort
         | of sequence generator to allow going back and forth among the
         | 255 levels.
        
         | jandrese wrote:
         | The other real challenge is that you have to build your entire
         | game using just 128 bytes of memory. Not kilobytes, bytes. You
         | don't have the luxury of having a single scanline of the screen
         | at memory at once. There is no caching of anything. You have
         | just enough memory for a handful of current state variables and
         | that's it.
         | 
         | Luckily your program is running out of ROM so you don't have to
         | load it before you execute, but even with that it's an
         | incredibly tight fit.
        
         | djmips wrote:
         | Easier said than done. Implementing the game logic during the
         | vertical blank is actually more straightforward.
        
       ___________________________________________________________________
       (page generated 2023-01-14 23:01 UTC)