The 4002 is the data/IO partner of the 4004/4040. 16-pin DIP, 80 nibbles (4 registers × 16 main chars + 4 status chars each), plus 4 dedicated output port pins driven by the WMP instruction. This skeleton: - Pin contract registered (D0..D3, O0..O3, SYNC, CL, RESET, CM, VDD, VSS). - Storage allocated (main[4][16] + status[4][4] arrays). - SYNC + own timer + CM-strobe gating tracks the SRC chip-select latch at X2/X3 (compile-time RAM4002_CHIP_PAIR selects which of 4 chip pairs this instance responds to). - RESET clears storage and drops output port to 0. Not yet implemented (Phase D-2 follow-up): full SRC + WRM/RDM/WR0..3/ RD0..3 round-trip with the 4004. The 4004 chip currently stubs those I/O instructions, so even though the 4002's address-latching works, no data ever flows. Requires modifying 4004.c to drive the bus during X2/X3 of SRC and during M2 of the I/O group. Tests: 2/2 passing (pin contract + RESET behaviour). Total test_intel: 111→113 passing. The 4-chip 4004 ecosystem (4001 + 4002 + 4004 + canvas-deployable variants) now exists. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| 4001-rom.c | ||
| 4001-rom.test.js | ||
| 4002-ram.c | ||
| 4002-ram.test.js | ||
| 8251-usart.c | ||
| 8251-usart.test.js | ||
| 8253-pit.c | ||
| 8253-pit.test.js | ||
| 8255-ppi.c | ||
| 8255-ppi.test.js | ||
| 8259-pic.c | ||
| 8259-pic.test.js | ||
| README.md | ||
| latch-8282.c | ||
| latch-8282.test.js | ||
| ram-64k.c | ||
| ram-64k.test.js | ||
| rom-1m.c | ||
| rom-1m.test.js | ||
| rom-32k.c | ||
| rom-32k.test.js | ||
README.md
test_buses — External memory chips for retro CPUs
Real PCBs from 1976 don't put RAM/ROM inside the CPU package. Faithful emulation requires the same separation: the CPU drives address pins, chip-select, and RD̅/WR̅; separate memory chips on the canvas listen.
These chips are reusable across all five Intel/Z80 CPU projects.
Chips planned
| Chip | Pins | Source file | Status |
|---|---|---|---|
rom-32k |
27 | rom-32k.c |
✅ Implemented — 6/6 tests passing |
ram-64k |
29 | ram-64k.c |
✅ Implemented — 7/7 tests passing |
latch-8282 |
20 | latch-8282.c |
📋 Spec only (only needed for 8086) |
Why we still test these C chips even though tests use installFakeRom
The BoardHarness.installFakeRom() and installFakeRam() helpers
emulate memory in JS for CPU unit tests. They are fast, flexible,
and don't require a per-test compile.
The real rom-32k.c / ram-64k.c chips are needed because:
- End users wire them on the canvas. A user dropping a Z80 into velxio expects a draggable ROM and RAM next to it. The C chips ARE that user-visible primitive.
- Integration tests need the real chip. Once a CPU is verified
in unit tests with a fake ROM, an integration test runs the same
CPU with the real
rom-32k.wasm, proving the on-canvas demo will work.
So the test split is:
*.unit.test.js→ usesinstallFakeRom/installFakeRam, tests instruction semantics and bus protocol*.integration.test.js→ uses real compiled bus chips, proves the user-visible demo works
For now we have rom-32k.test.js and ram-64k.test.js covering the
C chip behavior in isolation — pin contract + read/write protocol
with hand-crafted bus stimuli.
ROM image loading — the SDK constraint
The velxio chip SDK does not (yet) support arbitrary-length blob
attributes. vx_attr_register only takes a double. So a 32 KB ROM
image cannot be passed in via .chip.json properties.
Workaround for now: the C source contains
const uint8_t rom_image[32768] = { /* baked-in */ };. Each "ROM
variant" is a separate compiled chip. For shipping examples we will
generate one variant per demo program; for tests we use a small image
embedded directly in rom-32k.c.
A follow-up SDK proposal — adding vx_attr_register_blob() or an
"asset" import mechanism — is tracked in
../autosearch/05_open_questions.md.
ram-64k notes
The RAM chip is simpler — no embedded image, just a static uint8_t mem[65536] zero-initialized at chip_setup. No SDK extension required.