I initially thought (and didn't test) that an error from
fluxwrite could be signaled in place of the initial ACK
but in the protocol this ACK has to be written before the
flux is sent from the PC. So, save the result and use it down
in GETFLUXSTATUS instead.
The Apple Disk ][ produces a flux transition whenever the
WRDATA signal has a transition, rather than on only one edge.
This needs different low-level writing code than a PC drive.
We can implement it later for samd51 or bitbang if needed.
To ensure it's OK to activate winding 0, it's necessary
to go to a quartertrack that is a multiple of 8, not just 4.
The previous version of code could lead to loss of position when
the write-protect sense was read while the full track was
an odd number: 1, 3, ...
.. this helps get the state machine fifo good and packed,
avoiding a glitch during the first byte of the track.
Also superstitiously disable the PIO instance, even though it
should have been disabled already.
It's possible for `capture_track` to return early, in the
case that the buffer is small relative to the track time
(or something else is going wrong, like no index pulse).
However, in this case the flux sending loop would never exit,
but would index beyond the end of the flux_transitions array
and probably HardFault eventually.
Instead, use (-1) as the sentinel value for 'no index pulse arrived'
and break out of the loop.
ripping with genuine GW hardware, a typical track is read in
to gw as
```
Flux: 72.00 MHz
Total: 232202 samples, 594.17ms
Revolution 0: 93.06ms
Revolution 1: 166.87ms
Revolution 2: 166.87ms
Revolution 3: 166.87ms
```
our firmware came in as
```
Flux: 24.00 MHz
Total: 120485 samples, 652.35ms
Revolution 0: 0.00ms
Revolution 1: 162.34ms
Revolution 2: 55.11ms
Revolution 3: 162.17ms
Revolution 4: 55.28ms
Revolution 5: 162.12ms
```
Notice how there's an empty revolution 0 and a partial revolution
2 & 4.
It appears that
* if capture_ms is 0, nothing is captured after the index
(rather than 50ms)
* no index is emitted at the start (though this is because
the first revolution is almost always a partial revolution)
Now after this change, a track on rp2040 looks like
```
Flux: 24.00 MHz
Total: 96498 samples, 502.46ms
Revolution 0: 0.00ms
Revolution 1: 167.49ms
Revolution 2: 167.49ms
Revolution 3: 167.49ms
```
which appears to be closer to what gw expects; it also fixes how
g64conv used to require `r1` to select a particular revolution.
This may have been because it defaulted to one of the 'runt'
revolutions, which also made it misestimate the rotational speed
of the drive.
.. after awhile it would run out of program space, because
it was not freeing the right program.
also add support for terminating a read after a given number
of ms, or 50ms after the second index pulse.
This nearly works with fluxengine (slightly older revision):
```
$ ./fluxengine write ibm1440 -i bloop.img --usb.serial=...
Measuring rotational speed... 200ms
Writing to: drive 0
0.0: Write: 199 ms in 76988 bytes
Verify: 391 ms in 150010 bytes
0.1: Write: 199 ms in 92225 bytes
Verify: 326 ms in 150006 bytes
1.0: Write: 199 ms in 79272 bytes
Verify: 380 ms in 150002 bytes
```
but at some point, the fw and fluxengine stop successfully
talking:
```
Measuring rotational speed... 200ms
Writing to: drive 0
0.0: Write: 199 ms in 76988 bytes
Verify: 391 ms in 150010 bytes
0.1: Write: 199 ms in 92225 bytes
Verify: 326 ms in 150006 bytes
1.0: Write: 199 ms in 79272 bytes
Verify: 380 ms in 150002 bytes
```