Skip to content

rtc: persist RP5C01 battery RAM (battmem) in WinUAE-compatible nvram files#265

Merged
LinuxJedi merged 2 commits into
mainfrom
feat/rp5c01-battmem
Jul 23, 2026
Merged

rtc: persist RP5C01 battery RAM (battmem) in WinUAE-compatible nvram files#265
LinuxJedi merged 2 commits into
mainfrom
feat/rp5c01-battmem

Conversation

@LinuxJedi

Copy link
Copy Markdown
Collaborator

Summary

The RP5C01's battery-backed registers -- the 26 RAM nibbles behind AmigaOS battmem.resource, the alarm digits, and the 12/24 select -- now persist across runs to a backing file, the way the real A3000/A4000 board's battery keeps them. This is where scsi.device stores its per-unit SCSI host settings, so an A3000's or A4091's remembered CD drives and transfer/disconnect options survive a power cycle instead of reverting every run.

  • [machine] battmem = "path", defaulting to battmem.nvram in the working directory whenever an RP5C01 is fitted; battmem = "" keeps the battery registers session-only; naming a file on a machine with no RP5C01 is a loud config error.
  • The file layout is bit-compatible with WinUAE/Amiberry .nvram files (verified against Amiberry's cia.cpp and a real Amiberry A4000 file), so backing files interchange between emulators: three 16-byte blocks of one register per byte -- the time digits plus MODE/TEST/RESET as of the save, the alarm bank, and the 13 combined battery RAM bytes.
  • Only the battery payload loads back. The stored time digits never override the read-only (host- or rtc_time-driven) clock, and the stored MODE never overrides the power-on value: files park MODE at $9, and restoring that would break the power-on probe tell (MODE reads $8) AROS/battclock.resource identify the part by.
  • Flush boundary: a MODE write while battery state is dirty. Every battery-RAM access sequence brackets its nibble writes in a bank-select write and a bank restore (battmem.resource and Linux's nvram driver both do), so the restore is the transaction end -- the same shape as the Akiko NVRAM flushing on I2C STOP. Dirty is armed only by writes that actually change battery state, so clock reads locking/unlocking MODE never rewrite the file.
  • The backing-file binding is serialized like Akiko's NVRAM binding, so a resumed save state keeps persisting to the same file: STATE_VERSION 38 -> 39.
  • Docs: configuration.md battmem paragraph, copperline.example.toml; *.nvram gitignored as a local run artifact.

Testing

  • 6 new unit tests: flush produces the exact WinUAE layout (time digits from the seeded clock, MODE, alarm block, combined RAM bytes); loading an Amiberry file takes RAM + masked alarm digits but not clock or MODE; no file write without a real battery change; wrong-shape files (WinUAE's 16-byte MSM6242 flavour) rejected; config default/override/empty/error paths.
  • Full suite: 1760 unit tests pass, cargo clippy and cargo fmt --check clean.
  • End-to-end: recreated a real Amiberry A4000-040-MMU.nvram byte-for-byte, booted the A4000 profile headlessly with it -- it preloads (rtc: battery RAM (battmem) persisted to ...) and a boot that writes no battery state leaves the file byte-identical.

The RP5C01's battery-backed registers (the 26 RAM nibbles behind
battmem.resource, the alarm digits, and the 12/24 select) now persist
across runs to a backing file ([machine] battmem, defaulting to
battmem.nvram whenever an RP5C01 is fitted, "" for session-only), the
way the real board's battery keeps them. This is where scsi.device
stores its per-unit SCSI host settings, so an A3000's or A4091's
remembered CD drives and transfer options survive a power cycle.

The file is bit-compatible with the WinUAE/Amiberry .nvram layout
(three 16-byte blocks: time digits + MODE/TEST/RESET as of the save,
the alarm bank, the 13 combined RAM bytes), so backing files
interchange between emulators. Only the battery payload loads back:
the stored time never overrides the read-only (host- or
rtc_time-driven) clock, and the stored MODE never overrides the
power-on value ($8) every battclock probe matches on to identify the
part.

Changed battery state flushes when the guest writes MODE: every RAM
access sequence brackets its nibble writes in a bank-select write and
a bank restore (battmem.resource and Linux's nvram driver both do), so
the restore is the transaction boundary -- the same shape as the Akiko
NVRAM flushing on I2C STOP. Clock reads lock and unlock MODE too, so
only writes that actually change battery state arm a flush.

The backing-file binding rides in the save state like Akiko's, so a
resumed run keeps persisting to the same file: STATE_VERSION 38 -> 39.
Copilot AI review requested due to automatic review settings July 23, 2026 14:37

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds persistent backing storage for the RP5C01 RTC’s battery-backed registers (“battmem”) via WinUAE/Amiberry-compatible .nvram files, enabling SCSI host settings and other battmem.resource payloads to survive across emulator runs and save-state resumes.

Changes:

  • Implement RP5C01 battmem load/flush to a configurable .nvram file, with unit tests covering layout/compatibility and config behaviors.
  • Add [machine] battmem configuration (defaulting to battmem.nvram when an RP5C01 is fitted) and wire it into machine construction.
  • Bump save-state format version for the new RP5C01 state shape; document and gitignore .nvram artifacts.

Reviewed changes

Copilot reviewed 6 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/savestate.rs Bumps save-state version to account for added RP5C01 battmem binding fields.
src/rtc.rs Implements RP5C01 battmem backing-file support (load/flush) and adds unit tests.
src/emulator.rs Hooks config battmem path into machine build and logs persistence binding.
src/config.rs Adds [machine] battmem parsing, defaulting rules, validation, and tests.
docs/guide/configuration.md Documents the new battmem option and behavior.
copperline.example.toml Adds commented example configuration for battmem.
.gitignore Ignores *.nvram as a local run artifact.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/rtc.rs
Clearing the dirty bit before the write meant a transient host error
(full disk, missing directory, permissions) silently dropped the
battery state: no later MODE write would retry, so nothing persisted
until the guest changed a battery register again. Clear it only after
the write lands; a failure leaves it armed and the next MODE write
retries. Retries stay naturally rate-limited because only MODE writes
while dirty attempt a flush.
@LinuxJedi
LinuxJedi merged commit 241b967 into main Jul 23, 2026
13 checks passed
@LinuxJedi
LinuxJedi deleted the feat/rp5c01-battmem branch July 23, 2026 15:20
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