feat(cartridge): implement RTC calendar transfers and clock updates
This commit is contained in:
parent
692be36349
commit
fce222eea2
22 changed files with 1227 additions and 196 deletions
|
|
@ -1,9 +1,10 @@
|
|||
# Game Pak GPIO and RTC control subset
|
||||
# Game Pak GPIO and RTC calendar subset
|
||||
|
||||
The core supports an explicitly selected cartridge GPIO interface and RTC command/control transactions.
|
||||
The core supports an explicitly selected cartridge GPIO interface and RTC calendar/control transactions.
|
||||
GPIO means general-purpose input/output. RTC means real-time clock.
|
||||
Calendar access, clock advancement, battery persistence, RTC interrupts, and other cartridge sensors remain unimplemented.
|
||||
Unsupported operations return diagnostics. No fabricated date or successful calendar transfer is reported.
|
||||
An explicit caller supplies initial time and elapsed seconds. The core never samples a host clock.
|
||||
Battery persistence, RTC interrupts, and other cartridge sensors remain unimplemented.
|
||||
Unsupported operations and invalid calendar payloads return diagnostics.
|
||||
|
||||
## Selection
|
||||
|
||||
|
|
@ -18,9 +19,10 @@ direnv exec . cargo run --locked --release -- --rom roms/pokemon-emerald.gba --r
|
|||
direnv exec . cargo run --locked --release -- --rom roms/pokemon-emerald.gba --rtc --window --frames 60
|
||||
```
|
||||
|
||||
The report states that only GPIO and command/control are supported.
|
||||
The report states the desktop clock policy: UTC at startup, then host elapsed time, without persistence or RTC interrupts.
|
||||
UTC means Coordinated Universal Time. The host does not convert to local time.
|
||||
The JSON suite schema does not yet select cartridge peripherals. Its default remains no attached peripheral.
|
||||
There is no host-clock dependency, ROM patch, save file, or automatic device detection.
|
||||
There is no core host-clock dependency, ROM patch, save file, or automatic device detection.
|
||||
|
||||
## GPIO registers
|
||||
|
||||
|
|
@ -59,27 +61,80 @@ Chip select rising with clock high begins a command. Chip select falling aborts
|
|||
Command bits enter on rising clock edges after software establishes data while clock is low.
|
||||
The first four command bits on the wire must be `0,1,1,0`.
|
||||
GBATEK's forward and reverse command-byte representations describe this same wire sequence, not interchangeable wire prefixes.
|
||||
Control parameters transfer least-significant bit first.
|
||||
Control and calendar parameters transfer least-significant bit first.
|
||||
During reads, the RTC supplies each bit on the falling edge. GPIO reads do not advance the serial state.
|
||||
|
||||
Using GBATEK's MSB-first command representation:
|
||||
|
||||
- `0x62` writes one control byte; `0x63` reads one control byte.
|
||||
- `0x60` and `0x61` reset supported control state to zero. Calendar reset side effects are not implemented.
|
||||
- `0x64` through `0x67` return an explicit calendar-access diagnostic.
|
||||
- `0x60` and `0x61` reset control to zero and the calendar to year 00, month/day 01, weekday/time zero.
|
||||
- `0x64` writes seven date/time bytes; `0x65` reads them.
|
||||
- `0x66` writes three time bytes; `0x67` reads them.
|
||||
- `0x6c` and `0x6d` return an explicit force-interrupt diagnostic.
|
||||
- Unused commands and invalid command prefixes remain diagnostic.
|
||||
|
||||
Initial control is `0x40`, a deterministic powered 24-hour-mode setting.
|
||||
Bit 6 is writable. Unused bits and read-only bit 7 do not retain writes.
|
||||
Writes enabling bits 1, 3, or 5 fail because their interrupt or uncertain control behavior is not implemented.
|
||||
No power-failure condition is synthesized. There is no calendar value behind this control setting yet.
|
||||
No power-failure condition is synthesized. Core-only attachment initializes the calendar to the documented reset date.
|
||||
Changing hour mode changes its wire representation without changing the stored time.
|
||||
|
||||
A partial control write does not commit. A complete byte commits at its final rising edge.
|
||||
Extra clocks beyond the documented parameter length remain diagnostic rather than guessing repeated transfers.
|
||||
Selecting with clock low, driving data during read clocks, and changing data at a sampling edge also remain diagnostic.
|
||||
Minimum physical setup/hold durations, signal races, and exact analog behavior are not modeled.
|
||||
|
||||
## Calendar registers and transactions
|
||||
|
||||
Date/time payload order is year, month, day, weekday, hour, minute, second.
|
||||
Time-only payloads contain hour, minute, second. Numeric fields use binary-coded decimal (BCD).
|
||||
Each BCD byte stores a decimal tens digit in its upper nibble and a units digit in its lower nibble.
|
||||
The weekday remains an independent counter from zero through six; software can choose its naming convention.
|
||||
|
||||
The supported date range is 2000–2099. Month lengths and leap years follow that range's Gregorian calendar.
|
||||
Hours use `00`–`23` in 24-hour mode and `00`–`11` in 12-hour mode.
|
||||
GBA hour bit 7 indicates PM. In 24-hour reads it reflects hours 12–23; writes ignore it.
|
||||
In 12-hour mode, noon is `0x80`, not `0x12`. Midnight is zero.
|
||||
Documented unused bits are masked. Invalid BCD digits, out-of-range fields, and impossible dates remain diagnostic.
|
||||
The S-3511A datasheet describes invalid-data corrections, including delayed seconds correction. Those behaviors are not implemented.
|
||||
|
||||
A read snapshots the selected registers at command completion.
|
||||
Later caller time updates or reseeding do not change the current serial payload. The next command observes the updated calendar.
|
||||
A write buffers its entire payload and commits only at its final rising edge.
|
||||
Dropping chip select before completion discards that payload. A rejected final edge can be retried without partial calendar changes.
|
||||
Time-only writes preserve the live date and weekday at commit, including a midnight crossed during the transaction.
|
||||
This is a bounded transaction model, not physical verification of chip latching, partial writes, or oscillator phase.
|
||||
|
||||
## Clock ownership
|
||||
|
||||
The core exposes these APIs on `Memory`:
|
||||
|
||||
- `rtc_datetime()` inspects the live calendar, or returns `None` when no RTC is attached.
|
||||
- `set_rtc_datetime(RtcDateTime)` replaces the calendar between machine steps without changing pending read snapshots.
|
||||
- `advance_rtc_seconds(u64)` applies elapsed battery-clock seconds between machine steps.
|
||||
It changes neither CPU cycles nor interrupt state, and it cannot wake HALT or STOP.
|
||||
|
||||
`RtcDateTime::new` validates decimal calendar fields. `from_seconds_since_2000` provides checked epoch conversion with Sunday=0.
|
||||
Calendar advancement is bounded for any `u64` duration, without iterating once per second.
|
||||
The two-digit year wraps from 99 to 00 while weekday continues independently. This is the bounded century-wrap policy.
|
||||
Epoch construction rejects values outside 2000–2099 rather than wrapping a supplied host date.
|
||||
|
||||
CPU execution, `advance_cycles`, HALT, and STOP do not advance RTC time automatically.
|
||||
A caller can advance the battery clock while GBA clocks are stopped. Core tests inject deterministic dates and durations.
|
||||
Reset changes calendar registers but does not reset the caller's elapsed-time source or its fractional phase.
|
||||
Exact oscillator startup, subsecond reset/write phase, century-wrap behavior, and mode-switch timing lack physical validation.
|
||||
|
||||
The desktop adapter samples `SystemTime` once for UTC startup, at whole-second resolution.
|
||||
It then supplies elapsed whole seconds from `Instant`, preserving the fractional remainder in its elapsed-time measurement.
|
||||
Guest time writes and reset therefore remain effective; each update does not replace them with a fresh host date.
|
||||
Later system-clock adjustments do not change the running RTC. Host dates outside the supported range produce an error.
|
||||
|
||||
Terminal runs synchronize between bounded groups of machine steps and at exit.
|
||||
Native windows synchronize between execution slices, including while waiting for input in STOP.
|
||||
Host sleeping can advance the RTC on the next update but never advances CPU/device cycles.
|
||||
This is a coarse host-clock adapter, not cycle-exact pin scheduling or a guarantee about system-suspend behavior.
|
||||
There is no battery save file or offline catch-up. Each new `--rtc` process starts from host UTC.
|
||||
|
||||
## Bus integration and tests
|
||||
|
||||
CPU and DMA accesses retain Game Pak wait-state costs.
|
||||
|
|
@ -89,16 +144,20 @@ A later diagnostic leaves earlier RAM, GPIO, and CPU state unchanged.
|
|||
Data reads and instruction fetches share the selected register overlay. Fetches have no serial side effects.
|
||||
|
||||
Original tests cover selection, masks, directions, retained latches, read enable, widths, ROM preservation, and command framing.
|
||||
They check control reads/writes/reset, aborts, both command-byte representations, edge stability, and unsupported commands.
|
||||
They check control/calendar reads, complete writes, reset, aborts, both command-byte representations, and unsupported commands.
|
||||
Calendar tests cover every day in the supported century, hour modes, PM flags, leap days, midnight, large advances, and invalid payloads.
|
||||
Read snapshots, live-date time writes, independent HALT/STOP advancement, and failed final-edge rollback have separate checks.
|
||||
ARM/Thumb, DMA3, block preflight, staged fetches, retryable errors, and nominal bus costs have separate regressions.
|
||||
File-backed desktop tests check explicit `--rtc` selection, unchanged files, option rejection, and native-window propagation.
|
||||
File-backed desktop tests execute original ARM calendar writes/reads with `--rtc` in terminal and native-window modes.
|
||||
The probe places executable code outside the GPIO overlay. Host-adapter tests inject epoch values and elapsed durations without sleeping.
|
||||
These tests validate the bounded implementation, not physical RTC timing or game playability.
|
||||
|
||||
## References
|
||||
|
||||
- [Seiko S-3511A datasheet](https://www.rockby.com.au/DSheets/10110.pdf), sections 2-1, 3-3, and 4: BCD calendar fields, weekday counter, reset values, PM behavior, and invalid-data corrections. Chip variants and physical transfer timing remain unverified; unsupported corrections are not silently approximated.
|
||||
- [GBATEK cartridge GPIO](https://problemkaputt.de/gbatek-gba-cart-i-o-port-gpio.htm): register addresses, masks, directions, read control, and uncertain byte-store behavior.
|
||||
- [GBATEK GBA RTC](https://problemkaputt.de/gbatek-gba-cart-real-time-clock-rtc.htm): control fields, reset, calendar formats, and command mapping relative to the DS chip.
|
||||
- [GBATEK DS RTC](https://problemkaputt.de/gbatek-ds-real-time-clock-rtc.htm): the linked serial flow, chip-select sequencing, bit edges, and forward/reverse command representations. GBA register differences remain separate.
|
||||
- [mGBA GPIO at 3a5e34be](https://github.com/mgba-emu/mgba/blob/3a5e34be33dc7f8f707e5bc9db69e8a430046f21/src/gba/cart/gpio.c): comparison for retained outputs, direction changes, idle inputs, serial edges, and initial control. Its host-clock lookup, ROM-buffer mutation, and repeated transfers are not copied.
|
||||
- [mGBA GPIO at 3a5e34be](https://github.com/mgba-emu/mgba/blob/3a5e34be33dc7f8f707e5bc9db69e8a430046f21/src/gba/cart/gpio.c): comparison for retained outputs, direction changes, idle inputs, serial edges, and initial control. Its host-clock lookup, ROM-buffer mutation, and repeated transfers are not copied. The calendar implementation uses the documented GBA PM bit, including 24-hour readback; the pinned implementation does not supply that flag.
|
||||
- [mGBA memory at 3a5e34be](https://github.com/mgba-emu/mgba/blob/3a5e34be33dc7f8f707e5bc9db69e8a430046f21/src/gba/memory.c): first-window halfword GPIO write routing. This is not physical proof of all address aliases.
|
||||
- [Explaining GBA RTC](https://bmchtech.github.io/post/rtc/): introductory background surfaced during research; the author explicitly warns that details may be inaccurate. Register and protocol decisions use the references above.
|
||||
|
|
|
|||
|
|
@ -34,8 +34,9 @@ Headerless original programs are accepted.
|
|||
Reads past supplied cartridge bytes remain explicit memory errors, not open-bus values.
|
||||
All three Game Pak ROM windows use the same supplied bytes and existing wait-state rules.
|
||||
Ordinary cartridge bytes remain read-only. Save devices remain unsupported.
|
||||
Optional `--rtc` selection enables the bounded [Game Pak GPIO and RTC control interface](cartridge-gpio.md).
|
||||
It supports configuration and control transactions, not calendar access, clock advancement, or RTC interrupts.
|
||||
Optional `--rtc` selection enables the bounded [Game Pak GPIO and RTC calendar interface](cartridge-gpio.md).
|
||||
It supports date/time reads, complete writes, reset, and explicit elapsed-time updates. RTC interrupts and persistence remain unsupported.
|
||||
The desktop seeds UTC once, then supplies monotonic host elapsed seconds independently of GBA cycles and STOP.
|
||||
|
||||
Both modes call `bios::boot` with the loaded bytes.
|
||||
With `--rtc`, the host then selects the cartridge peripheral before the first machine step.
|
||||
|
|
|
|||
|
|
@ -235,7 +235,9 @@ The current desktop demos do not enter STOP; the frontend does not yet provide a
|
|||
|
||||
Only keypad wake-up is implemented. General-purpose serial and Game Pak wake sources require their missing external devices.
|
||||
Oscillator restart delays, exact entry/wake edges, and hardware-specific IF behavior remain unverified.
|
||||
There is no host-thread sleep or wall-clock accounting. STOP freezes the emulated timer-driven audio clock.
|
||||
Core STOP does not sleep a host thread or account for wall time. It freezes the emulated timer-driven audio clock.
|
||||
The optional [cartridge RTC](cartridge-gpio.md#clock-ownership) uses a separate caller-supplied battery clock that can advance during STOP.
|
||||
Desktop `--rtc` continues supplying elapsed time while its native window waits for input. RTC updates do not wake STOP.
|
||||
|
||||
The graphics demo now uses the optional original BIOS replacement's VBlankIntrWait service.
|
||||
Its IRQ callback acknowledges VBlank and updates the BIOS RAM flag before the service returns.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue