M5: the UniDisk reads a disk my board wrote
The board writes now. It formatted a blank-ish scratch disk in 46 s, wrote all 1600 blocks of my REF800K test image onto it, and then I put that disk in the working UniDisk on the IIe. ProDOS listed it. ADTPro pulled an image back through the UniDisk and it matched the original byte for byte.
TESTWRITE2.po (ADTPro image of disk 2 via the working UniDisk) vs REF800K: 0 blocks differ []
sha256 bfed064fef52e305 ref bfed064fef52e305

| Step | Result |
|---|---|
| First write, block 100 on disk 1 | status 00, verified on the first write; full re-read differs only in block 100 |
| Whole disk written onto disk 1 | 855 s, 0 soft errors, 0 blocks differ |
| Board format of disk 2 | 46.1 s, all 160 track sides on the first try |
| Whole disk written onto disk 2 | 853 s, 0 blocks differ |
| Disk 2 in the stock UniDisk | catalogs as /REF800K, ADTPro image identical |
The format sounds just like formatting one on the Apple II. Same layout, same order, same stepping rhythm.
How a write catches its sector
3.5" GCR has no index hole, so the only way to know where you are is to read. Core 1 decodes the track live, one flux interval at a time, and when the target sector’s header goes past it starts the write. A second PIO program does the writing. It takes a byte image from DMA and toggles WRTDATA once per 1 bit, 32 PIO cycles per bit cell, with /WRTGATE dropped one cell before the first edge and raised one cell after the last. The program raises the gate itself, so a firmware bug can’t leave it low.
The bytes it writes are the ones the original drive ROM writes: same sync patterns, same gaps, same 4:1 interleave. I used the ROM disassembly as the reference and didn’t copy its code.
What the scope says
| Measure | Measured | ERS spec |
|---|---|---|
| Gate low to first WRTDATA edge | 2.17 us | at least 1.8 us |
| Bit cell | 2.040 to 2.048 us | 2.0425 us |
| Last edge to gate high | 4.02 us | at least 2 us |
| One sector’s data field | 11.70 ms | 716 bytes |
| One track side during format | 165.95 ms | one revolution is 152 ms |
| Header seen to gate low | 3.1 us | the old data mark is about 160 us away |

I got the latency off RD rather than trusting the firmware. I saved the RD trace before the gate dropped, decoded it in Python, and found the header in it: D5 AA 96 9D A7 96 DB DF DE AA. The gate fell 3.1 us after the first flux edge that follows that last AA, which is the earliest the decoder can know the header is done. The original drive takes something like 16 to 30 us there.
A format write is one long gate with no index, and it’s longer than a revolution on purpose. The tail of the track lands on top of the sync bytes at the start, so it doesn’t matter where the head was when it began.

Reads went quiet as soon as I clipped the probes on
Right after the probes went on, every read failed. RD sat at about 0.4 V with no flux on either head and either disk, while status, tach and stepping kept working. A cold reboot didn’t fix it. It was the M3 problem again: CN104 pin 11 read 4.6 V with the motor running, and the ERS minimum is 4.75 V. I swapped the +5V jumper for solid-core wire and turned the supply up to 5.55 V to get 4.94 V at the pin. That’s 0.6 V lost in the bench wiring, so the real fix is still owed.
If your Sony 800K mechanism answers status but RD is flat, meter +5V at the connector with the motor spinning before you look at anything else.
Also worth writing down: CN104 pins 13, 15, 17 and 19 are +12 V, and RD (16) and WRTDATA (18) sit right between them. Ground is 1, 3, 5 and 7. Probes go on with the drive powered off from now on.
Format burned all 10 tries without writing
The first format 0 0 after starting the server came back failed in 0.7 s, and the scope never saw the gate move. Seeking to track 0 from an unknown position recalibrates, finds it’s already on the right track, and returned before the drive said READY. The format loop then saw not-ready on every try. Now the seek waits for READY after a recal too. After a reflash it formatted cold on the first try, and then the whole disk with no retries.
Writing a whole disk is slow
writedisk takes about 14 minutes, one block every half second or so. Each block waits for its header, writes for 12 ms, and then waits a full revolution for the same sector to come back around so it can be verified. The rest looks like the Python tool polling the serial port with 0.2 s reads. The original ROM doesn’t verify writes at all, so that’s a decision for when the Apple is the one asking.
Still open
- Fix the host tool’s serial polling and time
writediskagain. - Keep the per-block verify for SmartPort writes in M7, or drop it like the ROM? Depends on how long the Liron card waits for ACK.
- Rework the +5V and ground runs to CN104 so the supply can go back to 5.0 V.
- Drive B hasn’t written anything yet.
- M6: SmartPort on the RP2350.