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

Archives Details

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

Rust

2025.02.24

この記事は最終更新日から1年以上が経過しています。

どもです。

去年書いていた「

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

ゲーム開発に必要な基本数学入門

2025.08.15

Godot 4 & Rust 始め方

2025.06.19

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

CATEGORY LIST

LATEST NEWS

【2026】【VMware Fusion】MacでWindowsを無料で扱う。

windows

2026.07.19

Raspberry Pi 5 でマインクラフトサーバーを立てる(Java版 × 統合版クロスプレイ対応)

RaspberryPi

2026.06.24

ラズパイが高い。

RaspberryPi

2026.05.26

【Claude Code】フル稼働。ToDo Appを様々なGUIフレームワーク用いて作らせる。

AI・Bot・algorithm

2026.05.24

Macで歩く「たのしいバイナリの歩き方」うさみみハリケーンの代わりに、Cheat Engine / Bit slicerを使用する

アセンブラ

2026.04.12

Macで歩く「たのしいバイナリの歩き方」

アセンブラ

2026.04.10

【Railway】ひたすら安く個人開発サービスを運用する計画

サーバー

2026.04.06

たびのきろく

イベント

2026.02.23

【Railway】MySQLサービスをコスト抑えて運用する

運用

2026.01.19

あけましておめでとうございますmm DjangoアプリをRailwayに移行する。

運用

2026.01.06

効率の良い AI駆動開発について考える

AI・Bot・algorithm

2025.11.09

MacとClaude Codeで構築する cc65(NES)開発環境

Game

2025.10.24

RANKING

Follow

SPONSOR

現在、掲載募集中です。



Links

About Us

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

Entry Profile

Graphical FrontEnd Engineer
- Daisuke Takayama

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

FOLLOW US