Commit Graph

7 Commits

Author SHA1 Message Date
David Montero 1aa9fb872c test_intel: phase D-3 + todo cleanup — 125/126 passing
Convert 7 outstanding it.todo markers into actual passing tests now
that the chips and bus infrastructure can support them:

  - 4004 LDM: ACC observed via SRC + WMP X2 bus drive
  - 4004 FIM: register pair observed via SRC X2/X3 nibble drives
  - 8080 hand-built loop: LXI/MVI/INR/DCR/JNZ decrements counter
  - Z80 IM 2: vector table at I:00 → ISR via INT̅ low
  - 8086 1 MB wrap: DS=0xFFFF + offset 0x11 lands at physical 0x00001
  - 8086 ALE pulse: counts ALE rising edges per bus cycle
  - 8086 AD release: external drive sticks during T2 (chip released)
  - 8086 hello-world: 5 MOV BYTE [imm], imm writes to memory-mapped
    "UART" at DS:0x9000; bus capture + RAM peek verify "Hello"

Plus: remove redundant 8080 CPUDIAG and Z80 ZEXDOC todos — the
actual end-to-end runs already pass in dedicated cpudiag.test.js
and zexdoc.test.js files.

Suite is now 125/126 passing, 1 todo (Busicom 141-PF demo, awaiting
firmware ROM), 0 failed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 03:20:50 +02:00
David Montero 555a4315be test_intel: 8086 + 8259 PIC end-to-end interrupt integration
First test wiring the 8086 CPU to a real 8259 PIC chip on the same
board and proving hardware-interrupt routing works end-to-end:
  IRQ0 input → PIC asserts INT → CPU's INTR pin → CPU runs INTA
  cycle → PIC drives vector 0x40 on AD bus → CPU does do_int(0x40)
  → fetches CS:IP from IVT entry at 0x100 → ISR runs → IRET → main
  resumes from HLT.

Two related chip fixes required to make this work:

1. 8086 INTA cycle no longer drives AD itself.
   Real 8086 INTA bus cycle has the PIC drive the data lines, not
   the CPU. My earlier code did `bus_read_byte(0, false)` which
   first drove AD with addr=0, overwriting whatever the PIC had
   driven. Fix: release_ad → INTA̅ low → sample AD (PIC's INTA
   watcher fires synchronously and drives) → INTA̅ high.

2. 8086 HLT now interruptible.
   on_clock previously early-returned on G.halted, so step()
   never ran and the INTR check never executed. Real 8086 HLT
   wakes on INTR/NMI. Fix: remove the early return; step()'s
   own halted check (later in the function) only no-ops if no
   pending interrupt.

Tests: total test_intel 110 → 111 passing (+1, the integration
test). 0 failed. 11 todo. test_8086 now 11→12 passing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 00:35:09 +02:00
David Montero 7ac17ff2b6 test_intel: fix 8086 MOV r/m,imm encoding (0xC6/0xC7)
Root cause of the deferred CALL/RET test: my chip was missing the
0xC6 / 0xC7 (Group 11 — MOV r/m, imm) opcodes. Bytes like the
test's "MOV byte [0x8002], 0x55" (0xC6 0x06 0x02 0x80 0x55) fell
through to the default NOP, then the chip decoded the residual
0x06 0x02 0x80 0x55 as PUSH ES + ADD r/m + ... taking SP into
unpredictable territory.

Implementation:
- 0xC6 (8-bit) and 0xC7 (16-bit) variants added.
- The encoding is opcode + modrm + disp + imm. Critically the disp
  bytes (consumed by calc_ea) come BEFORE the immediate, so we
  compute EA first, then fetch imm. Earlier draft had imm fetched
  before disp — that had imm winning the disp slot and disp becoming
  the next instruction's bytes. Caught only after wiring CALL+RET.

Tests: 8086 10→11 passing. Total test_intel: 93→94 passing,
0 failed, 11 todo. CALL/RET integration test now active and green.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 20:44:17 +02:00
David Montero d2118b298e test_intel: phase E — 8086 ISA expansion
Adds ~600 LOC to 8086.c bringing the chip from ~50 opcodes to a
near-complete subset of the iAPX 86 ISA:
- Shift/rotate Group 2 (D0..D3) — ROL/ROR/RCL/RCR/SHL/SHR/SAR with
  imm-1 or CL count, full CF + OF + S/Z/P semantics.
- String ops MOVS/CMPS/SCAS/LODS/STOS (byte + word) with REP/REPE/
  REPNE prefix loop; DF-respecting SI/DI advance.
- MUL/IMUL/DIV/IDIV (Group 3 sub-opcodes 4-7) with divide-error halt.
- BCD: DAA/DAS/AAA/AAS/AAM/AAD with manual-canonical algorithms.
- Port I/O: IN/OUT byte+word, immediate or DX-indexed.
- Hardware interrupts: NMI rising → vector 2, INTR + IF → INTA cycle
  reading vector byte from data bus, INT imm8/3, INTO, IRET.
- LDS/LES, LAHF/SAHF, XCHG byte+word, XLAT.
- Group 4 (FE) INC/DEC r/m8 (was missing).
- PUSH/POP segment regs (06/0E/16/1E + 07/17/1F).
- Undocumented: POP CS (0F), SALC (D6).
- TEST r/m,r and TEST AL/AX,imm (84/85/A8/A9 — also missing baseline).

New harness:
- BoardHarness.installFake8086Bus() — full 8086 minimum-mode bus
  responder: ALE-snapshot + RD-drive + WR-latch.
- boot8086() helper in 8086.test.js placing test bytes at physical
  0xF0100 with reset-vector JMP-FAR stub.

Tests: 8086 3→10 passing (+7: MOV imm16, ADD, JMP near, SHL, MUL,
REP MOVSB, segment override). Total test_intel: 86→93 passing,
0 failed, 12 todo.

CALL/RET test deferred to it.todo — chip takes an unintended path
after the CALL push (debug ongoing). Master plan doc updated.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 20:44:17 +02:00
David Montero 323366dc53 test_intel: status docs for completed chip lineup
All 5 retro CPUs (Intel 4004/4040/8080/8086 + Zilog Z80) plus all 3
bus devices (rom-32k, ram-64k, latch-8282) are now implemented.
Update top-level matrix and per-chip READMEs to reflect 63/80 tests
passing, 0 failed, 17 deferred.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 03:59:44 +02:00
David Montero f9906c3ad5 test_intel: Intel 8086 chip (minimum mode baseline)
~750 LOC clean-room from Intel iAPX 86,88 User's Manual (Oct 1979),
cross-validated against 8086tiny (MIT), MartyPC (MIT, hardware-
validated 99.9997% on SingleStepTests 8088 V2), YJDoc2/8086-Emulator
(Apache+MIT). No GPL refs (Fake86, DOSBox, MAME, QEMU all excluded).

Implemented:
- 40-pin minimum-mode contract (AD0..AD15, A16..A19, ALE, RD, WR,
  M/IO, DT/R̅, DEN̅, BHE̅, INTR, NMI, INTA̅, RESET, READY, TEST̅, CLK,
  HOLD, HLDA, MN/MX̅, VCC, GND).
- Reset state per [I86] PDF p.51: CS=0xFFFF, IP=0, all other segs=0,
  flags clear with reserved bits canonicalised. First fetch at the
  physical address 0xFFFF0 with proper ALE strobe.
- Bus cycle T1-T4 (instruction-per-tick collapse): drive AD with low
  16 addr, A with high 4, pulse ALE, switch AD to input, assert RD̅
  (or drive data + WR̅ for writes).
- 20-bit physical addressing: (segment<<4)+offset modulo 1 MB.
- Register file: AX/BX/CX/DX with byte halves (union), SP/BP/SI/DI,
  IP, CS/DS/ES/SS, FLAGS.
- ModR/M decode for memory operands (Table 4-10 effective-address
  formulas with default-segment selection).
- ISA subset: NOP, HLT, MOV reg/imm and r/m forms, MOV sreg, MOV
  AL/AX,[addr]; ADD/OR/ADC/SBB/AND/SUB/XOR/CMP r/m + r and reverse
  + AL/AX-imm forms; Group 1 (immediate ALU); INC/DEC r16; PUSH/POP
  r16; PUSHF/POPF; CLC/STC/CLI/STI/CLD/STD/CMC; conditional short
  jumps Jcc; JMP near/short/far; CALL near/far; RET near/far +imm;
  LOOP/LOOPE/LOOPNE/JCXZ; Group 5 (INC/DEC/CALL/JMP/PUSH r/m16);
  segment-override prefixes.

Deferred (17 it.todo tests across ISA/integration):
- String ops (MOVS/CMPS/SCAS/LODS/STOS) with REP prefix.
- MUL/DIV/IMUL/IDIV.
- BCD adjust (DAA/DAS/AAA/AAS/AAM/AAD).
- Port I/O (IN/OUT).
- Hardware interrupts (NMI/INTR vectoring + INTA cycle).
- Maximum-mode bus protocol.
- Cycle-accurate prefetch queue.

Brings test_intel to 63 passing tests (was 60), 0 failed, 17 todo.
All 6 chips from the original plan (8080, Z80, 4004, 4040, 8086,
plus rom-32k/ram-64k/latch-8282 bus devices) now compiled and
their pin contracts + reset behavior + bus protocols are validated.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 03:58:49 +02:00
David Montero e493304cd6 autosearch — Research notes for Intel + Z80 custom-chip emulation 2026-04-29 22:24:02 +02:00