Classic Mac Floppy Emulator Boot-Up
Exciting news on the Classic Macintosh Floppy Disk Emulator: I successfully transferred two sectors from a virtual 800K floppy disk, and used it to boot a Mac Plus to the “Happy Mac” screen. This proves that all the trickiest parts are working: the drive RPM speed feedback signal, emulation of drive registers, GCR data encoding, correct sector headers / footers / checksums, and modulation of the read sense line to mimic magnetic disk media. Woohoo!
There’s not enough memory to hold a full disk image, so the Mac won’t boot all the way to the Finder yet. More work is needed to load a track’s worth of data at a time and buffer it in RAM, using the Mac’s drive step command to trigger loading of a new track. And of course there’s still the whole question of floppy disk writes in addition to reads… but now that the initial hurdle of basic data transfer has been cleared, I feel much more optimistic about the remaining work.
As described in my previous post, a CPLD implements all the timing-sensitive functions, and generates the signals that are sent to the Mac. It creates an RPM feedback square wave whose frequency varies according to the current track of the emulated floppy drive, in order to mimic the variable-speed behavior of the Mac 800K drive mechanism. It also ensures bits are sent at exactly 2 microsecond intervals, using the transition encoding method of a real drive. This method indicates a logical 1 as a high-to-low transition during a 2 microsecond bit window, and a logical 0 as no high-to-low transition during the window.
To the CPLD setup, I added an ATmega168 AVR microcontroller with 16KB of program Flash memory and 1KB of RAM. The AVR stores two sectors worth of pre-encoded GCR data in Flash memory, and passes it to the CPLD one byte at a time, using ready/ack control signaling. If the AVR doesn’t signal its readiness when the CPLD needs a new byte, then the CPLD will automatically insert a sync byte. This makes it possible to emulate the empty space between sectors on a floppy disk without actually storing or transferring the sync bytes that appear in the inter-sector space. The eventual plan is for the AVR to also load disk image data on-the-fly from an SD card, or possibly over a USB link from a PC, perform GCR encoding on the fly, and also perform GCR decoding to support disk writes as well as reads.
Luckily my first attempt at transferring data wasn’t far off the mark, because the emulator’s Mac interface is nearly impossible to debug. Ideally I could step through the floppy driver routines in the Mac’s ROM while floppy data was being loaded, and see what’s happening at a low level and troubleshoot problems. This is sort of possible, by installing the MacsBug debugger on the Mac, and setting breakpoints inside the ROM driver routines. Unfortunately the Mac’s 68000 CPU lacks hardware breakpoints, so breakpoints in ROM code must be implemented by setting a processor flag to invoke an interrupt handler after every instruction. (RAM breakpoints are implemented by dynamically patching the code.) This makes the Mac run 100-1000 times slower than normal when a breakpoint is set in ROM, rendering it virtually unusable. But even if you have the patience to wait 10 minutes for a breakpoint, I found that my ROM breakpoints didn’t always get hit, though I couldn’t explain why.
After setting up the AVR data transfer and discovering that it didn’t work, I scratched my head for a while, trying to find tools to help determine what was wrong. The first problem I found was that the disk RPM speed feedback I thought was working correctly earlier actually wasn’t. I was able to use MacsBug to see that the floppy driver was returning error -79 “can’t correctly adjust disk speed”, but I had to blindly experiment with different speed values until I hit on one that worked. Then the floppy driver was returning error -67 “can’t find an address mark”, which basically means it can’t make any sense of the data to determine where a sector begins. With zero other info to help troubleshoot, I methodically went through all my design assumptions one-by-one again looking for mistakes, and found a place in the IWM specification where I misinterpreted what Woz meant by a “transition” on the read sense line. At fist I thought a “falling transition in a bit window” meant any transition that falls in the window, but it turns out it literally meant a falling high-to-low transition. After fixing that, holy cow, it worked! I had fully expected needing to dig through half a dozen more problems after that one, so I was literally jumping around and shouting in excitement.
Read 7 comments and join the conversation7 Comments so far
Leave a reply. For customer support issues, please use the Customer Support link instead of writing comments.
This means you’re “an inch” away from having a complete emulated Mac Classic in hardware, doesn’t it? Anyway, congratulations on the major progress you’re making!
Looking forward to how this project progresses! Keep up the good work!!
@JaWi – It’s a good step, yes, but there’s still lots more to do! Actually the floppy emulator is not really part of the Mac replica (Plus Too) project, although there’s definitely lots of overlap. The floppy emulator must work with a real Mac’s floppy controller chip, with a serial interface and magnetic read head encoding method. But Plus Too can replace the the floppy controller and the floppy drive with a single new component, which can use a byte-wide interface and ignore all the magnetic encoding stuff.
I have too many projects going at once!
Awesome!! I’m also visiting often to see progress on the “Plus Too”. I would even donate some $$$ if anything was needed. Keep up the exciting work.
@Steve: ah, ok. I thought this project was a small side-step from the Plus Too to get the floppy drive emulation part developed. Anyway, it is a really interesting real on interfacing with “ancient” hardware… 🙂
I’ve been doing some rough figuring regarding streaming disk data from an SD card. It appears that sdfatlib with a 16MHz AVR may be fast enough to load each *sector* on demand, instead of loading whole tracks at a time. This would reduce the amount of RAM needed dramatically– 1KB of RAM would be enough. That means a lot more types of microcontrollers could be considered, instead of the relatively few that have 8KB or 16KB or RAM.
Back of the envelope: sdfatlib is reportedly capable of read speeds of 300KB to 1100KB/sec. That means a 512 byte sector could be read in about 1ms. At about 600 RPM, the disk takes 100 ms to make a single rotation through one track containing (on average) 10 sectors. Inserting an extra 1ms delay for each sector would therefore only increase the total time to 110ms, only 10% slower than “real speed”. And in practice there is empty space between each sector, and data loaded during this dead time would not make it any slower than a real floppy disk.
[…] I’ve been tinkering with this project for a while now, and wrote about it here several times before. Today I finally got read-only floppy emulation working from an SD card, in a rough approximation […]