Crisis averted… I think…
Feeling pretty happy with my new volume knob, I turned back to running ML on my Apple ][+. Then… I started getting crashes to the system monitor.
No es bueno. These types of system crashes are typically indicative of hardware issues. I struggled with a considerable number of these while reviving the ol’ clunker and am not particularly interested in revisiting that. What could have triggered these new problems?
Did RND(1) break something?
My first thought was a recent test I ran to see how long it would take for RND(1) to return a value of exactly zero. My interest was related to the log(0) vulnerability that I fixed previously. Does RND(1) ever return exactly zero, which would cause log(0) to crash? I don’t know but I ran it 10s of thousands of times and never got one.
Regardless, could the strain from running RND(1) in a tight loop cause something to overheat and perhaps break? It’s possible that this kind of sustained access pushed a chip’s local temperature up a few degrees and exposed a marginal connection or borderline component that’s been sitting right at the edge of failing for years. It might also be worth noting that Applesoft’s RND() is fully deterministic from a cold boot, so the fact the system was crashing at different places ruled out a fixed logic bug or hard stuck bit.
Thinking about debugging this caused me to get a bit depressed but I jumped into running some diagnostics.
Running diagnostics
RAM
I started with the RAM. My first stop was an Apple ][+ monitor memory test that I’ve seen before. After carefully entering the long string of strange characters into the system monitor, it ran and passed clean.
Not convinced, I found an Apple II Dead Test Diagnostic video that described replacing one of the system ROMs which would then run the diagnostic upon booting. You can find “dead test ROMs” on eBay for $40 but if the machine boots there’s an alternate method of downloading the diagnostic and running it off a floppy. Because the machine kept intermittently crashing to the system monitor, it took a few attempts for ADTPro to get the floppy image over to the machine but the result was a clean pass. Yay!
ROM
While testing RAM is as simple as writing values and ensuring that you can read back the same thing, ROMs are a little more difficult. The Apple ][+ has 6 ROMs ($D000, $D800, $E000, $E800, $F000 and $F800) and they all are permanently burned with particular values. Rather than exhaustively check them all, I eyeballed each of them and then confirmed that the first several bytes of $D000 matched its known values. I could have done a checksum but rather than spend a lot of time here, I felt relatively satisfied and decided to move on. I could always come back to this later.
CPU
Testing the CPU is even trickier because finding intermittent errors would require all kinds of stress testing. There’s a GitHub repo with a 6502 functional test but there isn’t an obvious way to download and run it, so I decided to just re-seat the chip. It’s a small thing and was easy to do. I removed the Synertek SY6502 with date code 8119 (week 19 of 1981), wiped the pins and sockets with DeoxIT for good measure, and then carefully put it back.
None of this resolved the issue so I decided to start eliminating things.
Process of elimination
Since starting this little adventure, I have added two cards to the bus: my memory expansion (aka language) card from high school and an 80-column card that I purchased off eBay. Since ADTPro enabled writing code on my laptop with Visual Studio, the 80-column functionality is not something that I’m ever going to use. So I removed it first.
To my surprise and delight, after closing the machine back up, the problem seems to have gone away. How could this be? According to Claude, “Every card on the bus shares the same power rails and the same address/data lines; a card with a going-bad decoupling cap or a weakening bus driver can sag or inject noise onto those shared lines, and that tends to show up specifically under sustained heavy bus activity — which is exactly the pattern you’ve been chasing.” While RND(1) never touches the 80-column card, it’s possible the sustained, heavy-duty load might have revealed a marginal component on the shared bus. So the unused 80-column card is out and, happily, my K-mean program is back to running without any issues.
Crisis averted. Now, hopefully, I can get back to coding…
![Split code running on Apple ][+ hardware](/assets/images/apple2/crash-one.jpg)
![More split code running on Apple ][+ hardware](/assets/images/apple2/crash-two.jpg)





Leave a Comment