Two long-deferred Phase C chips, both clean-room from public Intel datasheets. These complete the support-chip ecosystem needed for real interrupt-driven 8080/Z80/8086 software on the canvas. 8259 PIC (~280 LOC, single-master subset): - Full ICW1..ICW4 init sequence with branching on single/cascade and ICW4-needed flags. - IRR/ISR/IMR registers; OCW3 read-back; OCW1 mask write. - Priority-based INT (lower IRQ# = higher priority, fully-nested); pre-emption when a higher-priority IRQ arrives during a lower- priority ISR. - INTA falling-edge → drives vector_base + IRQ# on D bus. - Non-specific (0x20) and specific (0x60..67) EOI. - Cascade-master/slave routing NOT implemented (single master is sufficient for 95% of demos). - 7/7 tests passing. 8253 PIT (~210 LOC, Modes 0/2/3 subset): - Three independent 16-bit counters with own CLK/GATE/OUT pins. - Mode 0 (interrupt on terminal count) for one-shot timers. - Mode 2 (rate generator) for system tick. - Mode 3 (square wave, decrements by 2) for PC-speaker tone. - Modes 1/4/5 coerced to Mode 0 (rare in practice). - Full RW mode set: LSB-only / MSB-only / LSB-then-MSB / latch. - GATE-low pauses the countdown. - 4/4 tests passing. Tests: total test_intel 99→110 passing (+11). 0 failed. 11 todo. Master plan doc updated: Phase C extension done; Phase G still deferred. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| 4001-rom.c | ||
| 4001-rom.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.