Skip to content

GeoRAM and REU saves hold the computer while they write - #77

Merged
SensoriumEmbedded merged 5 commits into
SensoriumEmbedded:mainfrom
kfox:ram-save-consistent
Oct 30, 2026
Merged

SensoriumEmbedded merged 5 commits into
SensoriumEmbedded:mainfrom
kfox:ram-save-consistent

Conversation

@kfox

@kfox kfox commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

A GeoRAM or REU save from the Alt button now holds the computer while it writes, so the saved file is the RAM at one instant.

Before, the save wrote up to 512K to SD while the computer kept writing the same banks through the IO handlers. A save could mix before and after, such as a GEOS RAM disk whose directory and BAM disagree. WriteRAMBanksFile in RAMBanks.c, shared by both saves, now stops the computer with the safe asynchronous freeze the Pause button uses (HoldC64 in DMAControl.c), writes the file and releases it.

  • If the computer can't be stopped, nothing is saved and the last save is kept.
  • A computer the host has already paused stays paused after the save.
  • The plain TR has no Alt button and no DMA, so its build gets stubs and saves nothing, as before.

Verified

  • node --test Source/Teensy/tests/ram-banks.test.js: 5 tests on a host harness whose fake computer writes every bank between file writes unless it is held. The two save tests fail on main (the file comes out torn). Removing the release, forcing the hold to succeed, or removing the paused-computer check each turns tests red.

  • Memory, from CI's builds of this head and of main: RAM1 and RAM2 are unchanged in every image on both boards (main image free-for-locals 79,900 on the TR+ and 122,780 on the TR). Flash grows 144 B of code and 32 B of data in the TR+ main image, 32 B and 32 B in the TR's, and 16 B of code in the extension image.

  • Hardware, a TR+ in an NTSC C128, saving with the Alt button while GEOS ran. Each save printed Saved 512KBytes, and GEOS kept running afterwards:

    • GEOS 64 in C64 mode. A relaunch preloaded the saved file and reached the DeskTop.
    • GEOS 128 in 40 columns at 1 MHz.
    • GEOS 128 in 80 columns at 2 MHz. The pointer still moved and the clock still advanced.

    The GEOS 128 runs used this branch merged with GEOS 128 launches from the TR on a C128 with the USB mouse, no disk drive #76's launcher.

Reviewed at medium, and the review's fix commit at low; then at high over the whole PR, whose one fix moves the new message string to flash, and that fix at low.

kfox added 4 commits October 27, 2026 15:31
… the file is one instant

The Alt-button save wrote up to 512K to SD while the computer kept
writing the same banks through the IO handlers, so a save could mix
before and after, such as a RAM disk whose directory and BAM disagree.
WriteRAMBanksFile, shared by both saves, now stops the computer with the
safe asynchronous freeze the Pause button uses, writes, and releases it.
If the computer cannot be stopped, nothing is saved and the last save is
kept.
@kfox
kfox marked this pull request as ready for review October 29, 2026 18:35

@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.

Thank you for the consistent GeoRAM and REU saves. A RAM disk that comes back exactly as it was saved is a real fix for GEOS users!

I reviewed this merged onto current main (6c24667) and built both targets. As always, feel free to push back on anything that's inappropriate or would take significant memory/code to resolve.

Memory: RAM1 and RAM2 are unchanged in every image on both boards, which matches your numbers. Flash code grows 144 bytes in the TR+ main image and 16 in the extension image.

There are 2 things I'd like you to look at before merging. Both are in the new host test, and both have inline suggestions.

1. The harness doesn't compile on Windows (Source/Teensy/tests/ram_banks_harness.cpp:123)

RAMBanks.c calls strlcpy and strlcat. MinGW-w64 doesn't provide them, and neither does glibc before 2.38. On a Windows checkout the harness fails to build with "'strlcpy' was not declared in this scope", and all five tests fail. npm test passes there on current main, so this would turn it red for anyone testing on Windows. CI stays green because its Ubuntu runner has glibc 2.39.

Suggested fix: give the harness its own copies of the two functions before the include, and point the names at them with #define. The #undefs cover a C library that defines them as fortify macros. See the inline suggestion.

2. The test splits the harness's output on \n only (Source/Teensy/tests/ram-banks.test.js:34)

A MinGW build writes stdout in text mode, so every line ends in \r\n and each compared value keeps a stray \r. Even with item 1 fixed, all five tests still fail on Windows. 320511c fixed the same thing in usb-mouse.test.js.

Suggested fix: split on /\r?\n/, as in the inline suggestion.

With both applied, npm test and npm run verify:extensions pass on Windows and on Ubuntu 24.04 (glibc 2.39, the same as CI).

Hardware testing: Just to document. I'll hit these at some point, not a request or requirement! :)

Your saves under GEOS 64 and under GEOS 128 in 40 and 80 columns cover the basic path.

  • Repeated saves in GEOS 128 at 80 columns. #82 reports that a single DMA peek stopped GEOS 128 in that mode, and the hold here uses the same safe freeze. The freeze picks its cycle from the port's 1 MHz clock while the 8502 runs at 2 MHz, and the C128 only drops to 1 MHz once DMA is asserted (see docs/Architecture/C64-C128-DMA-Port-Reference.md). Your three saves came through, so ten or more in a row, checking the pointer and the clock after each, would settle it.
  • A save in the middle of a copy onto the RAM disk, then a relaunch and a validate. That's the case this PR fixes.
  • REU only: an Alt save while a program is using the REU.
  • A freezer cart with the REU: a long-press save, then a short press still freezes.
  • A save while the app has the C64 paused: it stays paused, and the app's un-pause resumes it.
  • GEOS 64 save and relaunch on a C64, NTSC and PAL.
  • Two saves in a row: the .bak rotation for GeoRAM and the numbering for the REU.

Thank you!

Comment thread Source/Teensy/tests/ram-banks.test.js Resolved
The harness brings its own strlcpy and strlcat, which MinGW-w64 and glibc
before 2.38 lack, and the test splits the harness's output on \r?\n, since
a MinGW build writes CRLF. Both as Travis suggested in review of SensoriumEmbedded#77.
@SensoriumEmbedded
SensoriumEmbedded merged commit 5e9d90a into SensoriumEmbedded:main Oct 30, 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