autosearch: Intel 4004/4040 spec + reference impls
Authoritative spec docs cite Intel MCS-4 (Feb 1973) and MCS-40 (Nov 1974) manuals page-by-page. Reference-implementations doc surveys four permissively-licensed open-source emulators (markablov/i40xx, Kostu96/K4004, lpg2709/emulator-Intel-4004, alshapton/Pyntel4004) for cross-validation, explicitly excluding GPL sources (MAME mcs40, carlini/intel-4004-in-4004-bytes-of-c). Critical findings: - 4040 interrupt vector is fixed at PC=0x003 (no vector table). - New 4040 instructions all live at OPR=0000, OPA=0x01..0x0E. - 4004 DAA (opcode 0xFB) is single-nibble, very different from 8080. - 4040 STP/STPA/INTA pin names per datasheet (not STOP/STOPACK). - R16..R23 are not directly named — they're Bank-1 R0..R7 via SB0/SB1. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
e493304cd6
commit
fd93c703c6
|
|
@ -0,0 +1,112 @@
|
|||
# Intel 4004 Authoritative Specification
|
||||
|
||||
Sources (in `autosearch/pdfs/`):
|
||||
|
||||
- **[M4]** *MCS-4 Micro Computer Set Users Manual*, Intel, **Feb 1973** (175 pp). Page numbers below are the printed body footers.
|
||||
- **[M40]** *MCS-40 User's Manual*, Intel, Nov 1974 — Ch. 1 also describes the 4004; used as cross-check.
|
||||
- **[I]** olbits MCS-4 instruction reference (e4004.szyc.org/iset.html) — used only to cross-check opcode hex against [M4] Table V.
|
||||
|
||||
---
|
||||
|
||||
## 1. Pin contract — 16-pin DIP ([M4] §III, pp. 7–9; supplies p. 102)
|
||||
|
||||
The 4004 (Nov 1971) is the first commercial single-chip microprocessor. PMOS, two-phase dynamic clock; **Vss = GND, Vdd = −15 V ±5%**. Logic 1 = low (negative) voltage; logic 0 = Vss ([M4] p. 6).
|
||||
|
||||
| Pin | Name | Dir |
|
||||
|---|---|---|
|
||||
| 1–4 | D0..D3 | I/O — multiplexed 4-bit data/address bus (D3 = MSB) |
|
||||
| 5 | Vss | GND |
|
||||
| 6, 7 | Φ1, Φ2 | In — non-overlapping clocks |
|
||||
| 8 | SYNC | Out |
|
||||
| 9 | RESET | In |
|
||||
| 10 | TEST | In |
|
||||
| 11 | CM-ROM | Out |
|
||||
| 12 | Vdd | −15 V |
|
||||
| 13–16 | CM-RAM3..CM-RAM0 | Out (CM-RAM0 = pin 16) |
|
||||
|
||||
[M4] p. 14 confirms pin 9 = RESET, pin 10 = TEST. CM-RAM0 auto-selected after RESET ([M4] pp. 6, 14).
|
||||
|
||||
## 2. The 8-phase instruction cycle ([M4] Fig. 2 p. 6, text pp. 5–6)
|
||||
|
||||
One cycle = **8 clock periods** = 10.8 µs at 750 kHz. Phases in order: **A1, A2, A3, M1, M2, X1, X2, X3**. Verbatim p. 5: *"the CPU sends 12 bits of address (in three 4-bit bytes on the data bus) … in the first three cycles (A1, A2, A3). … The selected ROM chip sends back 8 bits of instruction (OPR, OPA) to the CPU in the next two cycles (M1, M2)."*
|
||||
|
||||
| Phase | Driver | Contents |
|
||||
|---|---|---|
|
||||
| A1 | CPU | PC[3:0] — **low nibble first** (Fig. 2: "Lower 4-bit Address") |
|
||||
| A2 | CPU | PC[7:4] |
|
||||
| A3 | CPU | PC[11:8] (high 4 bits = chip select 1-of-16) |
|
||||
| M1 | ROM | OPR (high nibble of opcode) |
|
||||
| M2 | ROM | OPA (low nibble) |
|
||||
| X1 | CPU | execute (idle on bus for most ops) |
|
||||
| X2 | CPU/ROM | SRC: chip-select addr; I/O read: ROM/RAM drives ACC data |
|
||||
| X3 | CPU | SRC: char addr; otherwise idle |
|
||||
|
||||
Endianness on the bus: **PC low-nibble first**, chip-select last.
|
||||
|
||||
## 3. SYNC ([M4] p. 6, Fig. 2)
|
||||
|
||||
Generated once every 8 clocks; one clock wide; asserted during **phase X3** to mark end-of-cycle / beginning of A1 of the next. 4001/4002 derive their internal phase counters from SYNC + Φ2.
|
||||
|
||||
## 4. CM-ROM / CM-RAM strobes ([M4] pp. 13–14, Fig. 4)
|
||||
|
||||
- **SRC**: at **X2**, CM-ROM and the selected CM-RAMᵢ go true together while the bus carries the 4 high bits of the SRC address (chip select). At **X3** the bus carries char address.
|
||||
- **I/O & RAM instruction (WRM/RDM/WRR/...)**: at **M2** of that instruction's cycle, CM-ROM + selected CM-RAMᵢ are re-asserted so the latched chip executes OPA (which is on the bus at M2) ([M4] p. 14, step 4).
|
||||
|
||||
## 5. Register file ([M4] §III.A pp. 7–10, Tables III–IV)
|
||||
|
||||
- **Program counter & stack**: 4 × 12 bits — one is the live PC, three form the push-down stack ⇒ **3-deep subroutine stack** ([M4] p. 7).
|
||||
- **Index registers**: 16 × 4 bits, also addressable as 8 × 8-bit pairs R0R1…R14R15 ([M4] §III.B.2 p. 12).
|
||||
- **Accumulator** 4 bits + **carry/link** flip-flop CY ([M4] p. 8).
|
||||
- **Command-control register** (3 bits, latched by DCL).
|
||||
|
||||
## 6. Instruction set — 46 opcodes ([M4] Table V pp. 15–16, cross-checked with [I])
|
||||
|
||||
`*` = 2-byte. First byte shown.
|
||||
|
||||
| Opcode | Mnemonic | Notes |
|
||||
|---|---|---|
|
||||
| `00` | NOP | |
|
||||
| `1C` (`10..1F`) | *JCN cccc | + addr byte; in-page branch |
|
||||
| `20,22,…,2E` | *FIM Pn | + imm8 → reg pair |
|
||||
| `21,23,…,2F` | SRC Pn | send pair as RAM/ROM addr at X2/X3 |
|
||||
| `30…3E` | FIN Pn | indirect ROM fetch via P0 |
|
||||
| `31…3F` | JIN Pn | jump to (PC.high : Pn) |
|
||||
| `40..4F` | *JUN | + addr byte; 12-bit jump |
|
||||
| `50..5F` | *JMS | + addr byte; push PC+2; jump |
|
||||
| `60..6F` | INC Rn | |
|
||||
| `70..7F` | *ISZ Rn | + addr; in-page branch if ≠0 |
|
||||
| `80..8F` | ADD Rn | A ← A + Rn + CY |
|
||||
| `90..9F` | SUB Rn | A ← A + ~Rn + ~CY |
|
||||
| `A0..AF` | LD Rn | |
|
||||
| `B0..BF` | XCH Rn | CY unaffected |
|
||||
| `C0..CF` | BBL d | pop; A ← d |
|
||||
| `D0..DF` | LDM d | |
|
||||
| `E0..EF` | I/O+RAM grp | WRM(E0) WMP(E1) WRR(E2) WPM(E3) WR0..3(E4..E7) SBM(E8) RDM(E9) RDR(EA) ADM(EB) RD0..3(EC..EF) |
|
||||
| `F0..FD` | ACC group | CLB(F0) CLC(F1) IAC(F2) CMC(F3) CMA(F4) RAL(F5) RAR(F6) TCC(F7) DAC(F8) TCS(F9) STC(FA) DAA(FB) KBP(FC) DCL(FD); FE/FF unused |
|
||||
|
||||
## 7. JCN condition encoding ([M4] p. 27 + p. 16 footnote (1))
|
||||
|
||||
OPA bits **C1 C2 C3 C4** (D3..D0): C1=1 → invert sense; C2=1 → ACC==0; C3=1 → CY==1; C4=1 → TEST pin == 0 (high voltage, i.e. logic-0). Logic ([M4] p. 28):
|
||||
`JUMP = C1·((ACC=0)·C2 + (CY=1)·C3 + TEST·C4) + ~C1·~(…)`. **Page-wrap exception**: if JCN sits at words 254/255, the taken target lands on the *next* page ([M4] p. 28).
|
||||
|
||||
## 8. JMS / BBL ([M4] §III.B.3 pp. 12–13, Table IV; JMS p. 28)
|
||||
|
||||
JMS is 2 bytes; **the return address pushed = PC+2** ([M4] p. 12 footnote (3)). Push moves PC up one stack level; depth = 3. Verbatim [M4] p. 13: *"If a fourth JMS occurs, the deepest return address (the first one stored) is lost."* BBL pops + ACC ← D.
|
||||
|
||||
## 9. TEST pin ([M4] p. 14 + p. 28)
|
||||
|
||||
Asynchronous; sampled by condition logic only when JCN is being executed. "Jump if test = logic 0" means the pin is at the high (Vss) level — i.e. active-low in conventional polarity.
|
||||
|
||||
## 10. Reset state ([M4] §III.A.5 p. 9)
|
||||
|
||||
Verbatim: *"During reset … all RAM's and static FF's are cleared, and the data bus is set to 0. After reset, program control will start from 0 step and CM-RAM0 is selected. To completely clear all registers and RAM locations in the CPU the reset signal must be applied for at least 8 full instruction cycles (64 clock cycles) … (256 clock cycles for the 4002 RAM)."*
|
||||
|
||||
→ After RESET held ≥ 64 CPU clocks: **PC=0, ACC=0, CY=0, all 16 index regs = 0, all 3 stack words = 0, CM-RAM0 selected, condition FF = 0**.
|
||||
|
||||
---
|
||||
|
||||
## Open questions
|
||||
|
||||
- **SYNC pulse exact polarity / phase boundary** — [M4] Fig. 2 is a poor scan; the pulse sits on X3 but the rising-vs-falling edge isn't recoverable from the OCR. Cross-validate against the 4004.com redrawn schematics.
|
||||
- **CM-ROM during a normal opcode fetch** — [M4] Fig. 4 details only SRC and the I/O instruction; for a plain fetch CM-ROM is asserted A3→M2 in every emulator surveyed but the manual does not say so explicitly.
|
||||
- **What X1 is used for on most instructions** — Table V doesn't tabulate per-phase activity; reference emulators treat X1 as a no-op cycle for fetch+execute.
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
# Intel 4040 — Delta Spec vs 4004
|
||||
|
||||
Source (in `autosearch/pdfs/`):
|
||||
|
||||
- **[M40]** *MCS-40 User's Manual for Logic Designers*, Intel, **Nov 1974**. Page numbers below are the printed Ch. 1 footers ("1‑5", etc.).
|
||||
|
||||
The 4040 (1974) is binary-compatible with the 4004 — the 46 original opcodes execute identically — and adds 14 new opcodes plus interrupt, single-step, extended ROM/register banks ([M40] §1 p. 1‑1, summary p. 1‑22).
|
||||
|
||||
---
|
||||
|
||||
## 1. Pin contract — 24-pin DIP ([M40] Pin Description table pp. 1‑5/1‑6, Fig. 1‑5)
|
||||
|
||||
Vss = GND; Vdd = Vss − 15.0 V ±5%; PMOS, two-phase clock.
|
||||
|
||||
| Pin | Name | Description ([M40] verbatim where quoted) |
|
||||
|---|---|---|
|
||||
| 1–4 | D0..D3 | Bidirectional 4-bit data/address bus |
|
||||
| 5 | STPA | "STOP ACKNOWLEDGE output … open drain" |
|
||||
| 6 | STP | "STOP input … logic 1 causes the processor to enter the STOP mode" |
|
||||
| 7 | INT | "INTERRUPT input signal" |
|
||||
| 8 | INTA | "INTERRUPT ACKNOWLEDGE output … remains active until cleared by the new BRANCH BACK and SRC (BBS) instruction"; open drain |
|
||||
| 9 | Vss | GND (most positive) |
|
||||
| 10, 11 | Φ1, Φ2 | Non-overlapping clocks |
|
||||
| 12 | RESET | "A 1 level … forces the program counter to 0. To completely clear … RESET must be applied for **96 clock cycles (12 machine cycles)**" |
|
||||
| 13 | TEST | sampled by JCN |
|
||||
| 14 | Vdd | Main supply, Vss − 15 V |
|
||||
| 15 | Vdd2 | Output-buffer supply (may be reduced) |
|
||||
| 16 | SYNC | Marks start of instruction cycle |
|
||||
| 17–20 | CM-RAM0..3 | RAM bank select |
|
||||
| 21 | Vdd1 | Timing-circuit supply; "only SYNC will be generated when this pin is the only active Vdd" — standby |
|
||||
| 22 | CM-ROM0 | ROM bank-0 select |
|
||||
| 23 | CM-ROM1 | ROM bank-1 select (NEW vs 4004) |
|
||||
| 24 | CY | "CARRY output buffer … updated at X1"; open drain (NEW) |
|
||||
|
||||
vs the 4004 the 4040 adds: STP, STPA, INT, INTA, a second CM-ROM line, a CY pin, and dual standby supplies. INT/STP/STPA/INTA are active-high logic-1 (negative voltage).
|
||||
|
||||
## 2. New instructions — 14 total ([M40] p. 1‑22 summary)
|
||||
|
||||
All 14 use OPR=`0000` and live in OPA `0001..1110` of the 4004 (NOP `0000 0000` is preserved).
|
||||
|
||||
| Mnemonic | Opcode | Effect |
|
||||
|---|---|---|
|
||||
| HLT | `01` | Halt; HALT and STOP FFs set at X3 |
|
||||
| BBS | `02` | Branch back from interrupt: restore PC, SRC reg, index-bank FF |
|
||||
| LCR | `03` | ACC ← Command Register |
|
||||
| OR4 | `04` | ACC ← ACC OR R4 |
|
||||
| OR5 | `05` | ACC ← ACC OR R5 |
|
||||
| AN6 | `06` | ACC ← ACC AND R6 |
|
||||
| AN7 | `07` | ACC ← ACC AND R7 |
|
||||
| DB0 | `08` | Designate ROM bank 0 (CM-ROM0); takes effect 3 cycles later |
|
||||
| DB1 | `09` | Designate ROM bank 1 (CM-ROM1) |
|
||||
| SB0 | `0A` | Select index-register bank 0 |
|
||||
| SB1 | `0B` | Select index-register bank 1 |
|
||||
| EIN | `0C` | Enable interrupt |
|
||||
| DIN | `0D` | Disable interrupt |
|
||||
| RPM | `0E` | Read program memory (via 4289 device) |
|
||||
|
||||
`0F` is unused. The brief asked about a "JNT" — there is none; "jump on no test" is just JCN with C1=1, C4=1 (same as on 4004).
|
||||
|
||||
## 3. Interrupt sequence ([M40] §"INTERRUPT and STOP Control Logic" pp. 1‑11..1‑13, Fig. 1‑11)
|
||||
|
||||
When INT is sampled high at M2 and EIN is in effect:
|
||||
1. Current instruction completes.
|
||||
2. The next cycle becomes a forced JMS to **page 0, location 3** ([M40] p. 1‑12 verbatim: *"The subroutine address is forced to be page 0, location 3"*) — i.e. PC ← `0x003`. The pre-interrupt PC (NOT incremented) is pushed.
|
||||
3. At **X3** of that cycle the **INTA flip-flop is set** and the INTA pin asserts.
|
||||
4. The index-register bank FF and the SRC register are saved automatically; bank FF resets to 0.
|
||||
5. Handler runs from `0x003`. INTA stays asserted (blocking further interrupts) until the handler executes **BBS**, which pops the stack, restores PC, re-emits the saved SRC at X2/X3 with CM-ROM/CM-RAM at X2 (re-arming the previously selected ROM/RAM), restores the bank FF, and clears INTA.
|
||||
|
||||
There is no vector table — INT always lands at `0x003`.
|
||||
|
||||
## 4. STOP / STOP-ACK protocol ([M40] §"STOP/HALT Mode Operation" pp. 1‑10..1‑11, Fig. 1‑9, 1‑10)
|
||||
|
||||
- STP=1 latched at M2 → internal STOP FF set at X3 → CPU executes NOPs in a loop (clock keeps running) and STPA asserts.
|
||||
- Resume: STP=0 latched at M2 of cycle N → STOP FF reset at X3 → "Normal processor operation resumes at instruction cycle N+1" ([M40] p. 1‑10).
|
||||
- HLT sets STOP and HALT FFs at X3; exit via STP pulse OR INT (Fig. 1‑13 shows INT-exit forcing HALT FF reset, then taking the interrupt at `0x003`).
|
||||
- INT and STP latched together: **STP wins** ([M40] p. 1‑13).
|
||||
|
||||
## 5. Extended index-register file — 24 × 4 bits ([M40] p. 1‑11)
|
||||
|
||||
Three banks of 8 registers (R0..R7):
|
||||
- **Bank 0** (default after RESET, SB0): low 8 registers.
|
||||
- **Bank 1** (SB1): mirror low 8.
|
||||
- **Upper bank R8..R15**: shared, always visible.
|
||||
|
||||
R16..R23 are **not directly named** — they are Bank-1's incarnation of R0..R7. SB0/SB1 FF auto-saved/restored across interrupt.
|
||||
|
||||
## 6. PC stack — 8 × 12 bits = **7-deep** subroutine nesting ([M40] §"Extended Address Register Stack" p. 1‑12; bullet on p. 1‑1)
|
||||
|
||||
One slot holds the live PC, the other 7 are return addresses; on overflow the deepest is lost (same behaviour as 4004).
|
||||
|
||||
## 7. Other deltas
|
||||
|
||||
- **Two CM-ROM lines** (DB0/DB1 select) → 8 K × 8 ROM addressable ([M40] p. 1‑12). DB0/DB1 take effect on the **3rd cycle after execution**, and INT/STOP/HALT are internally inhibited during those 3 cycles ([M40] p. 1‑13).
|
||||
- **CY exposed on pin 24**, updated at X1 ([M40] p. 1‑6).
|
||||
- RESET clears interrupt enable; an EIN must be re-issued before INT is honored ([M40] p. 1‑13).
|
||||
- Cycle time same as 4004: 8 clock periods per machine cycle.
|
||||
|
||||
---
|
||||
|
||||
## Open questions
|
||||
|
||||
- Exact phase relationships of **STPA** and **INTA** open-drain transitions — [M40] Fig. 1‑9 implies STPA goes active the cycle after STP is latched, but the scan is hard to read. Verify against silicon or markablov/i40xx source.
|
||||
- Behaviour when INT arrives during a 2-byte instruction (JMS, FIM, JCN, JUN, ISZ): [M40] says the current instruction "completes" before the forced JMS, but doesn't tabulate the cycle accounting.
|
||||
- Whether DB0/DB1's 3-cycle inhibit also blocks WRR/RDR to the previously-selected bank during the transition — [M40] is silent.
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
# Intel 4004 / 4040 — Permissive Reference Emulators
|
||||
|
||||
License vetting performed against the GitHub `license` field via API on 2026‑04‑29.
|
||||
**Excluded** (GPL/copyleft): MAME `mame/src/devices/cpu/mcs40/mcs40.cpp` (GPL‑2.0+); `carlini/intel-4004-in-4004-bytes-of-c` (GPL‑3.0). The user-suggested `lkesteloot/intel-4004` returns 404 — does not exist.
|
||||
|
||||
## Candidates (all SPDX MIT or equivalent)
|
||||
|
||||
### 1. **markablov/i40xx** — https://github.com/markablov/i40xx
|
||||
- **License**: MIT (verified via API; LICENSE file in `packages/i40xx-emu`).
|
||||
- **Language**: JavaScript (Node, ESM). 18 ★.
|
||||
- **Coverage**: 4004 *and* 4040 in one core.
|
||||
- **Core file**: `packages/i40xx-emu/src/cpu/cpu.js` — **~600 LOC** (19,551 bytes). Pin map in `pins.js` (44 LOC). Companion packages: assembler (`i40xx-asm`), linker, preprocess, an ICE-like UI, and a `pi-digits` program demo.
|
||||
- **Tests**: `i40xx-program-pi-digits` package serves as integration smoke test (computes π via the 4040). No Busicom 141‑PF in-repo.
|
||||
|
||||
### 2. **Kostu96/K4004** — https://github.com/Kostu96/K4004
|
||||
- **License**: MIT (root LICENSE).
|
||||
- **Language**: C++17. 4 ★.
|
||||
- **Coverage**: separate `K4004.cpp`/`K4040.cpp` cores with a shared `instructions.cpp`.
|
||||
- **Core LOC**: K4004.cpp 3,654 B (~140 LOC), K4040.cpp 2,956 B, instructions.cpp 7,593 B (~280 LOC).
|
||||
- **Tests**: `emulator_core/tests/instructions_tests.cpp` (11.7 KB of GoogleTest cases). **Includes Busicom 141‑PF**: `programs/busicom/busicom_141-PF.obj` (3,846 B object) + 122 KB disassembly. Note `programs/busicom/LICENSE.md` carries its own (Busicom-firmware) license — separate from the emulator's MIT.
|
||||
- **Verdict**: best single repo to cross-validate against — has both cores and Busicom.
|
||||
|
||||
### 3. **lpg2709/emulator-Intel-4004** — https://github.com/lpg2709/emulator-Intel-4004
|
||||
- **License**: MIT. 67 ★.
|
||||
- **Language**: C99, single-file core `src/4004_chip.c` (9,762 B, ~360 LOC) + `4004_chip.h`. Built-in disassembler/assembler.
|
||||
- **Tests**: dedicated `test/` dir; ROMs in `roms/`. Uses Zig build (`build.zig`). No 4040.
|
||||
|
||||
### 4. **alshapton/Pyntel4004** — https://github.com/alshapton/Pyntel4004
|
||||
- **License**: MIT. Python. Has docs site (pyntel4004.readthedocs.io) and a `test/` dir.
|
||||
- **Coverage**: 4004 only. Useful as a *spec-style* reference because each opcode is its own well-commented Python file.
|
||||
|
||||
### 5. **markablov/js-4004** — duplicate redirect of i40xx (same repo metadata returned).
|
||||
|
||||
## Tricky points — cross-checked against [M4]/[M40] and the implementations above
|
||||
|
||||
**(α) JMS/JUN encoding** — `0101 AAAA` `AAAA AAAA` for JMS, `0100 AAAA` `AAAA AAAA` for JUN. The **high 4 bits of the 12-bit target are in the LOW nibble of the first byte (the OPA)**, the low 8 bits are the second byte. **Confirmed** by [M4] Table V p. 16 (OPA = `A3 A3 A3 A3` followed by `A2 A2 A2 A2 A1 A1 A1 A1`) and by `i40xx/cpu.js` and `K4004/instructions.cpp`. No disagreement.
|
||||
|
||||
**(β) FIM encoding** — `0010 RRR0` + 1 immediate byte → 8‑bit immediate to register pair P (RRR encodes one of 8 pairs; LSB=0 distinguishes from SRC `0010 RRR1`). **Confirmed** by [M4] Table V p. 16. So FIM P0 = 0x20, FIM P1 = 0x22, … FIM P7 = 0x2E.
|
||||
|
||||
**(γ) ADD with carry** — [M4] p. 25 verbatim: *"(RRRR) + (ACC) + (CY) → ACC, CY"*. CY is an input. After the op CY = 1 if `sum > 15`. Index register unchanged. Implementations agree. SUB is `~Rn + ACC + ~CY` (one's-complement form per [M4] p. 26) — i.e. CY=0 means borrow-in, CY=1 means no borrow-in; on result, CY=0 = borrow generated, CY=1 = no borrow. Note this is **inverted** vs 8080 borrow polarity — emulator authors get this wrong frequently.
|
||||
|
||||
**(δ) DAA** — opcode **`1111 1011` = 0xFB** ([M4] p. 31, [I] cross-check). Verbatim: *"The accumulator is incremented by 6 if either the carry/link is 1 or if the accumulator content is greater than 9. The carry/link is set to a 1 if the result generates a carry, otherwise it is unaffected."* This **differs from 8080's DAA** in two ways: (i) it acts on a single 4-bit nibble (no high/low nibble split), so there's no auxiliary-carry concept; (ii) **CY is sticky** — only set, never cleared (8080's also has this property, but only after step 2). No half-carry flag exists.
|
||||
|
||||
## Recommendation
|
||||
|
||||
For Velxio, port the instruction-decode skeleton from **markablov/i40xx** (single core covers both chips, MIT, smallest to read) and validate cycle-accurate behaviour against **Kostu96/K4004**'s Busicom 141‑PF run — that's the canonical Intel 4004 acceptance test (the chip was originally built for it).
|
||||
|
||||
## Open questions
|
||||
|
||||
- Has **anyone** published a cycle-by-cycle JCN/ISZ trace test? Neither i40xx nor K4004 ships one. Would have to be derived from [M4] §VII descriptions.
|
||||
- Whether `K4004`'s 4040 implements the **3-cycle DB0/DB1 inhibit window** correctly — needs source inspection.
|
||||
- Pyntel4004 imports `pyntel4004` from PyPI; its tests cover instruction decode but not pin-level timing.
|
||||
Loading…
Reference in New Issue