velxio/test/test_intel/test_z80
David Montero afad6a1ed0 test_intel: historic ROM boots — Busicom + Tiny BASIC + Galaksija
Wire up three real, public-domain ROMs from the silicon era and prove
they boot end-to-end on the clean-room chip implementations. Each
test reads a separate well-known boot artifact:

* Busicom 141-PF firmware (4004, 1 KB, Intel PD 2009)
  Wires real 4004 + real 4002 chips on the multiplexed nibble bus.
  Toggles TEST every ~400 phases to mimic the printer-drum encoder
  pulse the firmware polls. Asserts >2000 opcode fetches, >15 unique
  PC addresses, and >100 CMROM strobes.

* Palo Alto Tiny BASIC v2 (8080, 1.9 KB, Wang 1976 PD)
  CPUville port loaded from Intel HEX. Fake polled 8251 UART at port
  0x02 (data) / 0x03 (status). Asserts the captured TX stream
  contains the BASIC "OK" prompt — proving the interpreter reached
  its REPL.

* Galaksija ROM A (Z80, 4 KB, Voja Antonić PD 1984)
  ROM A+B at 0x0000..0x1FFF, system RAM at 0x2000..0x3FFF. Asserts
  PC visits the JP target 0x03DA from reset and the ASCII "READY"
  prompt appears in RAM after init.

ROMs are downloaded to roms/{4004,8080,z80}/ and gitignored — the
tests skip cleanly when the binaries are absent. License-clean: no
GPL ROMs, all PD by upstream provenance.

Total: 126 → 129 passing, 0 todo, 0 failed; 19 → 22 test files.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 04:18:00 +02:00
..
README.md autosearch — Research notes for Intel + Z80 custom-chip emulation 2026-04-29 22:24:02 +02:00
galaksija.test.js test_intel: historic ROM boots — Busicom + Tiny BASIC + Galaksija 2026-05-01 04:18:00 +02:00
hello.test.js test_intel: phase F — software validation (CPUDIAG + ZEXDOC pass) 2026-04-30 20:44:17 +02:00
z80.c test_intel: phase B — Z80 ISA polish (CB / DAA / RLD / ADC HL / CPI) 2026-04-30 04:44:27 +02:00
z80.test.js test_intel: phase D-3 + todo cleanup — 125/126 passing 2026-05-01 03:20:50 +02:00
zexdoc.test.js test_intel: phase F — software validation (CPUDIAG + ZEXDOC pass) 2026-04-30 20:44:17 +02:00

README.md

test_z80 — Zilog Z80 as a velxio custom chip

See ../autosearch/02_intel_chips_overview.md for the spec.

Status

Implemented (core). 6/13 active tests pass; 7 are it.todo deferred milestones. ~550 LOC clean-room C in z80.c compiled to fixtures/z80.wasm.

Validated against:

  • Zilog Z80 Family CPU User Manual UM008003-1202 (2002 reprint of the canonical doc; PDF at autosearch/pdfs/z80_user_manual.pdf)
  • Sean Young, "The Undocumented Z80 Documented" v0.91 (PDF at autosearch/pdfs/z80_undocumented.pdf)
  • Cross-checked against floooh/chips/z80.h (zlib), superzazu/z80 (MIT, passes ZEXALL), kosarev/z80 (MIT)

What works:

  • 40-pin contract, M1 cycle (M1̅+MREQ̅+RD̅ asserted simultaneously), RFSH̅ pulse with R counter and I driving the address bus.
  • 8080-superset ISA: LD r,r' / LD r,n / LD rr,nn / LD (nn),A / LD A,(nn) / ALU / INC / DEC / 16-bit ADD HL / rotates / control flow / stack.
  • Z80-only: EX DE,HL / EX AF,AF' / EXX / DJNZ / JR / LDIR / LDDR / NEG (8 aliases) / IM 0/1/2 / EI / DI / IN / OUT.
  • DD/FD prefix → IX/IY substitution for HL-using opcodes (incl. (IX+d) with displacement byte).
  • ED prefix → block ops, IM, NEG, RETN/RETI, LD (nn),rr / LD rr,(nn).
  • NMI̅ falling-edge → push PC, vector to 0x0066 (without IFF1→IFF2 copy, per Sean Young's hardware tests, contradicting Zilog's manual).

Deferred until ZEXDOC/ZEXALL integration phase:

  • X (bit 3) and Y (bit 5) "undocumented" flag bits — required by ZEXALL but no current test exercises them.
  • MEMPTR (WZ) register — only observable through BIT n,(HL).
  • CB-prefix bit ops (BIT/SET/RES/RL*/RR*/SLA/SRA/SLL/SRL).
  • Block I/O instruction flags (full deterministic rules per Sean Young §4.3 — currently approximate).
  • DAA's full Z80-specific table (currently uses an 8080-equivalent approximation — will diverge for N=1 cases).
  • Cycle-accurate WAIT̅ and contention timing.

Pin contract (40-pin DIP)

Group Pins Dir
Address bus A0..A15 out
Data bus D0..D7 I/O
Memory ctrl MREQ̅, RD̅, WR̅, RFSH̅ out
I/O ctrl IORQ̅ out
Cycle marker M1̅ out
CPU state HALT̅ out
Wait/sync WAIT̅ in
Interrupts INT̅, NMI̅ in
Bus arb BUSREQ̅, BUSACK̅ I/O
System CLK, RESET̅ in
Power VCC, GND power

Total: 16 + 8 + 4 + 1 + 1 + 1 + 1 + 2 + 2 + 2 + 2 = 40 pins — all 40 of the real DIP. No power simplification needed (single 5 V rail).

Bus cycle reference

The Z80's bus is closer to "what you'd design today" than the 8080's:

M1 (opcode fetch):
  T1: drive A0..A15, assert M1̅, MREQ̅ then RD̅
  T2: sample D0..D7
  T3: deassert RD̅, MREQ̅; assert RFSH̅; drive A0..A6 with R register
  T4: deassert RFSH̅
  
Memory read (non-M1):
  T1: drive A0..A15, assert MREQ̅
  T2: assert RD̅, sample D0..D7
  T3: deassert RD̅, MREQ̅
  
Memory write:
  T1: drive A0..A15, MREQ̅
  T2: drive D0..D7, assert WR̅
  T3: deassert WR̅, MREQ̅
  
I/O read/write:
  Like memory but with IORQ̅ instead of MREQ̅.

We faithfully drive M1̅ and RFSH̅ so dynamic-RAM-style wiring works in user demos.

Why the Z80 is the high-value target

  • Recognisable. ZX Spectrum, MSX, GameBoy CPU (modified Z80), CP/M machines, MAME arcade boards. Users will try to wire one.
  • Best documented. The full instruction set, including undocumented flags, has been reverse-engineered.
  • Best reference emulator. floooh/chips/z80.h is single-header, cycle-accurate, MIT-licensed.

Implementation plan

  1. Spike: LD A, n, OUT (n), A, JR n, HALT only. Drive an LED from a memory-mapped port. Confirms the bus state machine works.
  2. Port floooh/chips/z80.h into z80.c as the decoder core. Adapt the bus interface from "callback function" style to "drive velxio pins" style.
  3. Run ZEXDOC / ZEXALL — the canonical Z80 documented/all-flags self tests. These boot CP/M-style and print results to a UART.
  4. Add INT/NMI handling. Implement IM 0 / IM 1 / IM 2.
  5. Stretch: hook a ZX Spectrum ROM and a 16K RAM chip; see if the Spectrum boot screen renders. (Display would be a separate chip.)

Target demo sketch

Same as 8080 (UART hello world) so we can compare the two chips side-by-side on the canvas. Then a Z80-only second demo using the shadow registers (EXX) — something the 8080 cannot do — to show the Z80's expanded ISA.

Files to create later

  • z80.chip.json
  • z80.c (likely split into z80_core.c + z80_decode.c if the ported decoder is large)
  • vendor/ for any vendored MIT-licensed reference code (or move to wokwi-libs/cpu-cores/ per the open question in ../autosearch/05_open_questions.md)
  • roms/zexdoc.bin, roms/hello.bin
  • z80.test.ts