Fixing Bugs In A 37 Year Old Apple II Game

Emulators are a great way to reminisce about games and software from yesteryear. [Jorj Bauer] found himself doing just that back in 2002, when they decided to boot up Three Mile Island for the Apple II. It played well enough, but for some reason, crashed instantly if you happened to press the ‘7’ key. This was a problem — the game takes hours to play, and ‘7’ is the key for saving and restoring your progress. In 2002, [Jorj] was content to put up with this. But finally, enough was enough – [Jorj] set out to fix the bug in Three Mile Island once and for all.

The project is written up in three parts — the history of how [Jorj] came to play Three Mile Island and learn about Apple IIs in the first place, the problem with the game, and finally the approach to finding a solution. After first discovering the problem, [Jorj] searched online to see if it was just a bad disk image causing the problem. But every copy they found was the same. There was nothing left for it to be but problem in the binary.

title-screen
The revised title screen, with bugfix noted.

It’s a tale of disassembly and dredging though decades-old scanned literature. The key to the bug was found in a copy of the Micro 6502 Journal from June 1980. If you don’t want the story spoiled, stop here — the problem came about when someone copied an Apple DOS 3.1 version of the game to an Apple DOS 3.3 disk. The disk formats aren’t backwards compatible, so the 3.3 disk version would only play on a DOS 3.3 machine. However, the game’s code uses bytecodes in the save routine that refer to DOS 3.1 functions that had changed in DOS 3.3. It was by searching for this bytecode that the journal popped up on Google with a hint. The article mentions the changes in bytecodes between DOS versions, giving [Jorj] the clue he needed to solve the mystery.

In the end, to get the game to function properly under DOS 3.3, all that was required was to change the code to point to the proper register for DOS 3.3. With this done, the finishing touch was a modified title screen highlighting [Jorj]’s hard work. Credit where credit is due.

Kindly, [Jorj] has uploaded the fixed game for the world to enjoy (.gz file download)! It’s always great to see people still working with and enjoying these old systems. The Apple IIGS even got itself an OS update at age 29.

19 thoughts on “Fixing Bugs In A 37 Year Old Apple II Game

  1. The difference between features and bugs is simple.
    BUG: a problem within code which is found and fixed.
    Feature: A problem within code which has not been found after 5 years.

    This has been a feature for a very long time. So this is not a bug fix.
    It’s a feature change plain and simple!

      1. Thanks!

        I think it’s fair to say it’s a feature change, although that wasn’t obvious when I started. Unless they actually distributed it on DOS 3.3 disks in this broken state at some point, which seems unlikely.

  2. Change bytecodes -> addresses in this summary to make sense.

    All of the old Apple II stuff did this. They’d jump directly to routines in ROM and the DOS so if the devs weren’t careful, they’d break random programs because they’d end up jumping into the wrong part. A lot of work by Apple was spent keeping all the popular addresses the same when they altered code.

    1. Were the programmers doing things they shouldn’t have, or did Apple not have any kind of function dispatch mechanism in their OS? The Commodore Kernal (sic) used a jump table which provided some compatibility across their 8-bit computers.

      1. The latter. This is really early days, bootstrapped off of the history of the Apple I then II. Developers were creative about how to get things done using routines that existed in the ROM. I don’t know that any of them were initially documented. As they became commonly used, Apple worked hard to keep the memory addresses the same for the ones that were most popular — which explains the well-defined dispatch mechanism of the Macintosh. Lesson well learned :)

        1. Not too well learned in practice with every incremental update from 7.5.0 through 7.5.5. Every update broke someone’s software. Then they’d update for the current OS revision and Apple would break things again with the next patch. 7.5.1 was soooo horrible Apple swiftly withdrew the update then release the 7.5.2 patch. It got so bad that a large number of companies just threw in the towel at 7.5.2 or 7.5.3, never went back to Mac. Radius quit updating their software and drivers for a large amount of their Mac hardware at 7.5.3. It either can’t be used at all with 7.5.5 and later or has reduced functionality. Apple never released a 7.5.5 that directly installs that version, instead a “7.5.5” install installs 7.5.3 then the 7.5.5 Update. Like all Classic OS updates it ignores your custom choices and blows in *everything* so you have to dig in and delete useless junk like drivers for all the Apple printers you don’t have and the A/ROSE extension for the network card with a 68000 CPU that nobody has.

          Apple then knuckled down and tried really hard to not make a (worse) mess of things with 7.5.5, then started on PPC optimization with 7.6. There’s no reason to update to 7.6.1 on a 68k, all the changes are (supposedly) in the PPC code.

          Apple apparently deliberately repeatedly broke things for certain 3rd party software, for the ‘crime’ of doing things better than Apple. Jump Development’s RAM Charger being one of them. Combine RAM Charger for memory management and Connectix RAM compression / virtual memory replacement (turn off compression) and you have far better memory handling than Apple could figure out with the Classic OS. RAM Charger works 100% through OS 9.1, then Apple broke things again with the 9.2 update and Jump gave up fixing their software to account for Apple’s being petulant over being shown up. The important management function still works on 9.2 and 9.2.2. It automatically sets RAM size allocation to the size of the program plus a bit, then automatically allocates additional RAM as the software requests it, then takes it back when the program is done with it. RAM Charger also does on the fly RAM defragmenting, remapping all free RAM into a single contiguous free block so you don’t get the not enough RAM error due to fragmentation. So why would Apple try to keep that software from working, instead of either copying how it worked or licensing a feature subset of it, like they did with SuperClock, Extensions Manager and many other not invented at Apple software?

          Now there’s something for a current hacker to fix, make RAM Charger 100% working on MAC OS 9.2.2.

  3. Great stuff !

    I remember one of my favorite Apple ][ games was Robotron, but it was a hard one.
    So to achieve unlimited game life, I did some research inside the disassembled code and I changed “DEC lives” by “INC lives” at each kill !

  4. Can someone less lazy than me make sure that the Internet Archive gets a fixed version? There’s more than one Three Mile Island up there already, and it’s nice that it plays in-place, but the one I tried crashed to the prompt when 7 was pressed.

  5. Those lo-res graphics are downright adorable.

    I’ve been reading the Micro 6502 Journal archives recently and wow I have a whole new appreciation for personal computing from that era.

    1. I remember days of meticulously typing in programs from publications like this by hand. There’s nothing quite like having to type byte-by-byte, trying like hell to avoid mistakes in transcription. I certainly don’t miss that part of it…

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.