Configurable floppy drive speed with turbo mode#229
Merged
Conversation
Users keep asking for FS-UAE-style fast floppy loading. Add [floppy] speed / --floppy-speed with the same value set: 100 (real speed, the default), 200/400/800 percent, and 0 for turbo. The percentage modes multiply the elapsed time the data path sees -- platter rotation, the MFM read shifter, sync detection, DSKBYTR, and DMA pacing all advance at the whole multiple -- so every per-cell decision stays bit-identical to real speed, only compressed in time. Turbo mirrors FS-UAE's instant path through the ordinary bit engine: once a DMA has been armed for two scanlines (the same deferral WinUAE applies, protecting loaders that clear stale INTREQ bits after writing DSKLEN), the platter is spun forward in zero emulated time, first to the next DSKSYNC match and then to the transfer's end. A sync word the track never provides leaves the transfer to normal pacing, and the event-horizon predictors report the scaled deadlines so idle fast-forward stays bounded. Mechanics are never accelerated: motor spin-up, head stepping, and post-seek settle keep real timing, so drive-readiness state machines (Gods, Shadow of the Beast II spin-up arming) behave identically. The speed is host configuration, not machine state -- save states never carry it, and a loaded state keeps the running session's setting. The option is live everywhere: a Floppy Speed item in the runtime menu, a Drive speed row on the launcher's Floppy tab, and in the browser build a set_floppy_speed/floppy_speed WebEmu API with an optional #floppy-speed select and ?fdspeed= link parameter. Verified against the Alien Breed trackloader: 13 disk DMA completions in the first 15 emulated seconds at 100 percent, 22 at 800, 29 at turbo, all reaching the intro correctly.
Contributor
There was a problem hiding this comment.
Pull request overview
This PR adds a configurable “fast floppy” feature (including a turbo mode) to Copperline, wiring the new [floppy] speed / --floppy-speed setting through the core floppy controller and exposing it across the desktop UI/launcher and the web frontend, with accompanying documentation and tests.
Changes:
- Introduces a floppy speed setting supporting 100/200/400/800% and turbo (0), with timing/prediction support for STOP-state fast-forward.
- Adds desktop controls (menu + launcher) and web controls (JS API + optional page hooks + URL param) for changing floppy speed live.
- Updates configuration/CLI parsing plus docs and example config, and adds unit tests covering key timing/behavior cases.
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/video/window.rs | Plumbs current floppy speed into menu label state and adds a runtime menu action to cycle speeds. |
| src/video/ui.rs | Adds “Floppy Speed” menu item and label formatting; updates menu sizing and tests. |
| src/video/launcher.rs | Adds launcher “Drive speed” control and persists non-default speed into generated TOML. |
| src/main.rs | Adds --floppy-speed / --fdd-speed CLI parsing, help text, and tests for overrides/validation. |
| src/floppy.rs | Implements speed/turbo behavior in the floppy controller, prediction scaling, and extensive unit tests. |
| src/config.rs | Adds [floppy] speed to config model, raw TOML parsing/validation, and override plumbing + tests. |
| src/bus.rs | Preserves host-configured floppy speed across save-state loads via adopt_host_resources. |
| docs/guide/ui.md | Documents the new desktop menu/launcher UI for floppy speed. |
| docs/guide/configuration.md | Documents [floppy] speed and --floppy-speed, including behavior and trade-offs. |
| docs/guide/browser.md | Documents the new WebEmu API + optional #floppy-speed and ?fdspeed= hooks. |
| crates/copperline-web/www/try.js | Implements the optional #floppy-speed select + ?fdspeed= parameter behavior. |
| crates/copperline-web/src/lib.rs | Exposes set_floppy_speed() / floppy_speed() on WebEmu. |
| copperline.example.toml | Adds commented example for [floppy] speed. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Relying on the page shell to add a #floppy-speed element meant the browser build had no visible way to change the drive speed until the site was edited. Follow the status strip's pattern instead: when the shell provides #floppy-speed the page owns placement and styling, and without one try.js builds a labelled select (100%/200%/400%/800%/Turbo) directly below the canvas shell, so the control is always reachable. The select applies live and at boot, and ?fdspeed= still overrides its initial choice for shareable links.
Two review findings on PR 229. Entering turbo through set_speed_percent now arms the same two-scanline grace window and fresh burst attempt as a DSKLEN arming, so flipping the menu to turbo with a transfer in flight defers the burst like a new transfer instead of completing on the next tick, and a spent attempt from an earlier turbo phase cannot linger. And scale_prediction only reports a 1-cck event horizon when the burst can actually run: with the grace elapsed but the drive still spinning up (or settling, or the attempt spent), predictions fall back to the normal-paced deadline, where previously a STOP-parked CPU waiting on a DMA armed during spin-up would have been idle-stepped one cck at a time for the whole quarter-second spin-up.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds the FS-UAE-style fast floppy option that keeps getting requested:
[floppy] speed/--floppy-speed(alias--fdd-speed) accepting100(real speed, default),200/400/800percent, or0for turbo.How it stays accurate
floppy_speedpercentage (their 8.8 fixed-pointtrackspeeddivisor), minus their FIFO slot-pacing hacks, which Copperline's rate-based transfer does not need.next_completion_cck/next_sync_irq_cck/next_index_pulse_cck) reports the scaled deadlines, so STOP-state batching stays bounded to the accelerated events.adopt_host_resourcescarries the running session's setting across save-state loads, and the default (100) leaves every timing path byte-identical to before this change.Hooked up everywhere
[floppy] speed,--floppy-speed/--fdd-speed, validated to the supported set with a clear error.set_floppy_speed(percent)/floppy_speed()onWebEmu, plus a visible speed select on the page itself: a shell-provided#floppy-speedelement hosts it, and without one try.js builds a labelled 100%/200%/400%/800%/Turbo select below the canvas (the status strip pattern), so the control is always reachable.?fdspeed=100..800|0|turbooverrides the initial choice for shareable links; changes apply at boot and live.copperline.example.toml.Testing
cargo test(1665 unit + integration suites),cargo clippy --all-targets, andcargo fmt --checkall clean; web crate checked withcargo check/clippy --target wasm32-unknown-unknownandfmt --check.