📚

Rustで世界初のCPU「4004」エミュレータ #調査記録📚

2024/10/17に公開

はじめに

◆👇前回オリジナルCPUを設計してRustでエミュレートするまで投稿しました🥳
https://zenn.dev/chimipupu/articles/e0af6451e0cab9

👇GitHub世界初(1971年)のCPU Intel 4004のエミュレータを開発中で色々と調査中なので随時、共有していきます🥳

https://github.com/Chimipupu/cpu_4004_rs_emu

Rust

前回と同じ方法で実装!
https://zenn.dev/chimipupu/articles/e0af6451e0cab9

4004構造体

4004のCPUの構成はこんな構造体で定義して正解かな❓💁‍♀️

// intel 4004 の構造体
pub struct i4004 {
    acc: u8,             // アキュムレータACC
    idx_reg: [u8; 8],    // インデックスレジスタ (8ビット x 8ペア)
    pub pc: u16,         // プログラムカウンタ (12ビット)
    pub sp: [u16; 3],    // スタックポインタ (12ビット x 3レベル)
    pub carry_flg: bool, // キャリーフラグ
    pub memory: Memory,  // メモリ(ROM, RAM 4KB)
}

命令セットはビットマスク必須?

4004の命令セットは下位4bitにデータ上位にRPとかでビットマスクが必須かも🦆❓

[👇例)FIM、LDM命令のビットマスク]

// ビットマスク
const OP_FIM_MASK: u8       = 0b00101110;    // FIM [0b0010(3bit RP) 0][8ビット…データ]
const OP_FIM_RP_MASK: u8    = 0b00001110;    // FIM RP部マスク
const OP_LDM_MASK: u8       = 0b11011111;    // LDM [0b1101][下位4bitデータ]
const OP_LDM_DATA_MASK: u8  = 0b00001111;    // LDM データ部マスク

const OP_FIM: u8 = OP_FIM_MASK; // FIM 即値 -> レジスタ
const OP_LDM: u8 = OP_LDM_MASK; // LDM: 即値 -> ACC

// 🌟途中の記載は省略

    fn execute(&mut self, opcode: u8) -> bool {
        let mut result = true;

        match opcode {
            OP_FIM => {
                let val: u8 = self.fetch();
                let rp: u8 = (self.refetch() & OP_FIM_RP_MASK) >> 1;
                self.idx_reg[rp as usize] = val;
                println!("FIM {} (R{} <- {})", val, rp, val);
            }
            OP_LDM => {
                let val: u8 = self.refetch() & OP_LDM_DATA_MASK;
                self.acc = val;
                println!("LDM {}", val);
            }

// ここから下👇は省略

Intel 4004

インテルが1971年に発売した世界初のCPUIntel 4004

リファレンス

📍Intel 4004は下記Intelの文献をリファレンスにしています💁‍♀️

📚[Intel 4004 データシート]

📚[MCS4 Assembly Language Programming Manual]

仕様

  • バス幅: 4bit
  • クロック: 740kHz
  • 命令セット: 46
  • パッケージ: 16Pin DIP
  • ACC(アキュムレータ): 4bit
  • フラグ: キャリーフラグのみ
  • インデックスレジスタ
    • 4bit x16の個別
      • R0〜R15
    • 8bit x8のペア
      • R0P ~R7P
  • SP: 12bit x3レベル(ネスト3段まで)
  • PC: 12bit
  • ROM: 最大 32768 bit (4096 Byte)
  • RAM:
    • プログラムRAM: 最大 32768 bit (4096 Byte)
    • データRAM: 最大 5120 bit (640 Byte)

命令セット

一覧

No. Category Instruction Description (英語 / 日本語)
1 INDEX REGISTER INSTRUCTIONS INC Increment index register / インデックスレジスタをインクリメント
2 INDEX REGISTER INSTRUCTIONS FIN Finish operation / 操作を終了する
3 INDEX REGISTER TO ACCUMULATOR INSTRUCTIONS ADD Add index register to accumulator / インデックスレジスタをアキュムレータに加算
4 INDEX REGISTER TO ACCUMULATOR INSTRUCTIONS SUB Subtract index register from accumulator / アキュムレータからインデックスレジスタを減算
5 INDEX REGISTER TO ACCUMULATOR INSTRUCTIONS LD Load index register to accumulator / インデックスレジスタをアキュムレータにロード
6 INDEX REGISTER TO ACCUMULATOR INSTRUCTIONS XCH Exchange index register with accumulator / インデックスレジスタとアキュムレータを交換
7 ACCUMULATOR INSTRUCTIONS CLB Clear accumulator / アキュムレータをクリア
8 ACCUMULATOR INSTRUCTIONS CLC Clear carry / キャリーをクリア
9 ACCUMULATOR INSTRUCTIONS IAC Increment accumulator / アキュムレータをインクリメント
10 ACCUMULATOR INSTRUCTIONS CMC Complement carry / キャリーを補完
11 ACCUMULATOR INSTRUCTIONS CMA Complement accumulator / アキュムレータを補完
12 ACCUMULATOR INSTRUCTIONS RAL Rotate accumulator left / アキュムレータを左にローテート
13 ACCUMULATOR INSTRUCTIONS RAR Rotate accumulator right / アキュムレータを右にローテート
14 ACCUMULATOR INSTRUCTIONS TCC Transfer carry to accumulator / キャリーをアキュムレータに転送
15 ACCUMULATOR INSTRUCTIONS DAC Decrement accumulator / アキュムレータをデクリメント
16 ACCUMULATOR INSTRUCTIONS TCS Transfer accumulator to carry / アキュムレータをキャリーに転送
17 ACCUMULATOR INSTRUCTIONS STC Set carry / キャリーをセット
18 ACCUMULATOR INSTRUCTIONS DAA Decimal adjust accumulator / アキュムレータを十進法で調整
19 ACCUMULATOR INSTRUCTIONS KBP Keyboard process / キーボードプロセス
20 IMMEDIATE INSTRUCTIONS FIM Fetch immediate / 即時取得
21 IMMEDIATE INSTRUCTIONS LDM Load accumulator immediate / アキュムレータを即時にロード
22 TRANSFER OF CONTROL INSTRUCTIONS JUN Jump unconditionally / 条件なしジャンプ
23 TRANSFER OF CONTROL INSTRUCTIONS JIN Jump indirect / 間接ジャンプ
24 TRANSFER OF CONTROL INSTRUCTIONS JCN Jump on condition / 条件付きジャンプ
25 TRANSFER OF CONTROL INSTRUCTIONS ISZ Increment and skip if zero / ゼロの場合はインクリメントしてスキップ
26 SUBROUTINE LINKAGE INSTRUCTIONS JMS Jump to subroutine / サブルーチンへジャンプ
27 SUBROUTINE LINKAGE INSTRUCTIONS BBL Branch back and load / ブランチバックしてロード
28 NOP NOP No operation / ノーオペレーション
29 MEMORY SELECTION INSTRUCTIONS DCL Designate command line / コマンドラインを指定
30 MEMORY SELECTION INSTRUCTIONS SRC Send register control / レジスタコントロールを送信
31 I/O AND RAM INSTRUCTIONS WRM Write data RAM character / データRAM文字を書き込む
32 I/O AND RAM INSTRUCTIONS WMP Write RAM port / RAMポートに書き込む
33 I/O AND RAM INSTRUCTIONS WRR Write ROM port / ROMポートに書き込む
34 I/O AND RAM INSTRUCTIONS WPM Write program RAM / プログラムRAMに書き込む
35~38 I/O AND RAM INSTRUCTIONS WR[0:3] Write data RAM status character / データRAMステータス文字を書き込む
39 I/O AND RAM INSTRUCTIONS RDM Read data RAM data character / データRAMデータ文字を読み込む
40 I/O AND RAM INSTRUCTIONS RDR Read ROM port / ROMポートを読み込む
41~44 I/O AND RAM INSTRUCTIONS RD[0:3] Read data RAM status character / データRAMステータス文字を読み込む
45 I/O AND RAM INSTRUCTIONS ADM Add data RAM to accumulator with carry / キャリーを伴ってデータRAMをアキュムレータに加算
46 I/O AND RAM INSTRUCTIONS SBM Subtract data RAM from memory with borrow / メモリからデータRAMを減算

INDEX REGISTER INSTRUCTIONS

INC

FIN

INDEX REGISTER TO ACCUMULATOR INSTRUCTIONS

ADD

SUB

LD

XCH

ACCUMULATOR INSTRUCTIONS

CLB

CLC

IAC

CMC

CMA

RAL

RAR

TCC

DAC

TCS

STC

STC (SET CARRY)

DAA

DAA (DECIMAL ADJUST ACCUMULATOR)

KBP

KBP (KEYBOARD PROCESS)

IMMEDIATE INSTRUCTIONS

FIM

FIM (FETCH IMMEDIATE)

LDM

LDM(LOAD ACCUMULATOR IMMEDIATE)

TRANSFER OF CONTROL INSTRUCTIONS

JUN

JUN (JUMP UNCONDITIONALLY)

JIN

JIN(JUMP INDIRECT)

JCN

JCN(JUMP ON CONDITION)


ISZ

ISZ(INCREMENT AND SKIP IF ZERO)

SUBROUTINE LINKAGE INSTRUCTIONS

JMS

JMS(JUMP TO SUBROUTINE)

BBL

BBL(BRANCH BACK AND LOAD)

NOP

MEMORY SELECTION INSTRUCTIONS

DCL

DCL(DESIGNATE COMMAND LINE)

SRC

SRC(SEND REGISTER CONTROL)

I/O AND RAM INSTRUCTIONS

WRM

WRM(WRITE DATA RAM CHARACTER)

WMP

WMP(WRITE RAM PORT)

WRR

WRR(WRITE ROM PORT)

WPM

WPM(WRITE P ROG RAM RAM)

WRn

WRn(WRITE DATA RAM STATUS CHARACTER)

RDM

RDM(READ DATA RAM DATA CHARACTER)

RDR

RDR(READ ROM PORT)

RDn

RDn(READ DATA RAM STATUS CHARACTER)

ADM

ADM(ADD DATA RAM TO ACCUMULATOR WITH CARRY)

SBM

SBM(SUBTRACT DATA RAM FROM MEMORY WITH BORROV\T)

参考文献

📚[Intel 4004 データシート]

📚[MCS4 Assembly Language Programming Manual]

📚[Detailed Instruction Repertoire of the MCS-4]

🎦動画[NHKスペシャル 電子立国 日本の自叙伝 第5回 8ミリ角のコンピュータ]

📚嶋正利さん著書「マイクロコンピュータの誕生:わが青春の4004」

📚嶋正利さん[マイクロプロセッサ 4004の開発]

📚[Intel公式4004関連]

📚日経[電卓向けの性格を色濃く残す、4004のアーキテクチャー]

Discussion