BMOW title
Floppy Emu banner

Three Crazy Ideas

While I’m optimistic that the floppy write emulation technique described yesterday will work (at least for high speed cards), it would be great if I could buy an extra safety margin of time, or find a way of throttling the incoming data from the Macintosh during a write if it’s too fast. The biggest challenge is emulating the initialization of a floppy, where sectors to be written arrive from the Mac rapid fire, without stopping. Here are three slightly crazy ideas that just might work to handle the firehose of incoming data.

Floppy Driver Patch

One possibility is to write a custom INIT or extension that patches the floppy driver code in ROM, and extends the track step timeout from 12 ms to something much longer.  This would be a simple change of just a few bytes, and it would enable the emulator to pause the incoming data after each track step, while it saved the previous track’s data to the SD card. Because there’s no problem with the speed of floppy read emulation, the INIT itself could still be loaded from the emulated floppy.

The major drawback of this approach is that it would force you to boot from a special Floppy Emu setup disk in order to load the INIT. I also don’t know anything about writing INITs and extensions, and I’m not sure if many different versions would be needed. Can the same INIT work with System 1.0 and System 9?

Faking An Error

In yesterday’s post, I said there’s no error mechanism that can be exploited to slow down the incoming data without causing the write operation to fail. I took another look at it today, and I think I may have found a way, by exploiting some code that measures the size of the gap between the last sector and the first sector on one side of a track. During initialization of a floppy, after the Mac finishes writing the last sector on a side, it immediately switches back to read mode to measure the gap before the next sector, and confirm that the next sector is sector 0.

The disk initialization code uses some kind of progress counter that starts with a value of 7. Every successful side written increments a counter by 1. If the gap is the wrong size, the counter is decremented by 1. If the counter value is greater than 4, it attempts to rewrite the side again, otherwise it aborts with an error.

By intentionally generating a bad gap size after a full side is written, I can force the side to be rewritten. If I also make the emulator smart enough to detect when data written to a sector is identical to what was already there, then it can ignore the second rewrite. That effectively doubles the amount of time available for saving the track data to the SD card, since every side will be written twice by the Mac.

The bad gap size trick can only be done once per side, or else the progress counter will decrease and the initialization process will eventually fail, so it can’t buy an indefinite amount of additional time. It’s also a little risky, because it means the progress counter will never increase above 7, and any 3 other errors occuring during the initialization will cause it to fail.

I did some simple tests of this idea that look promising. By disabling SD saves, I was able to perform floppy initialization to measure its write speed, even though the initialization ultimately failed during the verify phase. In my initial test, it took 34 seconds to complete the write phase of initialization. After I added emulator code to generate a bad gap after every other side write operation, the time increased to 59 seconds, with no obvious ill effects.

Zero Flag

During floppy initialization, the Mac writes 1600 sectors very fast. What’s in those sectors? Zeroes. Instead of buffering a 512 byte sector full of zeroes, I could just set a flag that says “this sector is all zeroes”. Using a bitfield, I could buffer an entire disk’s worth of zero sectors using just 200 bytes of RAM. Those sectors could then be saved to the SD card whenever it was convenient, after the floppy initialization was finished. If a read request arrived before all those zero sectors were saved to the card, the emulator could check the flag first to see if an all-zero sector should be synthesized instead of actually loading the sector data from the SD card.

I like this idea because it’s short and simple, though its usefulness is limited to floppy initialization only.

Read 5 comments and join the conversation 

5 Comments so far

  1. Jeff - December 12th, 2011 7:04 am

    Your last idea is very good ! 😉

  2. Bartosz - December 13th, 2011 12:53 am

    I think: it is time to back to the roots.
    Emulator does not work perfectly with real Mac. That is a pity.
    But… the primary goal is to work with emulator. You need to feed the emulator with ROMs. So why not to patch ROMs to have longer step/write/retry times ? It could be done directly to the supplied ROM or the emulator could patch the original code on the fly when the needed values are fetched from memory if you do not want to touch the ROM. It is easy to be done with address decoder which spies on ROM access and feeds needed/correct values from RAM. Patches to the ROM could be even read from the SD card during initialization of emulator so the process seems to be flexible enough for different models of emulated Macs or different versions of ROM. The patch could be read once and stored in flash till newer hardware or different ROMs will be used.
    My second thought is if writing track/sector number to the display could be the problem of stealing to much time during SD operation ?

  3. Matt - December 13th, 2011 7:55 am

    Personally, I’d go to heroic lengths to make it work with unpatched ROMs. There’s just something cool about being able to use the original ROMs as-is.

    And yes, I understand that this is a lot easier to say than to do.

  4. Michail - December 13th, 2011 9:50 pm

    Well, at this point I would already switch to another solution:

    1) Use some kind of “cartridges” instead, made using FRAM memory. That would be fast enough & high-tec 🙂

    2) Using NOR-flash chips, instead of SD-cards. They are also much faster at writing/erasing small stuff.

  5. @ndy - December 19th, 2011 3:11 pm

    Perhaps you should invert every bit as
    (IIRC) after SD sectors are erased they are full of 1s. Is it quicker to write blocks of 1s than 0s with your SD card code?

    Inverting every bit and padding the on-SD-card sector allocation to the erase-block size might buy you some performance advantages, especially during initialization.
    If you always preerase an entire disk’s worth of blocks when the SDCard is inserted you might suddenly find that initialization becomes very cheap.

    Regards,
    @ndy

Leave a reply. For customer support issues, please use the Customer Support link instead of writing comments.