Commit Graph

2 Commits

Author SHA1 Message Date
David Montero Crespo 3137c40a90 feat(chipbus): Phase 2 - synchronous settle kernel (settle-before-read)
Fixes root cause B: a CPU bus cycle drives address+strobe then reads the
data bus in the same tickTimers call, so the memory chip must react before
the read. Phase 0/1 applied each net change by firing PinManager listeners
immediately, which recurses one JS frame per hop - deep glue chains are
deep recursion and a combinational loop overflows the stack.

- busKernel.ts: a delta-cycle settle loop. A net change is recorded in a
  pending set, not applied recursively; settle() drains it in batches
  (deltas), applying each and letting the driven chips re-dirty the next,
  until a fixed point or DELTA_CAP trips (oscillation -> warn, not hang).
  Two-phase: a drive lands in pending and is applied on the next delta, so
  a chip evaluating mid-settle reads last-stable nets. The first drive of a
  cycle settles synchronously before returning to the chip's C code, so the
  in-cycle vx_pin_read sees settled data.
- busNets: publishes resolved levels through the kernel instead of calling
  triggerPinChange directly.

Tests (chipbus-buskernel): multi-hop chain settles; settle-before-read; a
5000-hop chain settles without stack overflow; a ring oscillator trips the
cap and warns instead of hanging. The two-real-chip integration still
exchanges 0xA5 through the kernel. Full suite 2079 pass flag-off.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 02:36:54 -03:00
David Montero Crespo 23516247a6 feat(chipbus): Phase 1 - 4-valued logic + drive-strength tri-state buses
A chip-to-chip net is now resolved by (value, strength), not last-writer-
wins, so a real multi-driver bus works: many chips on one data line, only
the enabled one drives, the rest release to Hi-Z.

- busLogic.ts: 4-valued (0/1/Z/X) + drive-strength resolution. Strongest
  driver wins; equal strength + opposite = X (contention); no driver = Z;
  pull resistor = pull strength. modeToDrive maps VX_OUTPUT -> strong,
  VX_INPUT -> Hi-Z (the rom/ram/8255 "release by input" idiom becomes real
  tri-state), VX_INPUT_PULLUP/DOWN -> pull.
- busNets.ts: per-net driver registry; resolves and pushes the resolved
  level into PinManager; warns once on contention.
- syntheticPins.ts: isSyntheticNetPin distinguishes bus net keys.
- ChipRuntime.ts: pin register/write/set_mode route bus-net pins through
  busNets (gated by chipBusEnabled + isSyntheticNetPin); non-bus pins keep
  the legacy path; dispose releases the chip's bus drivers. SPICE source
  emission is skipped for bus pins (digital fast path beside SPICE).

Tests: busLogic (14), busNets (6, incl. tri-state hand-off + contention),
and the two-real-chip integration now exchanges 0xA5 through the registry.
Full suite 2074 pass with the flag off.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 02:18:47 -03:00