Add the generated-program software frame and calling convention in
src/runtime/frames.s. The frame stack grows downward from $C000 over
$B800-$BFFF; SP and FP use the free zero-page bytes $FB-$FE. A caller
pushes arguments right-to-left, JSRs the callee, the callee enters a frame
(old FP, then locals below FP), returns one byte in A or two in A/X, and
the caller discards its arguments. frame_enter checks the stack bound and,
on overflow, restores SP/FP and returns FRAME_ERR_STACK without
corrupting the caller's frame.
The x128 ABI fixture runs with CR $0E (RAM through $BFFF), exercises a
nested recursive function to a bounded depth, a one-byte-return function, and
a deliberate overflow that unwinds cleanly, then restores the entry mapping
and reports through the mailbox.
src/runtime/frames.s (new), src/common/frames.inc (new)tests/codegen/frame-test.sscripts/build-frame-test.ps1, scripts/verify-frame-test.ps1cfg/compiler.cfg (COMMON optional for runtime-only links)docs/decisions.md, docs/architecture.md, docs/memory-map.mdplanning/claims/E04-S02.mdbuild/FP+2 into a local, uses locals below
FP, and preserves a local sentinel across nested calls.SP to $C000; the one-byte
helper also returns with SP/FP restored.sum_bytes returns 12 in A;
recurse(50) returns 1275 ($04FB) in A/X.FRAME_ERR_STACK, restores SP=$C000 and FP=0, and leaves no
partial frame. A direct check lowers the 6502 stack pointer below $40,
calls frame_enter, verifies the refusal, and restores the hardware stack.done; E04-S01's container is complete.$0E itself and restores the entry CR before
returning to BASIC. Code generation will install the same mapping and call
frame_init when it emits user code (E04-S03); this story provides the
runtime and ABI evidence, not codegen integration.cfg/compiler.cfg now marks COMMON optional so runtime-only fixtures can
link without compiler startup; compiler builds still provide it.JSR levels
first. Added the $40 hardware-stack guard and gave the overflow fixture
24-byte locals so the software bound is exercised before the hardware one.tsx before saving the caller's X, replacing
the locals high byte with the stack pointer. Locals are now saved first.scripts/build-frame-test.ps1scripts/verify-frame-test.ps1 -Port 6530scripts/verify-output-test.ps1 -Port 6530 -RunPort 6531scripts/verify-diag-test.ps1 -Port 6530scripts/verify-parser-test.ps1 -Port 6530git diff --check$C000, frame_error=1, final FP=0. The map switch and restore
complete and the fixture prints/returns to BASIC.src/runtime/frames.s, src/common/frames.inc,
tests/codegen/frame-test.s, scripts/build-frame-test.ps1,
scripts/verify-frame-test.ps1, cfg/compiler.cfg, docs/decisions.md,
docs/architecture.md, docs/memory-map.md, this claim.$40 hardware-stack threshold
are provisional; the 6502 stack still limits deep recursion even when frames
are small; expression spills beyond the tested locals are not yet exercised;
the frame stack occupies fixed bank 0 and is not banked; codegen must install
CR $0E, call frame_init, and restore the entry CR; runtime fault codes
are not yet mapped to the future R-code namespace (E04-S05); no ABI test
covers four-byte interface results or self yet.Powered by TurnKey Linux.