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 |