Atari 2600 Java
Posted: December 20, 2015
A while ago Joe Davisson added 6502 support to Java Grinder with a Commodore 64 API and demo. Since the old Atari 2600 video game system designed in 1977 also runs on a 6502 variety CPU (the 6507), I was curious if I could create a little Java API for writing code on this platform. I made an Atari2600.cxx class in Java Grinder which extended Joe's M6502.cxx class and started throwing together some code. After Joe saw what I came up with, he took over the Atari 2600 generator adding sound, sprites, and more to the API and creating a game called Space Revenge (click to download to run in an emulator). Cheesy name, cheesy music, and could have sold like crazy in 1982 :).
Keep in mind that that Atari 2600 only had 128 bytes of RAM and 4096 bytes (4kB) of space for software (without the bank switching). The first sentence of this paragraph is 131 bytes (characters) long and is too big to fit in the RAM space of this computer.
Related Projects @mikekohn.net
Above is Joe Davisson's Space Revenge game written in Java and running in the Mess emulator. Feel free to download the game here: space_revenge.bin to play it on an emulator. Full video: https://youtu.be/VN-8Z4VUjzg
I started coding this demo for Java Grinder running on the Atari 2600. This is supposed to be the Atari logo.. or something like it. Joe ended up adding a little song to it too. I built a binary of the demo here: atari_2600_java_demo.bin to run on an emulator. Full video: https://youtu.be/H60ybAIkgcc
Some of this was actually quite easy and some of the Java methods compile directly into just 1 or 2 6502 instructions. At the same time, the Atari 2600's graphic chip is extremely primitive and requires quite a bit of the CPU's power and some.. not exactly precise timings, but timing is important. I added sound, joystick, and collision support .. and pretty much every other control register in the Atari 2600.
Joe added playfield and sprite drawing support directly into the API so a game developer doesn't have to worry about the complexities of drawing the playfield and sprites, and started writing a game around it. The 16 bit nature of the M6502.cxx generator module was making the size of the generated Atari 2600 code bigger than the 4k of the ROM, so he created a M6502_8.cxx generator module that creates pure 8 bit code for the Atari.
Even with the 8 bit version of th 6502 code geneator, he still wasn't able to fit both a title screen with music and the game into the 4k ROM size limit. Since the Atari 2600 only gives 12 addressing lines to the cartridge port, 4096 bytes is the size limit for any Atari cartridge. To get around this, Atari 2600 developers would put multiple 4k ROMs in a cartridge and add some circuitry that would allow them to select which 4k ROM is currently attached to the bus. It ends up the emulators know how to deal with ROM files that use this technique (known as bank switching). Joe ended up creating 2 separate programs in 2 separate ROM files: one was a title screen with music and the other was the actual game. I added to Java API the ability to do bank switching and modified the makefile so it compiles both ROMs and concatinates them together.
The source code for the game is in the Java Grinder repository.
Atari 2600 Playfield Complexity
Newer computers, like the early 1980's Commodore 64 and Apple II, would give the programmer a chunk of RAM that they could put an entire image into. The video chip in those computers take care of things like applying the vertical sync signal to the computer monitor (or TV) and taking care of blanking. In the Atari 2600, the graphics chip gives the programmer 20 bits of bitmap drawing area that is drawn on only 1/2 of the display and then either repeated on the other half or mirrored. That same 20 bits is drawn on every scan-line on the screen. So the programmer has to figure out when the horizontal blank is starting and change the bitmap and color registers before the TV starts drawing again. That horizontal blank time is only 76 CPU clock cycles in length, so not a lot of time. The programmer also has to count 192 scan lines and apply vertical sync and vertical blank themselves. This proved to be not so simple in Java. Since the Atari 2600 can halt the CPU until horizontal blanking starts, I made a method Atari2600.waitHsync(). I tried to put a for loop around it to count lines, but that was too slow. So I ended up adding Atari2600.Hsync(int lines) so the for loop could be done in tight assembly.
The source code to the demo Atari2600JavaDemo.java shows how this is done.
Copyright 1997-2021 - Michael Kohn