You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
UCI adapter: CIA1 TOD is never started, so the TOD-bounded waits (uci_wait_idle / uci_wait_not_busy / resp reads) are unbounded on real hardware #145
Found while chasing c64-wireguard#58 on a U64E (fw 3.15), using the uci_wait_idle design your adapter originated (c64-https#37) — this applies to the original as much as to our port.
Measurement
With the C64 hung inside net_udp_send, I hooked $0314 with a routine copying $DC08–$DC0B into RAM on every IRQ: 207 samples over 3 s, TOD = 00:00:00.0 every time, hour byte $91 (the CIA's untouched reset value). The CIA TOD does not run until its TENTHS register is written, and neither adapter ever writes it. So the cmp last_tenths / beq loop bound never advances: every "wall-clock bounded" wait is unbounded on hardware. (VICE's CIA starts the TOD running, which is why the emulator never shows this.)
Proof of mechanism: a one-shot sta $DC08 from the hook started the clock, and the hung wait expired within 2 s and returned C=1 with the adapter's error.
Fix (c64-wireguard src/net/uci/uci_cmd.s, uci_tod_start, called first thing in net_init)
lda$DC0F ; and #$7F ; sta $DC0F ; CRB bit 7 = 0: writes set the clock, not the alarmlda #0sta$DC0B ; sta $DC0A ; sta $DC09 ; hours (halts), min, secsta$DC08 ; tenths — starts the clock
Run it once before any bounded wait. Note every run_prg/reset stops the TOD again, so it belongs in init, not in a one-off.
Contract
Reported to the c64-lib-contract lane for a normative line in §13.4 ("adapter MUST start the TOD before the first bounded wait; a stopped TOD makes the bound infinite").
Contract side: c64-lib-contract#145 (SPEC v0.13.0 draft §13.4) now makes this normative — start the TOD, then verify it ticks (bounded spin until the tenths digit changes; fail init with the contract-generic $01 NET_ERR_TIMEBASE_STOPPED if it never does), plus a conformance test where the device never answers so $89 is actually exercised. c64-wireguard's uci_tod_start (PR #68) is built to that shape and verified on the hung device: net_udp_send returns C=1 in 1.5 s where it previously hung forever.
Activity
JC-000 commentedon Aug 27, 2026
Contract side: c64-lib-contract#145 (SPEC v0.13.0 draft §13.4) now makes this normative — start the TOD, then verify it ticks (bounded spin until the tenths digit changes; fail init with the contract-generic
$01 NET_ERR_TIMEBASE_STOPPEDif it never does), plus a conformance test where the device never answers so$89is actually exercised. c64-wireguard'suci_tod_start(PR #68) is built to that shape and verified on the hung device:net_udp_sendreturnsC=1in 1.5 s where it previously hung forever.docs: the bounded-wait design needs a running clock (#145)
Merge pull request #146 from JC-000/fix/145-cia-tod-start