Skip to content

settings: share /VMS checks between launch and the Installed Extension page - #68

Merged
SensoriumEmbedded merged 6 commits into
SensoriumEmbedded:mainfrom
kfox:ext-pkg-review-fixes
Oct 26, 2026
Merged

SensoriumEmbedded merged 6 commits into
SensoriumEmbedded:mainfrom
kfox:ext-pkg-review-fixes

Conversation

@kfox

@kfox kfox commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Follow-up to the Installed Extension package list (ced99da), from its review.

Background. On a TR+, an installed extension (for example an emulator) opens file types like .nes or .a26. Each file type is registered by a small folder in /VMS on the SD card. Two parts of the firmware read those folders:

  • the Installed Extension page on the C64 (F8, then 0), which lists the folders and marks the ones with a problem; and
  • the launch, which runs when you pick one of those files in the menu: it finds the folder that claims that file type, checks it, and starts the extension.

The page is meant to show what a launch would do. Before this PR each one had its own copy of the folder scan and the checks, so they could disagree: the page could list a folder as fine and the launch then refuse it.

What changes

  • The page and the launch now use the same folder scan and the same checks (in VMRegistry.h), so what the page marks is what the launch does.
  • The check for whether an SD card is inserted is one function, SDSlotFilled(), used by both the page and CheckLaunchSDAuto.
  • The page starts the card through SDBegin(), so an SD read left open is ended before the card restarts, as it is in SDFullInit and MenuChange.
  • The /VMS scan and SDSlotFilled() stay out of ITCM. The scan takes a FLASHMEM visitor function rather than being a template, because FLASHMEM on a template does not reach every instance.
  • With many folders, the page keeps room on screen for the rows that explain failures and the last launch. It shortens the folder list with a +N more row, and shows a +N more notes row if the explanations don't fit.
  • The page checks file sizes and headers only. It skips the full checksum of each module, because every redraw would read every byte of every module from the card. The launch still does the full check, so a damaged file the page lists as fine is still refused at launch. A test covers that case.
  • General_Usage.md and TR_Host_Extensions.md now say what the ! mark covers.

Verified: node tools/verify-extensions.mjs passes, including new cases for a bad-checksum module and for many folders. Both targets build. On the TR+, ITCM code in the main image is 320 B smaller than on main (198,632 to 198,312 B) and RAM1 variables are unchanged. The card-detect pin behavior was not tried on a board.

kfox added 3 commits October 20, 2026 16:29
…xtension page

The page copied find(), refresh() and preflight() and had drifted: it skipped
the module-payload and client-bank CRC passes, so a package with a bad CRC
showed launchable and then failed at launch.

VmRegistry now owns the folder rule, the bounded /VMS walk and verify(), and
find(), refresh(), preflight() and the page all call them. SDSlotFilled moves
to Teensy.ino beside its other caller; SD.begin already muxes DAT3 back, so
the pin needs no restore of its own.

The page keeps rows for the reasons and the last launch when many packages
are listed, and counts any it still has to cut. The docs say what '!' covers.
The page redrew with a full read of every package's module and client banks.
It now checks sizes and headers only; launch still verifies every CRC.
@kfox
kfox marked this pull request as ready for review October 21, 2026 19:49

@SensoriumEmbedded SensoriumEmbedded left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for putting the page and the launch on one /VMS scan.

Memory: on the TR+, RAM1 variables are unchanged and ITCM code grows 80 B net; the TR is unchanged. Both of these are worth doing before merging:

  • The walk<> template's FLASHMEM doesn't hold for every instance. walk<> is declared FLASHMEM, but the instance refresh() uses (388 B) still lands in ITCM, along with veneers for readManifest and vm_path_component. A plain FLASHMEM function in place of that lambda avoids it.
  • SDSlotFilled lost its FLASHMEM in the move to Teensy.ino, and its callers aren't timing-critical.

With those, it's ready.

Hardware testing still to do: for one of us to possibly get to before release

The PR says the firmware wasn't compiled. CI built both targets at this head, and so did I.

  • the Installed Extension page:
    • with more than 8 packages (the +N more rows)
    • with a bad-checksum module, which should be listed, then refused at launch
    • with the card pulled and reinserted
  • power-up autolaunch with and without a card, now that CheckLaunchSDAuto goes through SDSlotFilled()

Thanks again.

@kfox
kfox marked this pull request as draft October 26, 2026 14:52
kfox added 3 commits October 26, 2026 09:56
walk<> was a FLASHMEM template, but the instance refresh() uses landed in
ITCM (388 B), with veneers for readManifest and vm_path_component. walk now
takes a FLASHMEM visitor function and a context pointer. SDSlotFilled gets
back the FLASHMEM it had before it moved to Teensy.ino.
Each draw that finds no begun card restarts it, and the menu's last read can
still be open then, so it ends that read first as SDFullInit and MenuChange do.
@kfox

kfox commented Oct 26, 2026

Copy link
Copy Markdown
Contributor Author

Thank you for the review and the measurements!

I merged current main (5f16876) into this PR. Main now has SDBegin() beside the moved SDSlotFilled().

  • walk<>'s FLASHMEM: walk is now a plain FLASHMEM function that takes a visitor function and a context pointer. The three callers (find, refresh and the package list) each pass a named FLASHMEM visitor. With this, no walk instance is left in ITCM. One 8 B veneer remains, because LoadDirectory and RemoteLaunch call it from ITCM.
  • SDSlotFilled is FLASHMEM again.
  • The page also starts the card through SDBegin() instead of SD.begin, so it ends any read left open first, as SDFullInit and MenuChange do since 9d29a00.

Memory, TR+ main image: ITCM code is 198,632 B on main, 198,696 B at the merge before these fixes, and 198,312 B now, 320 B under main. RAM1 variables are unchanged (214,212 B). The TR builds too.

@kfox
kfox marked this pull request as ready for review October 26, 2026 15:33
@SensoriumEmbedded
SensoriumEmbedded merged commit 648bd53 into SensoriumEmbedded:main Oct 26, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants