feat(reu): auto-provision the U64 REU for runs that need it#45
Merged
Conversation
…that need it The REU-staged audio/video paths ([audio].use_reu_pump, explicit [video].use_reu_staged = true) required the user to manually enable the REU in the F2 menu first — and --doctor errored when it was off. Now c64cast provisions it itself: at startup, for a run that hard-requires the REU, it PUTs "RAM Expansion Unit" = Enabled + "REU Size" = 16 MB over the Ultimate REST config API. The change is LIVE (the firmware applies it via effectuate, no reboot) and VOLATILE (never saved to flash, so it reverts on the next power-cycle); teardown restores the original. - api.put_config_item(): PUT /v1/configs/<cat>/<item>?value=<v> (the same route the HW-validated _diaglib.rest_set_config uses). Capability-gated default on the backend ABC. - doctor.provision_reu/restore_reu/read_reu_config: the policy + REST reads. Provisioning is gated on auto_reu, profile.supports_reu, a probe being allowed, and the _wants_reu hard-requirement (use_reu_pump or explicit use_reu_staged = true). The "auto" default is left alone — it self-heals to host-DMA double-buffer (also tear-free) without touching machine config. Always sizes to 16 MB (covers the audio ring near 1 MB and the video staging region near 14 MB; FPGA-backed, so free). - [ultimate64].auto_reu (default true) controls it; false = manage the REU yourself. - --doctor downgrades the REU-disabled diagnostic from error to ok when auto_reu will enable it; still errors when auto_reu = false. - cli.build_stack runs the provisioner before _resolve_reu_available (so that probe sees the now-enabled REU); teardown_stack restores it. - 16 MB covers every c64cast REU offset, which the docs never spelled out (the video staging region tops out near 14 MB — a 2 MB default REU would have silently wrapped). Also corrects the _diaglib.rest_set_config docstring: the single-item PUT is live + volatile, NOT a flash write (verified in route_configs.cc + config.h at_close_config, which calls effectuate only).
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #45 +/- ##
==========================================
+ Coverage 79.69% 79.76% +0.06%
==========================================
Files 68 68
Lines 12947 13020 +73
Branches 1911 1924 +13
==========================================
+ Hits 10318 10385 +67
- Misses 2190 2195 +5
- Partials 439 440 +1 ☔ View full report in Codecov by Harness. |
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.
What
The REU-staged audio/video paths required the user to manually enable the REU in the U64's F2 menu first, and
--doctorerrored when it was off. This makes c64cast provision the REU itself.When a run hard-requires the REU —
[audio].use_reu_pump, or an explicit[video].use_reu_staged = true(the same_wants_reucondition--doctorchecks) —cli.build_stacknow PUTsRAM Expansion Unit = Enabled+REU Size = 16 MBover the Ultimate REST config API at startup. The change is:at_close_config()callseffectuate()only.teardown_stackalso restores the captured original explicitly.The default
use_reu_staged = "auto"is deliberately left alone — it self-heals to the host-DMA double-buffer path (also tear-free), so no machine config is mutated for it.Why 16 MB
It covers every c64cast REU offset — the audio ring near 1 MB and the video staging region near 14 MB (
modes.REU_VIDEO_BITMAP_COLOR_BASE). This was an unstated requirement: a 2 MB default REU would have silently wrapped the video-staging writes. 16 MB is the max and is FPGA-backed, so it's free.Changes
api.put_config_item()—PUT /v1/configs/<cat>/<item>?value=<v>(the same route the existing_diaglib.rest_set_configshim uses). Capability-gated default on the backend ABC (Ultimate-only; gated onprofile.supports_reu).doctor.provision_reu/restore_reu/read_reu_config— the policy + REST reads. Gated onauto_reu,supports_reu, a probe being allowed (never writes config it can't first read back), and the hard-requirement check.[ultimate64].auto_reu(defaulttrue) — setfalseto manage the REU yourself.--doctordowngrades the REU-disabled diagnostic from error → ok whenauto_reuwill enable it; still errors whenauto_reu = false._diaglib.rest_set_configdocstring: the single-item PUT is live + volatile, not a flash write (it previously claimed "Persists to flash").c64cast.schema.json.Verification
load_from_flashreverts it (confirming volatility);provision_reuenables + sizes to 16 MB;restore_reuputs the originals back; machine restored + reset. All checks PASS.put_config_itemroute shape (tests/test_doctor.py,tests/test_api.py); existing doctor REU-error test split intoauto_reuon/off cases.make checkgreen: ruff, mypy --strict, pyright (0 errors), 1606 tests.