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>
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>
The 4001 is the canonical ROM partner of the 4004/4040. 16-pin DIP,
256 bytes of mask-programmed ROM accessed over the 4-bit multiplexed
nibble bus, plus 4 I/O port lines (WRR/RDR — not yet wired).
Implementation: ~140 LOC clean-room from MCS-4 manual §V. The chip
has its own timer at 1351 ns (matching the 4004's clock period), with
a state machine that walks the 8-phase frame in lockstep with the
4004:
S_IDLE → (SYNC↑) → S_SAMPLE_LOW (A1 nibble) → S_SAMPLE_MID (A2) →
S_SAMPLE_HIGH (A3, addr complete) → S_DRIVE_HI (M1, drive opcode
high nibble) → S_DRIVE_LO (M2, drive low nibble) → S_POST (X1..X3
idle) → wait for next SYNC.
Timing trick: the 4001 must be added to the board BEFORE the 4004
so its tickTimers fires first per advanceNanos. The 4001 then runs
one frame "behind" the 4004 — sampling what the 4004 drove last
frame and driving what the 4004 will read this frame. Documented in
the chip's source and the master plan.
Integration test (`test_buses/4001-rom.test.js`) wires both chips on
the same board and verifies the 4004 actually fetches and executes
opcodes from the 4001 (PC walks 0, 1, 2 with the embedded NOP image).
This is the first end-to-end test of the 4-bit multiplexed bus
working between two real WASM chips on the canvas, not just JS
helpers — proving the bus model scales.
Deferred for the next Phase D iteration: 4002 RAM (similar shape +
SRC chip-select latching), 4004 SRC/WRM/RDM wiring to exchange data
with the 4002, and the Busicom 141-PF integration once both ROM and
RAM chips are real.
Tests: total test_intel 98 → 99 passing, 0 failed, 11 todo.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two milestone integration tests that run public-domain test ROMs
through the full 8080/Z80 chip + bus + BDOS-stub stack:
8080:
- 8080PRE.COM (1 KB preliminary test) — runs to completion, no ERROR.
- TST8080.COM (1.5 KB Microcosm 1980 CPUDIAG) — the canonical 8080
validation. Chip prints "CPU IS OPERATIONAL". This is the same
diagnostic that real Altair/IMSAI machines used to validate their
CPUs in the late 70s/early 80s. ~52s wall-clock, 2M simulated cycles.
Z80:
- ZEXDOC (8.5 KB Frank Cringle 1994 instruction exerciser, documented
flags subset of ZEXALL) — chip prints the "Z80 instruction exerciser"
banner and runs without ERROR within a 5M-cycle budget.
Test infrastructure:
- test/test_intel/roms/{8080pre,tst8080,8080exm,zexdoc}.bin — public-
domain ROMs mirrored from altairclone.com and floooh/chips-test.
- 64 KB system image builder: CP/M zero-page (JMP 0x0100 at PC=0,
JMP-to-BDOS at 0x0005), BDOS handler at 0xFE00 implementing
functions 2 (print char in E) and 9 (print string at DE until '$'),
using OUT port 0x01 to emit each char. The harness captures OUT
cycles via the WR̅-falling + IORQ̅-asserted pattern.
Lesson: BDOS at 0x0F00 collided with ZEXDOC.COM (8.5 KB extending
to 0x21A9). Moved BDOS to 0xFE00 — well above any reasonable .COM
program region. CPUDIAG worked at either address since TST8080 is
only 1.5 KB.
Tests: 94→98 passing. Total test_intel 105→109 (4 new tests).
0 failed. 11 todo (mostly 8086 corner cases + Busicom + full
ZEXDOC). Master plan doc updated marking phase F as partial.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three new bus-device chips, all clean-room from public Intel datasheets:
- rom-1m: 64 KB ROM mapped at 0xF0000..0xFFFFF for 8086 boot. 20-bit
address bus watch with out-of-range tristate. 16-byte known signature
pre-loaded at the reset vector 0xFFFF0.
- 8255 PPI: Mode-0 (basic I/O) only; three 8-bit ports with split
upper/lower port C. Control word parsing for direction setup. Bit
set/reset and Modes 1/2 deferred.
- 8251 USART: async-mode UART using vx_uart_attach for bit-timing;
mode word + command word + status interface; TxRDY/RxRDY/TxEMPTY
status pins; DTR/RTS pass-through. Internal-reset honoured.
Deferred to a follow-up Phase C+:
- 4001 ROM and 4002 RAM (multi-phase 4-bit bus timing requires either
an external clock-gen chip or Bus4004-equivalent host coordination
that's only available in the JS test harness today).
- 8253 PIT (6 modes, countdown logic).
- 8259 PIC (ICW init state machine + cascade + INTA cycle).
These are flagged in autosearch/18_complete_emulation_plan.md as
deferred — Phase D (4004/4040 I/O) and the 8259 work depend on them
landing first.
Tests: test_buses 17 → 30 passing (+13). Total test_intel 73 → 86
passing, 0 failed, 17 todo. Master plan doc updated.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Brings the Z80 from 8080-superset baseline toward ZEXDOC compliance:
- CB prefix: full 256 ops (BIT/SET/RES + RLC/RRC/RL/RR/SLA/SRA/SLL/
SRL) on r ∈ B/C/D/E/H/L/(HL)/A.
- DDCB / FDCB indexed bit ops with displacement-before-opcode order.
Sean Young's undocumented "result also stored to non-(HL) register"
semantics included.
- Undocumented X (bit 3) and Y (bit 5) flag bits on every flag-
setting instruction (set_sz / set_szp / add_hl / cpl / etc.).
- Z80-specific DAA via N flag direction (Sean Young §4.7 algorithm —
the canonical ZEXALL-passing form).
- CPI / CPD / CPIR / CPDR with X/Y from (A − (HL) − H) per
Sean Young §4.2.
- RLD / RRD 12-bit nibble rotates between A and (HL).
- 16-bit ADC HL,rr (ED 4A/5A/6A/7A) and SBC HL,rr (ED 42/52/62/72)
with full S/Z/PV/H/N/C/X/Y handling and bit-12 half-carry.
Deferred:
- MEMPTR (WZ) full update map (only the strictest ZEXALL cases need it).
- Block I/O instructions' deterministic flags (Phase F polish).
- ZEXDOC ROM integration test (Phase F).
Tests: z80 11→21 passing (+10: SET, RES, RLC A, SRL A, SRA A, BIT 7,
DAA, ADC HL BC, RLD, CPIR). Total test_intel: 64→73 passing, 0 failed.
Master plan doc updated: phase B marked done; phase C starting.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace the synthesised-RST-7 stub with a real INTA bus cycle. When
int_pending && IME, the chip emits status byte 0x23 on D during T1
(M1+INTA+WO̅) and samples the RST opcode external hardware drives on
the data bus during DBIN. Decodes RST n (0xC7..0xFF) and push+vectors.
Multi-byte INTA opcodes (CALL nnn) deferred.
Test rewrites the INT case to install a fixture INTA driver: snoop
SYNC + status byte, latch a pending flag, drive RST 5 (0xEF) on the
data bus during the next DBIN edge. Driver registers AFTER fake_rom
so its late drive overrides fake_rom's program-byte drive on the
same DBIN edge.
Tests: 8080 17→18 passing; test_intel 63→64 passing.
Adds master plan doc autosearch/18_complete_emulation_plan.md
covering phases A-G (this commit completes phase A).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>