I'm an Apple ][ fan. One game from my childhood keeps crashing on me... and it's time to finally fix it!
My great aunt used to say that she had a great Forgettery. I think I inherited it. My Remembery is faulty.
I can remember really arcane and worthless trivia, like "CALL -151" enters the machine monitor on an Apple ][ and that the HERO-1 robot had a built-in speech synthesizer with the phrase "I don't do windows". Useful everyday stuff, like where my wife said the various knives belong in the knife drawer? Not a chance.
This works out pretty well for this project, though! I still remember enough of how to get around the Apple //. The assembly language looks familiar. I can poke at executables in memory. I can boot various kinds of DOS and transfer files between them. With ProDOS and Virtual ][, I can copy files back out to my Mac and use all of the tools I've got there, too. But I need a bit of a refresher - I haven't looked at the internals of the Apple //e since 1989. I don't remember what $C010 is, but I do remember that $C000 is the beginning of ROM. But it's a fast study: I quick remember zero-page memory, Applesoft BASIC tricks with magic values therein, and find references for various ROM entry points. The TMI disk is a DOS 3.3 disk; I use disk Copy to copy it to a ProDOS disk, boot to ProDOS, and then use Virtual ][ to copy it out to my Mac. Lovely.
Do I know where in memory this binary even loads, so that I can poke at it in the virtualizer? Nope. But a little poking around memory, and I find it at $1000.
Do I have a disassembler for 6502? Well, no. But several exist. I download a few and find them all lacking.
The 6502, being an 8-bit processor, has at most 256 opcodes. It can't be that hard to write a disassembler. When faced with the same problem for the PIC, I wrote pic-disassemble, a (wait for it) disassembler for (ahem) the PIC. (Bet you didn't see that coming.)
So an hour later, and I've got a perl script that disassembles. Just like all the other disassemblers that I found and didn't like. But from here, I can augment it to do anything I want!
I want it to be able to label memory points. I want it to be able to mark regions of memory as data, so they're not disassembled. But mostly I want it to be able to draw call flow graphs. Like perhaps this one!
(The full-size copy is here, on my web server, if you really want to look at it.)
From the call flow graph - which initially just had nameless labels, no descriptive ones like "MAINLOOP" - I was able to guess where the highlights are. MAINLOOP was my first target. Then I named ROM entry points in the assembly listing, followed by a lot of reset-to-monitor; call subroutine manually; see what happens.
Eventually I got tired of pure exploration and went in for the kill.
What does this program *do*?
0x1000 ORG 0x1000 0x1000 JSR ASKINIT 0x1003 L1003 JSR F8ROM:INIT 0x1006 JSR F8ROM:HOME 0x1009 JSR PRNTMENU 0x100C MAINLOOP LDA #$FF 0x100E STA CURSCR 0x1011 JSR PRNTTIME 0x1014 JSR RUNTILL 0x1017 CMP #$84 0x1019 BNE L1022 0x101B LDA #$2 0x101D STA $5B28 0x1020 BNE MAINLOOPWell, there's the beginning of it. Simple enough. The ASKINIT function asks if you want to initialize the reactor core, and then returns. The F8ROM functions are part of the machine's rom - in this case, clearing the screen and returning the cursor to the top-left. The PRNTMENU function prints out the list of screens in the game. And so on. Boring.
I spent some time looking at code bits that read from the hardware KBD register, and that cleared the KBDSTROBE register (telling the machine that you're ready for the next keypress). Which lead me to this piece of the program:
0x543F GETKEY LDA KBD 0x5442 BMI L5446 0x5444 SEC 0x5445 RTS 0x5446 L5446 BIT KBDSTRB 0x5449 STA $18 0x544B CLC 0x544C RTSRead from the keyboard; if the high bit isn't set, then there's no input, and we'll set the Carry flag and return. If the high bit *is* set, then we'll clear it, store the result in zero-page location 0x18, clear the carry, and return. Clearly this is a utility function to get a keypress and return (via the Carry flag)... Read more »
The problem is multivariate.
This is a disk image that I got online. I have no idea what its provenance is. I don't know if someone had to crack it (there's no crack notice, which was a point of pride back in the day, so I suspect not).
The software is old. Not just 36-years-old-from-today. It's also from 1980, which was early days. The Apple ][+ had just been released; words like "language card" were on the way out. When the Apple //e was released the Apple world took big steps forward again. Everything I know about the internals of Apple ][s comes from 1982 and later. This is, to me, from Apple pre-history.
And then I'm also running this in emulators. No emulator is perfect. I expect glitches.
So when 36-year-old "old" software in an emulator crashes, where do you look for the problem? Well, for 14 years (I'm guessing I downloaded this along with many other titles around 2002), the answer is "nowhere." When you forget that '7' is the keystroke of death and accidentally push it, you stop playing.
What makes now different, then?
I found a copy of Merlin Pro 2.58 - a ProDOS version of the assembler that I used through High School.
This was the first piece of serious software that I bought for myself. It was expensive, IIRC. But it opened so many doors. I spent a lot of high school programming nonsense in my free time - mucking around with the internals of ProDOS, creating new commands; mucking around with the internals of floppy drives, learning what prologs and epilogs were and how bits were encoded on the disk; generally breaking things and learning how they worked. And a lot of the most advanced work I did was powered by Merlin Pro 2.58.
I had occasionally looked for this online before. Merlin 2.4* (2.43, maybe?) has been available as an image for a long time. But this is DOS-only, and my work disks were all ProDOS (unreadable from DOS 3.3).
So when I found Merlin Pro 2.58, I jumped at the chance to go look at the assembly that I wrote back in the late 1980s. And wow, such nostalgia! I remember vividly the printouts of fan-fold continuous feed sprocket dot matrix assembly. Marking them up during math class. Trying out new things in our Apple lab in my high school (they didn't have assemblers; the classes were all in BASIC, but that's another story). Running home to code changes after school, print it back out in the morning, and repeat. I loved those days.
After perusing the code I wrote as a teenager, I looked at some of the other disk images in my archive. I played Ali Baba and the Forty Thieves with my 11-year-old son (who is now addicted to it, mwahahaha). I found Temple of Apshai images online and spent a few minutes remembering how I wanted to love this game but hated its controls. And I found my image of Three Mile Island, in its semi-defunct state.
Curious, I thought I'd troubleshoot it a bit.
Was it perhaps designed for a specific ROM? Virtual ][+, my emulator of choice, comes with ROMs for the ][ and the ][+. A quick test showed that it failed the same way there.
Is this a bad disk image? I downloaded every copy of TMI that I could find - some with different names - just to find that they're all exactly the same disk image. So either this is exactly the original image, or they're all copies of the same single disk.
Which leaves little to do except to poke in the binary itself and see what the heck it's doing.
I grew up in suburban Norristown, PA. My mother, a single parent, raised my brother and me on a shoestring budget; we had little room for niceties. So in 1984, when my grandfather decided to buy me a computer, I was ecstatic. Computers were cool. I had been using the Apple ][+ since 6th grade at school; we had a Commodore PET lab there as well. Some of my friends had Commodore VIC-20s and C-64s. One had a TI-99/4a. Another loaned me her TRS-80 MC-10 for a while. I never thought I'd have a computer of my own, and here it was - an opportunity to buy whatever kind of computer I wanted!
I spent months preparing - deciding what kind of computer I wanted, based on what I wanted to do with it. The TI-99/4a was fun, but an outlier. C-64s were for playing games, and that's not what I wanted. I wanted to be able to fiddle. Like I did with the Apple computers at school. CoCos were very fiddly, but had a feel that I didn't quite like. And so it happened that one day - after a lengthy discussion with him about what I wanted and why - my grandfather drove me down to Bundy Typewriter & Computer in Northeast Philly to buy an Apple.
Now, as I recall it, the school year was coming to a close - which means it was early 1985. I would have just finished 7th grade (for the second time!) and was entering the 8th grade "gifted" classes (the district had dropped me out of the program after I flunked 7th the first time - note, it is not possible to pass 7th grade in 1983-4 if you do absolutely no homework all year, despite your test scores).
I suspect there was some condition attached to the computer - probably related to my getting back on the academic straight-and-narrow. I'd probably aced that year. The district dropped me in to the "average" classes, which were a breeze. I accidentally got myself in to the advanced Algebra class for 8th grade. I stumbled in to helping the Title I Math class with their Apple ][s, which paved the way to helping to teach the computer classes with Commodore PETs. All of this led toward my 8th grade year of gaming the system: I found the things that I liked and was good at (orchestra, Commodore PETs, Algebra, managing the Apple ][s, stage crew) and then things I hated and was bad at (umm... art, which is a sign of a crappy teacher, since I consider myself an actual artist) and balanced my life accordingly (read: found an excuse to skip every art class in 8th grade with a signed teacher's note for one of the aforementioned fun activities).
One of the biggest reasons I wanted the Apple //e (released in early 1983! New! Shiny!) was so that I would have a set of tools to work with. Yes, my friends had all those other computers; but I wanted to be able to work with the same software I'd been using in the Apple ][ lab at school. The games, I suppose. But more: the utilities. Disk editors. Programming languages like Logo and Applesoft BASIC. Program listings out of BYTE magazine. These were what really intrigued me. I wanted to be able to understand how things worked. Change them. Make my own things.
(I'm sure that will have surprised absolutely nobody that knows me today.)
So when we walked in to Bundy and they tried to upsell us to the brand new shinier Macintosh 128 (this is 1984, remember!), I was having none of it. It was clearly infantile in its capabilities. Nascent. Perhaps it had promise, but in that moment, it was the wrong machine. It had no programming languages. It didn't even boot in to Applesoft BASIC. I wouldn't be able to share any of it at school. Or run it in the school labs in the mornings and evenings, then head back home to work on it some more. Nope. No Mac, No How.
We actually went back home to deliberate (certainly not my choice) and went back a few weeks later. Walking in the second time, I knew *exactly* what we were getting. An Apple //e, 128k extended graphics card, color monitor. Which is exactly what we bought, and exactly what I used pretty much nonstop for the next 5 years. (Including - to much of my...Read more »