このサイトは、只今WEB業界で活躍中のデザイナー、プログラマーの方々の情報を集めたweb統合情報サイトです。

Archives Details

Rustで創る MOS 6502 CPU その3 (Cursorと共に)

Rust

2025.02.24

どもです。

去年書いていた「

Rustで創る MOS 6502 CPU その2

 

」の続きとなります。

まぁ、間が空きすぎてのでどこまでやっていたかもあやふやだったのですが、確かopcodeも途中だったはず。

ということで、今回はopcodeを最後まで書いて行きたいのですが、手書きで書いていくのもしんどくなって来ました。と、言うのも最近では専らAI駆動開発を行っているということもあり、大枠などは大抵AIに作成してもらっている今日此の頃です。

いやぁ、楽ですね。あんまり考えなくなるのではないかと心配ではありますが、まぁあとから直せば良いかとAIさんにお任せしております。

そこで、今回から「Cursor – The AI Code Editor」のcomposerで指示を与えながら作成していこうではないと言うことで、このシリーズの再開を行いたいなと(ちょっと飽きて来たのもあって早く終わらせたいなんてことは全然思っていません。。)。

ということで、早速、こちらのドキュメントを「obelisk-6502-guide」をCursorさんの方に喰わせて、シンボリック機能を用いてcomposerで指示をしていきます。

@nes6502 を参考にして、
cpuのopcode0x01から続きを作成してください。

すると、

6502プロセッサのオペコードを実装していきましょう。まず、0x01の次のオペコードを追加します。

とのこと。

どかどか追加していってくれます。

また、

また、ASLの実装を修正する必要があります。現在の実装では結果を常にアキュムレータに格納していますが、メモリアドレスに書き込む場合もあるため、値を返すように変更します:

とのことで、

asl命令あたりも修正が入ります。「お、おうよ。」

これらの変更により、以下のオペコードが実装されました:
0x05: ORA Zero Page - ゼロページアドレスのメモリの値とアキュムレータのORを実行
0x06: ASL Zero Page - ゼロページアドレスのメモリの値を左シフト
0x08: PHP - プロセッサステータスをスタックにプッシュ
0x0A: ASL Accumulator - アキュムレータの値を左シフト
0x0D: ORA Absolute - 絶対アドレスのメモリの値とアキュムレータのORを実行
続けて他のオペコードも実装していきましょうか?

と一瞬で作成してくれる。

いやぁ。楽だ。しかし頭に入っていないなぁ(各オペコードを覚えようと思っていたので)

とはいえ非常に楽なので「続けてopcodeを作成してください」と入力し残りのopcodeを作成してもらう。

まず、StatusRegisterにas_byteメソッドが必要なのでそれを追加し、その後新しいオペコードを実装していきましょう。
また、StatusRegister構造体にas_byteメソッドを追加する必要があります。register.rsファイルに以下のコードを追加してください:
impl StatusRegister {
    pub fn as_byte(&self) -> u8 {
        let mut result = 0u8;
        if self.c { result |= 0b0000_0001; }
        if self.z { result |= 0b0000_0010; }
        if self.i { result |= 0b0000_0100; }
        if self.d { result |= 0b0000_1000; }
        if self.b { result |= 0b0001_0000; }
        // bit 5は常に1
        result |= 0b0010_0000;
        if self.v { result |= 0b0100_0000; }
        if self.n { result |= 0b1000_0000; }
        result
    }
}

と、こちらが追加されました。

追加したオペコードの説明:
0x0E: ASL Absolute - 絶対アドレスのメモリの値を左シフト
0x10: BPL - N(負)フラグがクリアされている場合に分岐
0x11: ORA Indirect,Y - インデックス付き間接アドレスのメモリの値とアキュムレータのOR
0x15: ORA Zero Page,X - Xレジスタでオフセットされたゼロページアドレスのメモリの値とアキュムレータのOR
0x16: ASL Zero Page,X - Xレジスタでオフセットされたゼロページアドレスのメモリの値を左シフト
0x18: CLC - キャリーフラグをクリア
0x19: ORA Absolute,Y - Yレジスタでオフセットされた絶対アドレスのメモリの値とアキュムレータのOR
続けて他のオペコードも実装しましょうか?

ふむふむ。「続けてopcodeを作成してください」を繰り返す。

はい、続けてオペコードを実装していきます。
また、StatusRegisterにfrom_byteメソッドを追加する必要があります:と

とのことで、

pub fn from_byte(byte: u8) -> Self {
    StatusRegister {
        c: (byte & 0b0000_0001) != 0,
        z: (byte & 0b0000_0010) != 0,
        i: (byte & 0b0000_0100) != 0,
        d: (byte & 0b0000_1000) != 0,
        b: (byte & 0b0001_0000) != 0,
        // bit 5は無視
        v: (byte & 0b0100_0000) != 0,
        n: (byte & 0b1000_0000) != 0,
    }
}

こちらが追加される。

追加したオペコードの説明:
0x1D: ORA Absolute,X - Xレジスタでオフセットされた絶対アドレスのメモリの値とアキュムレータのOR
0x1E: ASL Absolute,X - Xレジスタでオフセットされた絶対アドレスのメモリの値を左シフト
0x20: JSR - サブルーチンにジャンプ(戻りアドレスをスタックに保存)
0x21: AND Indirect,X - インデックス付き間接アドレスのメモリの値とアキュムレータのAND
0x24: BIT Zero Page - ゼロページアドレスのメモリの値とアキュムレータのビットテスト
0x25: AND Zero Page - ゼロページアドレスのメモリの値とアキュムレータのAND
0x28: PLP - スタックからプロセッサステータスを復元
0x29: AND Immediate - 即値とアキュムレータのAND
続けて他のオペコードも実装しましょうか?

ふむふむ。「続けてopcodeを作成してください」を繰り返す。

はい、続けてオペコードを実装していきます。
また、rol命令の実装を修正する必要があります。現在の実装では結果を常にアキュムレータに格納していますが、メモリアドレスに書き込む場合もあるため、値を返すように変更します:

ROLが修正される

fn rol(&mut self, value: u8) -> u8 {
    let old_carry = self.status.c;
    self.status.c = (value & 0x80) != 0;
    let result = (value << 1) | (old_carry as u8);
    self.status.z = result == 0;
    self.status.n = (result & 0x80) != 0;
    result
}

そして

追加したオペコードの説明:
0x2A: ROL A - アキュムレータを左ローテート
0x2C: BIT Absolute - 絶対アドレスのメモリの値とアキュムレータのビットテスト
0x2D: AND Absolute - 絶対アドレスのメモリの値とアキュムレータのAND
0x30: BMI - N(負)フラグがセットされている場合に分岐
0x31: AND Indirect,Y - インデックス付き間接アドレスのメモリの値とアキュムレータのAND
0x35: AND Zero Page,X - Xレジスタでオフセットされたゼロページアドレスのメモリの値とアキュムレータのAND
0x36: ROL Zero Page,X - Xレジスタでオフセットされたゼロページアドレスのメモリの値を左ローテート
0x38: SEC - キャリーフラグをセット
0x39: AND Absolute,Y - Yレジスタでオフセットされた絶対アドレスのメモリの値とアキュムレータのAND
続けて他のオペコードも実装しましょうか?

繰り返すのが面倒なので、「残りのオペコードすべて作成してください」とする。

すると、

はい、リンターエラーを修正しながら、残りのオペコードを実装していきます。まず、lsrとrorの実装を修正し、戻り値を返すように変更します:
これで6502プロセッサの主要なオペコードがすべて実装されました。各命令の実装は以下のような特徴を持っています:
メモリアドレッシングモードに応じた適切なアドレス計算
フラグの適切な設定
レジスタやメモリの更新
プログラムカウンタの適切な更新
これらの実装により、6502プロセッサの基本的な命令セットが完成しました。

おお。まじかよ。

取り敢えず徐ろに、cargo runで起動するか確かめる。

CPU { a: 0, x: 0, y: 0, pc: 0, sp: 255, status: StatusRegister { c: false, z: false, i: false, d: false, b: false, v: false, n: false } }

エラーなく、いっちゃっているな。ほぼ、「続けてopcodeを作成してください」

しか言っていないのに作成されてしまった。いやぁ楽だ。

■ 今回の追加コミット

https://github.com/retrodig/mos6502r/commit/4414fce6cb87a81619b223edfe35412dd80e774a

この快適さを知ってしまうともう抜け出せない。。。

次回からもCursor様といっしょに制作を進めていきます。

ではではぁ。

 

 

 

Comment

Related Article

Rustでつくる ふっかつのじゅもん

2025.04.29

Tauri(Rust) × AI で作る GitGUIクライアントアプリ その5

2025.04.14

Tauri(Rust) × AI で作る GitGUIクライアントアプリ その4

2025.04.10

Tauri(Rust) × AI で作る GitGUIクライアントアプリ その3

2025.04.08

Tauri(Rust) × AI で作る GitGUIクライアントアプリ その2

2025.04.07

Tauri(Rust) × AI で作る GitGUIクライアントアプリ その1

2025.04.05

keyring-rsで、Macのキーチェーンに登録する。

2025.04.04

RustとWebAssemblyによるゲーム開発 Webpack5対応

2025.03.27

Rustで創る MOS 6502 CPU その3 (Cursorと共に)

2025.02.24

Rust-SDL2 examplesをすべて試す

2024.09.01

CATEGORY LIST

LATEST NEWS

Rustでつくる ふっかつのじゅもん

Rust

2025.04.29

Tauri(Rust) × AI で作る GitGUIクライアントアプリ その5

Rust

2025.04.14

う、動くぞ! Mac mini Apple M4 Pro で PS3ソフトを遊ぶ。RPCS3 Mac版を起動

Game

2025.04.12

Tauri(Rust) × AI で作る GitGUIクライアントアプリ その4

Rust

2025.04.10

Tauri(Rust) × AI で作る GitGUIクライアントアプリ その3

Rust

2025.04.08

Tauri(Rust) × AI で作る GitGUIクライアントアプリ その2

Rust

2025.04.07

時代を先取りし過ぎた ニューラルネットワークが導入されたゲーム『がんばれ森川君2号』を令和に嗜んでみる。

Game

2025.04.06

Tauri(Rust) × AI で作る GitGUIクライアントアプリ その1

Rust

2025.04.05

keyring-rsで、Macのキーチェーンに登録する。

Rust

2025.04.04

RustとWebAssemblyによるゲーム開発 Webpack5対応

Rust

2025.03.27

Rustで創る MOS 6502 CPU その3 (Cursorと共に)

Rust

2025.02.24

あけましておめでとうございます(24日経過)

イベント

2025.01.24

RANKING

Follow

SPONSOR

現在、掲載募集中です。



Links

About Us

WEBデザイナーの、WEBデザイナーによる、WEBデザイナーの為のサイト。「みんなで書こう!」と仲間を募ってみたが、結局書くのは自分だけとなってしまいました。日々のメモを綴っていきます。

Entry Profile

Graphical FrontEnd Engineer
- Daisuke Takayama

MAD CITY 北九州市で生まれ育つ。20代はバンド活動に明け暮れ、ふと「webデザイナーになりたい。」と思い、デジタルハリウッド福岡校入学。卒業後、数々の賞を受賞、web業界をざわつかせる。
現在、主に、ゲーム制作中心に港区六本木界隈で活動中。

FOLLOW US