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
Scope-corrected 2026-08-31. The original report below is accurate, but every
line number it cites is cfg/c64-https-uci.cfg's, while its title globs cfg/c64-https-uci*.cfg. cfg/c64-https-uci-onchip.cfg carries the identical
stale block at its own offsets, and each of the two files is the cfg a
different shipped product links against — so an implementer following the
line numbers literally would fix one shipped image and leave the other wrong.
The scope block added at the end of this issue cites both files with verified
master line numbers, and separates the symptoms PR #168 already fixes from the
ones that survive it. The original text is preserved unedited.
Symptom
cfg/c64-https-uci.cfg's header comments describe a memory map the file itself no longer implements. Verified against a live BACKEND=uci USE_NISTCURVES_ONCHIP=1 link.
UCI_BSS placement. Line 12 describes the NET_CODE tail as holding "UCI_BSS + …", and line 74's arithmetic reasons from the same premise. The map says otherwise:
UCI_BSS 006746 00687B 000136
$6746 is inside CRYPTO_HOT ($6000-$9FFF), not NET_BSS_TAIL ($3B66-$41FF).
Line 14 calls UCI_BSS_REGION a "zero-size alias post-W1" while still describing UCI_BSS as living there — the two halves of one sentence disagree.
Related, already fixed elsewhere — this is the same cluster
PR #168 corrected three neighbouring instances of this defect:
cfg/c64-https-uci.cfg:206 claimed LIB_NISTCURVES_P256_BSS"no longer rides here (it moved to CRYPTO_COLD_SHADOW)", while line 321 of the same file loads it into NET_BSS_TAIL and the map confirms $3CB5.
src/data.s:270-272 claimed BSS_TAIL is routed to NET_BSS_TAIL; it is at $A000.
cfg/c64-https-uci-onchip.cfg carried every one of those plus a header describing the pre-W1 24 KB CRYPTO_HOT and a TCP_BUF removed in Phase 3.
The items above were left out of #168 to keep that PR reviewable. They are the remainder of the same audit, not a new discovery.
Why the cfg comments matter more than ordinary staleness
This is the file people read to answer "where can I put N bytes?" — it is cited in CLAUDE.md's Memory layout section and consulted whenever a segment overflows. NET_CODE overflowed by 35 bytes as recently as #149 and cost the UCI backend entirely. Reasoning about placement from a header that misplaces a live segment is how that recurs.
Two further specifics worth folding in:
cfg/c64-https-uci-onchip.cfg's "GENERATED VARIANT" header is aspirational — the file is hand-maintained, which is why it drifted independently of its sibling. Either generate it for real or drop the claim; a header asserting a property nothing enforces is the same defect one level up.
Both cfgs state "~185 B slack"; the measured tail is 43 B.
Suggested approach
Prefer deleting a duplicated fact over re-stating it. Per #161's rule — would this copy change if the fact did? — a prose byte-count in a cfg header answers no, and will rot again on the next segment move. The SEGMENTS block and the emitted .map are the authority; the header should point at them rather than paraphrase them.
Where a number must appear, consider a link-time .assert (the pattern proposed in #120 for LIB_NISTCURVES_REU_BANK_COMB) so a move fails the build by name instead of quietly contradicting a comment.
Flagged during the #168 audit; verified independently before filing.
Scope correction (added 2026-08-31)
Everything below was verified directly against master at 0b55c30 and against
branch docs/drift-audit-161 (PR #168, OPEN — nothing in it has landed on
master yet). No line number here is inferred from the other file's offsets; each
was read out of the file it is attributed to.
1. Both cfgs ship. Neither is the "spare" copy.
Makefile:34 sets CFG := cfg/c64-https-$(BACKEND).cfg, and Makefile:256 is
the only reassignment in the file — it sits inside ifeq ($(USE_NISTCURVES_ONCHIP_COMB),1). Plain USE_NISTCURVES_ONCHIP=1 never
retargets $(CFG). Cross-checking the three rows of PACKAGE_VARIANTS
(tools/package/_common.sh:24-28):
shipped product
build flags
cfg it links against
c64-https-ip65-onchip.prg
BACKEND=ip65 USE_NISTCURVES_ONCHIP=1
cfg/c64-https-ip65.cfg
c64-https-uci-onchip.prg
BACKEND=uci USE_NISTCURVES_ONCHIP=1
cfg/c64-https-uci.cfg
c64-https-uci-comb.prg
BACKEND=uci USE_NISTCURVES_ONCHIP_COMB=1
cfg/c64-https-uci-onchip.cfg
Confirmed independently by build/flags.stamp from a BACKEND=uci USE_NISTCURVES_ONCHIP=1 tree, whose link line reads -C cfg/c64-https-uci.cfg.
So this is not "fix the shipping one first". Both files back a released image,
and the fix has to be applied twice. The -onchip.cfg name is misleading —
that file is the comb cfg; the onchip product uses the base cfg.
(Note in passing: CLAUDE.md:80 documents USE_NISTCURVES_ONCHIP=1 as using cfg/c64-https-$(BACKEND)-onchip.cfg. That is wrong for the same reason, and is
additionally unsatisfiable for ip65 — no cfg/c64-https-ip65-onchip.cfg exists
in the tree. PR #168 already fixes that line; listed here only so it is not
re-filed.)
2. Master line numbers, both files
cfg/c64-https-uci.cfg is 393 lines at master; cfg/c64-https-uci-onchip.cfg
is 405 (a 14-line GENERATED VARIANT preamble, then a near-verbatim copy).
defect
uci.cfg
uci-onchip.cfg
header map: NET_BSS_TAIL described as holding UCI_BSS
11-13
25-27
header map: UCI_BSS_REGION "zero-size alias … UCI_BSS moved into NET_BSS_TAIL above"
14-15
28-29
header map: CRYPTO_HOT as $6000-$BFFF, 24 KB
19-28
33-42
header map: TCP_BUF at $C000-$CFFF (region removed in Phase 3)
29
43
MEMORY prose: "UCI_BSS now shares NET_BSS_TAIL too … only used ~$125"
74-76
88-90
MEMORY prose: NET_CODE "~$1B26 = 6950 B"
72
86
MEMORY prose: "occupancy tops out at $625 … leaving $B5 slack"
80-81
94-95
MEMORY prose: "UCI_BSS now rides on the head of this combined region"
84-85
98-99
MEMORY prose: "ld65 distributes UCI_BSS (~293 B) + …"
The authority the header contradicts is in the same files: UCI_BSS: load = CRYPTO_HOT at cfg/c64-https-uci.cfg:203 and cfg/c64-https-uci-onchip.cfg:218. No map file is needed to see the
contradiction — the cfg disagrees with itself.
Two arithmetic errors are checkable by inspection, no build required:
NET_CODE is declared size = $1B66 (uci.cfg:82, onchip:96) = 7,014 B.
The comment two lines above says ~$1B26 = 6950 B.
UCI_BSS measures $0136 (310 B) in the map quoted at the top of this issue.
The comments say ~$125 (293 B) and ~293 B.
Read off branch docs/drift-audit-161 itself, not off the PR description. Fixed in both cfgs:
the entire header memory-map block, rewritten from the live map. It now states
the placement positively and negatively: "NOT UCI_BSS, which is in CRYPTO_HOT, and NOT BSS_TAIL, which is in CRYPTO_COLD_SHADOW"
(branch uci.cfg:11-17, onchip:25-31). This is the headline symptom of this
issue — it is already solved on that branch.
the UCI_BSS_REGION header line, which no longer claims UCI_BSS moved there
(branch uci.cfg:18-19, onchip:32-33).
CRYPTO_HOT corrected to 16 KB $6000-$9FFF, with CRYPTO_COLD_SHADOW added
to the map (branch uci.cfg:23-31, onchip:39-47).
the stale TCP_BUF region (branch uci.cfg:32-36, onchip:48-51).
LIB_NISTCURVES_P256_BSS "no longer rides here" — gone from both.
4. What survives #168 — this is what remains for this issue
Confirmed still present at branch tip, in both files:
remaining defect
branch uci.cfg
branch onchip.cfg
"UCI_BSS now shares NET_BSS_TAIL too … ~$125"
86-88
101-103
"UCI_BSS now rides on the head of this combined region"
96-97
111-112
"ld65 distributes UCI_BSS (~293 B) + …"
98-99
113-114
NET_CODE~$1B26 / $625 / $B5 arithmetic
84, 92-93
99, 107-108
GENERATED VARIANT header claim
—
4
PR #168 flags exactly this itself, under "Not fixed, flagged only":
cfg/c64-https-uci.cfg:99-114 has further stale arithmetic in the NET_CODE block (~$1B26 = 6950 B, "UCI_BSS now shares NET_BSS_TAIL", $625 ... leaving $B5 slack). UCI_BSS is in CRYPTO_HOT. Left alone to
keep this diff reviewable; happy to take it in a follow-up.
(Those are branch line numbers, not master's; the master equivalents are in
§2 above.) The one thing #168 does not mention leaving behind is the GENERATED VARIANT header, which its own body argues is aspirational but which
it does not touch.
Apply the remaining fix to both files, in the same PR. Each backs a
released product (§1). A PR that touches only one is half a fix, and the -onchip.cfg name will invite exactly that mistake.
Decide the GENERATED VARIANT claim separately. Either add a generator
and a check that the two files agree, or delete the word. Leaving it is the
same defect one level up, and it is the mechanism by which these two files
will drift apart again after this issue closes.
Symptom
cfg/c64-https-uci.cfg's header comments describe a memory map the file itself no longer implements. Verified against a liveBACKEND=uci USE_NISTCURVES_ONCHIP=1link.UCI_BSSplacement. Line 12 describes theNET_CODEtail as holding "UCI_BSS + …", and line 74's arithmetic reasons from the same premise. The map says otherwise:$6746is insideCRYPTO_HOT($6000-$9FFF), notNET_BSS_TAIL($3B66-$41FF).Line 14 calls
UCI_BSS_REGIONa "zero-size alias post-W1" while still describingUCI_BSSas living there — the two halves of one sentence disagree.Related, already fixed elsewhere — this is the same cluster
PR #168 corrected three neighbouring instances of this defect:
cfg/c64-https-uci.cfg:206claimedLIB_NISTCURVES_P256_BSS"no longer rides here (it moved to CRYPTO_COLD_SHADOW)", while line 321 of the same file loads it intoNET_BSS_TAILand the map confirms$3CB5.src/data.s:270-272claimedBSS_TAILis routed toNET_BSS_TAIL; it is at$A000.cfg/c64-https-uci-onchip.cfgcarried every one of those plus a header describing the pre-W1 24 KBCRYPTO_HOTand aTCP_BUFremoved in Phase 3.The items above were left out of #168 to keep that PR reviewable. They are the remainder of the same audit, not a new discovery.
Why the cfg comments matter more than ordinary staleness
This is the file people read to answer "where can I put N bytes?" — it is cited in CLAUDE.md's Memory layout section and consulted whenever a segment overflows.
NET_CODEoverflowed by 35 bytes as recently as #149 and cost the UCI backend entirely. Reasoning about placement from a header that misplaces a live segment is how that recurs.Two further specifics worth folding in:
cfg/c64-https-uci-onchip.cfg's "GENERATED VARIANT" header is aspirational — the file is hand-maintained, which is why it drifted independently of its sibling. Either generate it for real or drop the claim; a header asserting a property nothing enforces is the same defect one level up.Suggested approach
Prefer deleting a duplicated fact over re-stating it. Per #161's rule — would this copy change if the fact did? — a prose byte-count in a cfg header answers no, and will rot again on the next segment move. The
SEGMENTSblock and the emitted.mapare the authority; the header should point at them rather than paraphrase them.Where a number must appear, consider a link-time
.assert(the pattern proposed in #120 forLIB_NISTCURVES_REU_BANK_COMB) so a move fails the build by name instead of quietly contradicting a comment.Flagged during the #168 audit; verified independently before filing.
Scope correction (added 2026-08-31)
Everything below was verified directly against
masterat0b55c30and againstbranch
docs/drift-audit-161(PR #168, OPEN — nothing in it has landed onmaster yet). No line number here is inferred from the other file's offsets; each
was read out of the file it is attributed to.
1. Both cfgs ship. Neither is the "spare" copy.
Makefile:34setsCFG := cfg/c64-https-$(BACKEND).cfg, andMakefile:256isthe only reassignment in the file — it sits inside
ifeq ($(USE_NISTCURVES_ONCHIP_COMB),1). PlainUSE_NISTCURVES_ONCHIP=1neverretargets
$(CFG). Cross-checking the three rows ofPACKAGE_VARIANTS(
tools/package/_common.sh:24-28):c64-https-ip65-onchip.prgBACKEND=ip65 USE_NISTCURVES_ONCHIP=1cfg/c64-https-ip65.cfgc64-https-uci-onchip.prgBACKEND=uci USE_NISTCURVES_ONCHIP=1cfg/c64-https-uci.cfgc64-https-uci-comb.prgBACKEND=uci USE_NISTCURVES_ONCHIP_COMB=1cfg/c64-https-uci-onchip.cfgConfirmed independently by
build/flags.stampfrom aBACKEND=uci USE_NISTCURVES_ONCHIP=1tree, whose link line reads-C cfg/c64-https-uci.cfg.So this is not "fix the shipping one first". Both files back a released image,
and the fix has to be applied twice. The
-onchip.cfgname is misleading —that file is the comb cfg; the onchip product uses the base cfg.
(Note in passing:
CLAUDE.md:80documentsUSE_NISTCURVES_ONCHIP=1as usingcfg/c64-https-$(BACKEND)-onchip.cfg. That is wrong for the same reason, and isadditionally unsatisfiable for ip65 — no
cfg/c64-https-ip65-onchip.cfgexistsin the tree. PR #168 already fixes that line; listed here only so it is not
re-filed.)
2. Master line numbers, both files
cfg/c64-https-uci.cfgis 393 lines at master;cfg/c64-https-uci-onchip.cfgis 405 (a 14-line
GENERATED VARIANTpreamble, then a near-verbatim copy).uci.cfguci-onchip.cfgNET_BSS_TAILdescribed as holdingUCI_BSSUCI_BSS_REGION"zero-size alias …UCI_BSSmoved intoNET_BSS_TAILabove"CRYPTO_HOTas$6000-$BFFF, 24 KBTCP_BUFat$C000-$CFFF(region removed in Phase 3)MEMORYprose: "UCI_BSSnow sharesNET_BSS_TAILtoo … only used~$125"MEMORYprose:NET_CODE"~$1B26= 6950 B"MEMORYprose: "occupancy tops out at$625… leaving$B5slack"MEMORYprose: "UCI_BSSnow rides on the head of this combined region"MEMORYprose: "ld65 distributesUCI_BSS(~293 B) + …"LIB_NISTCURVES_P256_BSS"no longer rides here"~185 B slackafter the P-256 claim"GENERATED VARIANTheader (aspirational; nothing generates it)The authority the header contradicts is in the same files:
UCI_BSS: load = CRYPTO_HOTatcfg/c64-https-uci.cfg:203andcfg/c64-https-uci-onchip.cfg:218. No map file is needed to see thecontradiction — the cfg disagrees with itself.
Two arithmetic errors are checkable by inspection, no build required:
NET_CODEis declaredsize = $1B66(uci.cfg:82,onchip:96) = 7,014 B.The comment two lines above says
~$1B26 = 6950 B.UCI_BSSmeasures$0136(310 B) in the map quoted at the top of this issue.The comments say
~$125(293 B) and~293 B.3. What PR #168 already fixes — do not redo these
Read off branch
docs/drift-audit-161itself, not off the PR description.Fixed in both cfgs:
the placement positively and negatively: "NOT
UCI_BSS, which is inCRYPTO_HOT, and NOTBSS_TAIL, which is inCRYPTO_COLD_SHADOW"(branch
uci.cfg:11-17,onchip:25-31). This is the headline symptom of thisissue — it is already solved on that branch.
UCI_BSS_REGIONheader line, which no longer claimsUCI_BSSmoved there(branch
uci.cfg:18-19,onchip:32-33).CRYPTO_HOTcorrected to 16 KB$6000-$9FFF, withCRYPTO_COLD_SHADOWaddedto the map (branch
uci.cfg:23-31,onchip:39-47).TCP_BUFregion (branchuci.cfg:32-36,onchip:48-51).LIB_NISTCURVES_P256_BSS"no longer rides here" — gone from both.~185 B slackreplaced with the measured figure in both(branch
uci.cfg:343,onchip:353). docs: correct seven documentation-drift defects, and stop restating rot-prone counts #168 measures the tail at 43 B(
$41D5-$41FF) on both profiles, which is where this issue's "43 B" comesfrom.
4. What survives #168 — this is what remains for this issue
Confirmed still present at branch tip, in both files:
uci.cfgonchip.cfgUCI_BSSnow sharesNET_BSS_TAILtoo …~$125"UCI_BSSnow rides on the head of this combined region"UCI_BSS(~293 B) + …"NET_CODE~$1B26/$625/$B5arithmeticGENERATED VARIANTheader claimPR #168 flags exactly this itself, under "Not fixed, flagged only":
(Those are branch line numbers, not master's; the master equivalents are in
§2 above.) The one thing #168 does not mention leaving behind is the
GENERATED VARIANTheader, which its own body argues is aspirational but whichit does not touch.
5. Revised scope for this issue
branch; rebasing this work onto it avoids two lanes rewriting the same header.
released product (§1). A PR that touches only one is half a fix, and the
-onchip.cfgname will invite exactly that mistake.than re-measuring it — per Three VICE suites pass or fail for reasons unrelated to what they measure (test_finished_verify's 16 negatives are vacuous on UCI) #161, a hand-typed byte count in a comment cannot
change when the fact does, so re-measuring buys a correct file today rather
than a file that stays correct.
MEMORY/SEGMENTSand the emitted.maparethe authority.
GENERATED VARIANTclaim separately. Either add a generatorand a check that the two files agree, or delete the word. Leaving it is the
same defect one level up, and it is the mechanism by which these two files
will drift apart again after this issue closes.