6502

目次

アーキテクチャ

レジスタ一覧

ファミコンは、6502をベースに音声機能などを同梱したリコー製のカスタムCPUを採用しています。
6502はモステクノロジーの開発したCPUで、モトローラの6800をモデルにレジスタ数を簡素化した非常にシンプルな設計のCPUです。特に演算に使えるレジスタは1つしかありません。
また、インデックスレジスタを含むほとんどのレジスタが8bit幅となっており、256バイト以上のテーブルは割と扱いにくいです。
スタックポインタも8bit幅となっており、スタックとして使われる空間は$0100-$01FF固定となっています。

記号 サイズ 名前 用途
A 8bit アキュームレータ 汎用演算
X 8bit インデックスレジスタ アドレッシング、カウンタなど
Y 8bit インデックスレジスタ アドレッシング、カウンタなど
S 8bit スタックポインタ スタックの位置を保持
P 8bit ステータスレジスタ CPUの各種状態を保持
PC 16bit プログラムカウンタ 実行している位置を保持

ステータスレジスタの詳細

8bitのレジスタで、1ビット毎に違う意味を持っています。それぞれのビットはCPUが命令を進めるごとに自動的に変化しますが、フラグを手動で設定する命令もあります。
それぞれのビットの状態に応じて分岐する命令が用意されています。

位置 記号 名前 内容
7 N ネガティブ Aの7ビット目と同じになります。負数の判定用。
6 V オーバーフロー 演算がオーバーフローを起こした場合セットされます。
5 R 予約済み 使用できません。常にセットされています。
4 B ブレークモード BRK発生時はセットされ、IRQ発生時はクリアされます。
3 D デシマルモード セットすると、BCDモードで動作します。(ファミコンでは未実装)
2 I IRQ禁止 クリアするとIRQが許可され、セットするとIRQが禁止になります。
1 Z ゼロ 演算結果が0になった場合セットされます。ロード命令でも変化します。
0 C キャリー キャリー発生時セットされます。

割り込み

6502の割り込みはRESET、NMI、IRQ、BRKの4種類ですが、IRQとBRKは同じ割り込みベクタを共有しています。その為、割り込みルーチン内でステータスレジスタのBフラグを確認し、IRQなのかBRKなのかを判断する必要があります。

アドレス 名前 発生条件 ステータスレジスタの変化
$FFFA NMI ハードウェアからの特殊信号が入った時。 Iがセット, Bがクリア
$FFFC RESET 電源投入時。リセットボタンの押下時。 Iがセット
$FFFE IRQ/BRK ハードウェアからの信号、もしくはBRK命令時。 Iがセット、Bが変化

アドレッシング

6502はレジスタ数はかなり少ないですが、アドレッシングの種類は比較的豊富です。
通常、6502のアセンブラは、16進数を表記する際は数字の頭に"$"を付けて"$2e"、2進数を表記する際は頭に"%"を付けて、"%00110101"と表記します。
また、下の表記の”IM8”は8bit幅の数値、”IM16”は16bit幅の数値とします。

名称 表記例 動作
Implied TAX AをXにコピー
Accumulator LSR A Aを左に1bitシフト
Immediate LDA #IM8 即値IM8をAにロード
Zeropage LDA IM8 アドレス「IM8」の8bit値をAにロード
Zeropage, X LDA IM8, X アドレス「IM8 + X」の8bit値をAにロード
Zeropage, Y LDA IM8, Y アドレス「IM8 + Y」の8bit値をAにロード
Relative BEQ IM8 ステータスレジスタZがオンの時、アドレス「PC + IM8」へジャンプ
Absolute LDA IM16 アドレス「IM16」の8bit値をAにロード
Absolute, X LDA IM16, X アドレス「IM16 + X」の8bit値をAにロード
Absolute, Y LDA IM16, Y アドレス「IM16 + Y」の8bit値をAにロード
(Indirect) JMP (IM16) アドレス「アドレス「IM16」の16bit値」へジャンプ
(Indirect, X) LDA (IM8, X) アドレス「アドレス「IM8 + X」の16bit値」の8bit値をAにロード
(Indirect), Y LDA (IM8), Y アドレス「アドレス「IM8」の16bit値 + Y」の8bit値をAにロード

転送命令

LDA

メモリからAにロードします。[N.0.0.0.0.0.Z.0]

アドレッシング コード バイト数 サイクル数
Immediate $A9 2 2
Zeropage $A5 2 3
Zeropage, X $B5 2 4
Absolute $AD 3 4
Absolute, X $BD 3 4
Absolute, Y $B9 3 4
(Indirect, X) $A1 2 6
(Indirect), Y $B1 2 5

LDX

メモリからXにロードします。[N.0.0.0.0.0.Z.0]

アドレッシング コード バイト数 サイクル数
Immediate $A2 2 2
Zeropage $A6 2 3
Zeropage, Y $B6 2 4
Absolute $AE 3 4
Absolute, Y $BE 3 4

LDY

メモリからYにロードします。[N.0.0.0.0.0.Z.0]

アドレッシング コード バイト数 サイクル数
Immediate $A0 2 2
Zeropage $A4 2 3
Zeropage, X $B4 2 4
Absolute $AC 3 4
Absolute, X $BC 3 4

STA

Aからメモリにストアします。[0.0.0.0.0.0.0.0]

アドレッシング コード バイト数 サイクル数
Zeropage $85 2 3
Zeropage, X $95 2 4
Absolute $8D 3 4
Absolute, X $9D 3 5
Absolute, Y $99 3 5
(Indirect, X) $81 2 6
(Indirect), Y $91 2 6

STX

Xからメモリにストアします。[0.0.0.0.0.0.0.0]

アドレッシング コード バイト数 サイクル数
Zeropage $86 2 3
Zeropage, Y $96 2 4
Absolute $8E 3 4

STY

Yからメモリにストアします。[0.0.0.0.0.0.0.0]

アドレッシング コード バイト数 サイクル数
Zeropage $84 2 3
Zeropage, X $94 2 4
Absolute $8C 3 4

TAX

AをXへコピーします。[N.0.0.0.0.0.Z.0]

アドレッシング コード バイト数 サイクル数
Implied $AA 1 2

TAY

AをYへコピーします。[N.0.0.0.0.0.Z.0]

アドレッシング コード バイト数 サイクル数
Implied $A8 1 2

TSX

SをXへコピーします。[N.0.0.0.0.0.Z.0]

アドレッシング コード バイト数 サイクル数
Implied $BA 1 2

TXA

XをAへコピーします。[N.0.0.0.0.0.Z.0]

アドレッシング コード バイト数 サイクル数
Implied $8A 1 2

TXS

XをSへコピーします。[N.0.0.0.0.0.Z.0]

アドレッシング コード バイト数 サイクル数
Implied $9A 1 2

TYA

YをAへコピーします。[N.0.0.0.0.0.Z.0]

アドレッシング コード バイト数 サイクル数
Implied $98 1 2

算術命令

ADC

(A + メモリ + キャリーフラグ) を演算して結果をAへ返します。[N.V.0.0.0.0.Z.C]

アドレッシング コード バイト数 サイクル数
Immediate $69 2 2
Zeropage $65 2 3
Zeropage, X $75 2 4
Absolute $6D 3 4
Absolute, X $7D 3 4
Absolute, Y $79 3 4
(Indirect, X) $61 2 6
(Indirect), Y $71 2 5

AND

Aとメモリを論理AND演算して結果をAへ返します。[N.0.0.0.0.0.Z.0]

アドレッシング コード バイト数 サイクル数
Immediate $29 2 2
Zeropage $25 2 3
Zeropage, X $35 2 4
Absolute $2D 3 4
Absolute, X $3D 3 4
Absolute, Y $39 3 4
(Indirect, X) $21 2 6
(Indirect), Y $31 2 5

ASL

Aまたはメモリを左へシフトします。[N.0.0.0.0.0.Z.C]

アドレッシング コード バイト数 サイクル数
Accumulator $0A 1 2
Zeropage $06 2 5
Zeropage, X $16 2 6
Absolute $0E 3 6
Absolute, X $1E 3 7

BIT

Aとメモリをビット比較演算します。[N.V.0.0.0.0.Z.0]

アドレッシング コード バイト数 サイクル数
Zeropage $24 2 3
Absolute $2C 3 4

CMP

Aとメモリを比較演算します。[N.0.0.0.0.0.Z.C]

アドレッシング コード バイト数 サイクル数
Immediate $C9 2 2
Zeropage $C5 2 3
Zeropage, X $D5 2 4
Absolute $CD 3 4
Absolute, X $DD 3 4
Absolute, Y $D9 3 4
(Indirect, X) $C1 2 6
(Indirect), Y $D1 2 5

CPX

Xとメモリを比較演算します。[N.0.0.0.0.0.Z.C]

アドレッシング コード バイト数 サイクル数
Immediate $E0 2 2
Zeropage $E4 2 3
Absolute $EC 3 4

CPY

Yとメモリを比較演算します。[N.0.0.0.0.0.Z.C]

アドレッシング コード バイト数 サイクル数
Immediate $C0 2 2
Zeropage $C4 2 3
Absolute $CC 3 4

DEC

メモリをデクリメントします。[N.0.0.0.0.0.Z.0]

アドレッシング コード バイト数 サイクル数
Zeropage $C6 2 5
Zeropage, X $D6 2 6
Absolute $CE 3 6
Absolute, X $DE 3 7

DEX

Xをデクリメントします。[N.0.0.0.0.0.Z.0]

アドレッシング コード バイト数 サイクル数
Implied $CA 1 2

DEY

Yをデクリメントします。[N.0.0.0.0.0.Z.0]

アドレッシング コード バイト数 サイクル数
Implied $88 1 2

EOR

Aとメモリを論理XOR演算して結果をAへ返します。[N.0.0.0.0.0.Z.0]

アドレッシング コード バイト数 サイクル数
Immediate $49 2 2
Zeropage $45 2 3
Zeropage, X $55 2 4
Absolute $4D 3 4
Absolute, X $5D 3 4
Absolute, Y $59 3 4
(Indirect, X) $41 2 6
(Indirect), Y $51 2 5

INC

メモリをインクリメントします。[N.0.0.0.0.0.Z.0]

アドレッシング コード バイト数 サイクル数
Zeropage $E6 2 5
Zeropage, X $F6 2 6
Absolute $EE 3 6
Absolute, X $FE 3 7

INX

Xをインクリメントします。[N.0.0.0.0.0.Z.0]

アドレッシング コード バイト数 サイクル数
Implied $E8 1 2

INY

Yをインクリメントします。[N.0.0.0.0.0.Z.0]

アドレッシング コード バイト数 サイクル数
Implied $C8 1 2

LSR

Aまたはメモリを右へシフトします。[N.0.0.0.0.0.Z.C]

アドレッシング コード バイト数 サイクル数
Accumulator $4A 1 2
Zeropage $46 2 5
Zeropage, X $56 2 6
Absolute $4E 3 6
Absolute, X $5E 3 7

ORA

Aとメモリを論理OR演算して結果をAへ返します。[N.0.0.0.0.0.Z.0]

アドレッシング コード バイト数 サイクル数
Immediate $09 2 2
Zeropage $05 2 3
Zeropage, X $15 2 4
Absolute $0D 3 4
Absolute, X $1D 3 4
Absolute, Y $19 3 4
(Indirect, X) $01 2 6
(Indirect), Y $11 2 5

ROL

Aまたはメモリを左へローテートします。[N.0.0.0.0.0.Z.C]

アドレッシング コード バイト数 サイクル数
Accumulator $2A 1 2
Zeropage $26 2 5
Zeropage, X $36 2 6
Absolute $2E 3 6
Absolute, X $3E 3 7

ROR

Aまたはメモリを右へローテートします。[N.0.0.0.0.0.Z.C]

アドレッシング コード バイト数 サイクル数
Accumulator $6A 1 2
Zeropage $66 2 5
Zeropage, X $76 2 6
Absolute $6E 3 6
Absolute, X $7E 3 7

SBC

(A - メモリ - キャリーフラグの反転) を演算して結果をAへ返します。[N.V.0.0.0.0.Z.C]

アドレッシング コード バイト数 サイクル数
Immediate $E9 2 2
Zeropage $E5 2 3
Zeropage, X $F5 2 4
Absolute $ED 3 4
Absolute, X $FD 3 4
Absolute, Y $F9 3 4
(Indirect, X) $E1 2 6
(Indirect), Y $F1 2 5

スタック命令

PHA

Aをスタックにプッシュダウンします。[0.0.0.0.0.0.0.0]

アドレッシング コード バイト数 サイクル数
Implied $48 1 3

PHP

Pをスタックにプッシュダウンします。[0.0.0.0.0.0.0.0]

アドレッシング コード バイト数 サイクル数
Implied $08 1 3

PLA

スタックからAにポップアップします。[N.0.0.0.0.0.Z.0]

アドレッシング コード バイト数 サイクル数
Implied $68 1 4

PLP

スタックからPにポップアップします。[N.V.R.B.D.I.Z.C]

アドレッシング コード バイト数 サイクル数
Implied $28 1 4

ジャンプ命令

JMP

アドレスへジャンプします。[0.0.0.0.0.0.0.0]

アドレッシング コード バイト数 サイクル数
Absolute $4C 3 3
(Indirect) $6C 3 5

JSR

サブルーチンを呼び出します。[0.0.0.0.0.0.0.0]

アドレッシング コード バイト数 サイクル数
Absolute $20 3 6

RTS

サブルーチンから復帰します。[0.0.0.0.0.0.0.0]

アドレッシング コード バイト数 サイクル数
Implied $60 1 6

RTI

割り込みルーチンから復帰します。[N.V.R.B.D.I.Z.C]

アドレッシング コード バイト数 サイクル数
Implied $40 1 6

分岐命令

BCC

キャリーフラグがクリアされている時にブランチします。[0.0.0.0.0.0.0.0]

アドレッシング コード バイト数 サイクル数
Relative $90 2 2

BCS

キャリーフラグがセットされている時にブランチします。[0.0.0.0.0.0.0.0]

アドレッシング コード バイト数 サイクル数
Relative $B0 2 2

BEQ

ゼロフラグがセットされている時にブランチします。[0.0.0.0.0.0.0.0]

アドレッシング コード バイト数 サイクル数
Relative $F0 2 2

BMI

ネガティブフラグがセットされている時にブランチします。[0.0.0.0.0.0.0.0]

アドレッシング コード バイト数 サイクル数
Relative $30 2 2

BNE

ゼロフラグがクリアされている時にブランチします。[0.0.0.0.0.0.0.0]

アドレッシング コード バイト数 サイクル数
Relative $D0 2 2

BPL

ネガティブフラグがクリアされている時にブランチします。[0.0.0.0.0.0.0.0]

アドレッシング コード バイト数 サイクル数
Relative $10 2 2

BVC

オーバーフローフラグがクリアされている時にブランチします。[0.0.0.0.0.0.0.0]

アドレッシング コード バイト数 サイクル数
Relative $50 2 2

BVS

オーバーフローフラグがセットされている時にブランチします。[0.0.0.0.0.0.0.0]

アドレッシング コード バイト数 サイクル数
Relative $70 2 2

フラグ変更命令

CLC

キャリーフラグをクリアします。[0.0.0.0.0.0.0.C]

アドレッシング コード バイト数 サイクル数
Implied $18 1 2

CLD

BCDモードから通常モードに戻ります。ファミコンでは実装されていません。[0.0.0.0.D.0.0.0]

アドレッシング コード バイト数 サイクル数
Implied $D8 1 2

CLI

IRQ割り込みを許可します。[0.0.0.0.0.I.0.0]

アドレッシング コード バイト数 サイクル数
Implied $58 1 2

CLV

オーバーフローフラグをクリアします。[0.V.0.0.0.0.0.0]

アドレッシング コード バイト数 サイクル数
Implied $B8 1 2

SEC

キャリーフラグをセットします。[0.0.0.0.0.0.0.C]

アドレッシング コード バイト数 サイクル数
Implied $38 1 2

SED

BCDモードに設定します。ファミコンでは実装されていません。[0.0.0.0.D.0.0.0]

アドレッシング コード バイト数 サイクル数
Implied $F8 1 2

SEI

IRQ割り込みを禁止します。[0.0.0.0.0.I.0.0]

アドレッシング コード バイト数 サイクル数
Implied $78 1 2

その他の命令

BRK

ソフトウェア割り込みを起こします。[0.0.0.B.0.0.0.0]

アドレッシング コード バイト数 サイクル数
Implied $00 1 7

NOP

空の命令を実行します。[0.0.0.0.0.0.0.0]

アドレッシング コード バイト数 サイクル数
Implied $EA 1 2