velxio/test/test_intel/test_buses
David Montero d5ab6ba6b9 test_intel: phase D — 4002 RAM chip (basic skeleton)
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>
2026-05-01 00:38:36 +02:00
..
4001-rom.c test_intel: phase D — 4001 ROM chip with 4004 integration 2026-04-30 20:44:17 +02:00
4001-rom.test.js test_intel: phase D — 4001 ROM chip with 4004 integration 2026-04-30 20:44:17 +02:00
4002-ram.c test_intel: phase D — 4002 RAM chip (basic skeleton) 2026-05-01 00:38:36 +02:00
4002-ram.test.js test_intel: phase D — 4002 RAM chip (basic skeleton) 2026-05-01 00:38:36 +02:00
8251-usart.c test_intel: phase C — support chips (partial: rom-1m, 8255, 8251) 2026-04-30 04:53:31 +02:00
8251-usart.test.js test_intel: phase C — support chips (partial: rom-1m, 8255, 8251) 2026-04-30 04:53:31 +02:00
8253-pit.c test_intel: phase C extension — 8259 PIC and 8253 PIT 2026-04-30 20:44:17 +02:00
8253-pit.test.js test_intel: phase C extension — 8259 PIC and 8253 PIT 2026-04-30 20:44:17 +02:00
8255-ppi.c test_intel: phase C — support chips (partial: rom-1m, 8255, 8251) 2026-04-30 04:53:31 +02:00
8255-ppi.test.js test_intel: phase C — support chips (partial: rom-1m, 8255, 8251) 2026-04-30 04:53:31 +02:00
8259-pic.c test_intel: phase C extension — 8259 PIC and 8253 PIT 2026-04-30 20:44:17 +02:00
8259-pic.test.js test_intel: phase C extension — 8259 PIC and 8253 PIT 2026-04-30 20:44:17 +02:00
README.md autosearch — Research notes for Intel + Z80 custom-chip emulation 2026-04-29 22:24:02 +02:00
latch-8282.c test_intel: Intel 8282 octal latch 2026-04-29 22:51:19 +02:00
latch-8282.test.js test_intel: Intel 8282 octal latch 2026-04-29 22:51:19 +02:00
ram-64k.c autosearch — Research notes for Intel + Z80 custom-chip emulation 2026-04-29 22:24:02 +02:00
ram-64k.test.js autosearch — Research notes for Intel + Z80 custom-chip emulation 2026-04-29 22:24:02 +02:00
rom-1m.c test_intel: phase C — support chips (partial: rom-1m, 8255, 8251) 2026-04-30 04:53:31 +02:00
rom-1m.test.js test_intel: phase C — support chips (partial: rom-1m, 8255, 8251) 2026-04-30 04:53:31 +02:00
rom-32k.c autosearch — Research notes for Intel + Z80 custom-chip emulation 2026-04-29 22:24:02 +02:00
rom-32k.test.js autosearch — Research notes for Intel + Z80 custom-chip emulation 2026-04-29 22:24:02 +02:00

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:

  1. 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.
  2. 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 → uses installFakeRom / 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.