Board-less digital circuits (logic gates + switches + LEDs) run today as ngspice
analog B-sources, which is fragile for deep logic: a 4-bit ripple adder re-solves
but never lights its result LEDs live. This adds an event-driven digital motor
that reuses the multichip-bus settle kernel, so the same engine that boots a Z80
over a chip bus evaluates a gate network exactly and instantly.
Phases 0-2 (project/digital-gate-engine/), all behind ?digitalgates=on (default
OFF — flag off is byte-for-byte the old behaviour):
- digitalGateEngine.ts: buildDigitalNetwork(components, wires) does union-find
over the wires (merging pass-through resistors), identifies the rail/gnd from
the signal-generator, registers drivers (rail STRONG-1, gnd 0, pull resistors
PULL, slide-switch as a pass-gate) and event-driven gates (reusing the
LogicGateParts boolean semantics), settles on busKernel, and exposes
setSwitch / readLed / netOf. Tolerant of both the raw example `type` and the
store `metadataId`. Returns {ok:false} for any non-primitive, so mixed/analog
circuits stay entirely on ngspice.
- digitalGateController.ts + a SimulatorCanvas useEffect: when the flag is on and
the circuit is all-digital, rebuild from the store on switch-toggle / load
(rAF-coalesced) and paint the wokwi-led DOM. CircuitSimulationService.tick()
skips the SPICE solve for all-digital circuits when the flag is on, so the two
motors never fight over the LEDs.
Tests: digitalgate-kernel (22 — single gates -> half/full adder -> 4-bit
adder/subtractor -> exhaustive ADD 256 -> mux/decoder/comparator/parity/
multiplier) and digitalgate-engine-examples (6 — the real gallery data for
and/or/xor/not + the full adder/subtractor). Verified live: ?digitalgates=on
lights the adder's result LEDs that the SPICE path leaves dark. Full suite
2117 pass / 5 pre-existing unrelated fails.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>