[新連載開始]W65C02マイコンボードの製作
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
私としてはW65C02をさわるのは全く初めてです。何から何まで未経験です。さてどうなりますでしょうか。
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
[第4回]
●アドレッシングモード
今回はW65C02のアドレッシングモードです。
W65C02のアドレッシングモードは結構種類が多くてしかもややこしいです。
[第1回]で紹介しました最初に喫茶店でコーヒーを飲みながら読んだドキュメントにある説明はちょっと分かりにくくてすぐには頭に入ってきませんでした。
なんじゃいな。
このわかりにくいヤツは。
私としてはこちらのほうが分かりやすいと思います↓
https://en.wikibooks.org/wiki/65c02_Assembly
どちらも同じことを言っているのでしょうが整理の仕方が違うのですね。
こちらはサンプルとしてアセンブラ表記が使われているのでそれが大いに理解の助けになりました。
分かりやすかったので下にほぼコピペいたします。
このドキュメントはW65C02アセンブラの解説のようで同アセンブラの表記を使って説明をしています(ちょいとクセがあります)。
Immediate(イミージエイト、即値):#
オペランドの8ビットの値をそのまま使って演算します。
シンボルは#です。
例 LDA #$22
Aレジスタ(アキュムレータ)に$22をロードする
8080アセンブラなどならここはLDA $22とかLDA 22のようにするところです。
$は16進数表記を示しています。
それならLDA $22にすればいいじゃないかと思いますが実はLDA $22とするとそれはzp(ゼロページアドレス)の指定になってしまいます(zpは後述)。
W65C02アセンブラでは8ビットの即値を示すのに#を使います。
16ビットを示すのには使いません(うーん。ややこしい!)。
Abusolute(絶対アドレス、16bit):a
オペランドの2バイトで直接アドレスを示してその値を使って演算します。
シンボルはaです。
例 LDX $D010
Xレジスタにアドレス$D010の値をロードする
こちらが16ビットです。
16ビットの数を示す場合には例のように$XXXXと表記します。
これはアドレスのみの表記です。
16ビットの即値はありません。
Z80ではLD HLとかLD IXなどの命令で16ビットの値(即値)を扱いますがW65C02にはPC(プログラムカウンタ)以外に16ビットのレジスタが無いことを思い出してください。
Zero Page(ゼロページ):zp
オペランドの1バイトがメモリアドレスの$00xxを示しその値を使って演算します。
シンボルはzpです。
例 LDY $12
アドレス$0012の値をYレジスタにロードする
ここで8ビットのアドレス表記を使います。
Relative(相対アドレス):r
オペランドの1バイトを符号付の数−128〜+127としてPC(プログラムカウンタ)に加算します。
相対ジャンプ命令に使われます。
シンボルはrです。
例 BPL $2D
現在のPCの値が$C100のときに前の演算の結果が正ならば$C12Dにジャンプする(Branch if result PLus)
Absolute Indirect(絶対アドレス、間接指定):(a)
オペランドの2バイトで直接アドレスを示し、そのアドレスと次のアドレスの値が16ビットのアドレスを示します。
シンボルは(a)です。
()は間接指定であることを示します。
aは直接アドレスを示します。
それに対して(a)はaが示すメモリアドレスの値(下位8ビット)とその次のメモリアドレスの値(上位8ビット)によって目的とするメモリアドレスを示します。
(a)はJMP命令のみに使われます。
例 JMP($A001)
アドレス$A001の値が$FFでアドレス$A002の値が$00のときアドレス$00FFにジャンプする
Absolute Indirect Indexed with X(Xでインデックス修飾した絶対アドレスによる間接指定):(a,X)
オペランドの2バイト(16ビット)とXの値を加算した値をメモリアドレスとしてそのアドレスとその次のアドレスの値が示す16ビットの値が目的とするメモリアドレスになります(もうめちゃくちゃややこしいです)。
シンボルは(a,X)です。
,XはXの値で修飾することを示します。
(a,X)はJMP命令のみに使われます。
例 JMP($E015,X)
Xの値が$06のときアドレス$E01Bの値が$10でアドレス$E01Cの値が$D0だとするとアドレス$D010にジャンプする
Absolute Indexed with X(Xでインデックス修飾した絶対アドレス):a,X
16ビットの値にXの値を加算した値がメモリアドレスになります。そのメモリアドレスの値を使って演算します。
シンボルはa,Xです。
例 ADC $C001,X
Xの値が$02のときアドレス$C003の値とキャリーがAレジスタに加算される
Absolute Indexed with Y(Yでインデックス修飾した絶対アドレス):a,Y
16ビットの値にYの値を加算した値がメモリアドレスになります。そのメモリアドレスの値を使って演算します。
シンボルはa,Yです。
例 INC $F001,Y
Yの値が$03のときアドレス$F004の値が+1される
Zero Page Indexed with X(Xでインデックス修飾したゼロページアドレス):zp,X
ゼロページのアドレスを示す1バイトの値にXの値を加算して得られるアドレスの値を使って演算します。
シンボルはzp,Xです。
例 LDA $01,X
Xの値が$02のときアドレス$0003の値がAレジスタ(アキュムレータ)にロードされる
Zero Page Indexed with Y(Yでインデックス修飾したゼロページアドレス):zp,Y
ゼロページのアドレスを示す1バイトの値にYの値を加算して得られるアドレスの値を使って演算します。
シンボルはzp,Yです。
例 LDA $01,Y
Yの値が$03のときアドレス$0004の値がAレジスタにロードされる
Zero Page Indirect(ゼロページアドレスが示す間接アドレス指定):(zp)
ゼロページアドレスが示す16ビットの値が示すアドレスの値を使って演算します。
シンボルは(zp)です。
例 STA ($15)
$0015の値が$10、$0016の値が$D0のときアドレス$D010にAレジスタの値がストアされる
Zero Page Indexed Indirect(Xでインデックス修飾したゼロページアドレスで示す間接指定):(zp,X)
ゼロページアドレスにXの値を加算して得られる値がメモリアドレスになります。そのアドレスの値を下位、その次のアドレスの値を上位とする2バイトの値が示すアドレスの値を使って演算します(なんとややこしい)。
シンボルは(zp,X)です。
例 STA ($15,x)
Xの値が$02のときアドレス$0017の値が$10、$0018の値が$D0だとするとアドレス$D010にAレジスタの値がストアされる
Zero Page Indirect Indexed with Y(ゼロページアドレスが示す間接指定アドレスをYでインデックス修飾する):(zp),Y
ゼロページアドレスとその次のアドレスの値が16ビットのアドレスになります。その値にYの値を加算して得られる値が示すアドレスの値を使って演算します(これもややこしい)。
シンボルは(zp),Yです。
例 EOR ($2A),Y
Yの値が$03のときアドレス$002Aの値が$35、$002Bの値が$C2だとするとアドレス$C238の値とAレジスタの値のXORがAレジスタの値になる
以上がW65C02のメモリに対するアドレッシングモードです。
全部覚える必要はありませんでしょう。
とりあえず分かりやすいものだけを使うだけでもそれなりのプログラムは組めるはずです。
上記のシンボルはW65C02のInstruction tableで使われています。
同表では上記以外に次のシンボルが使われています。
A(対象がアキュムレータであることを示します)
表ではシンボルとして使われていますがオペランド部には’A’は表記されません。
i(明示しなくても対象が明らかであることを示します)
表ではシンボルとして使われていますがオペランド部には’i’は表記されません。
例 STC
C(キャリーフラグ)をセットする
s(対象がスタックポインタであることを示します)
表ではシンボルとして使われていますがオペランド部には’s’は表記されません。

[出典]https://en.wikibooks.org/wiki/65c02_Assembly
前回はスタックアドレスについて思い違いがあっておかしなことを書いてしまいました。
スタックはそこに書きました通り$0100〜$01FFに限定されています。
W65C02マイコンボードの製作[第4回]
2026.7.6 upload
前へ
次へ
ホームページトップへ戻る